Deploying the app as a service using systemd and Podman
This short guide is intended as an example of configuration (please note that it is experimental and as such not to be used in production!) for system admins who would like to deploy the Beacon as a service using Linux systemd unit config files.
Prerequisites
- Linux OS
- Podman version >= 2.0.4
To run Podman from Windows or MacOS you either use a remote client or run Linux inside a virtual machine.
Creating a common directory for service files
After having installed podman on your linux-like machine, ssh into this machine and create a folder in the user's home directory. This directory will contain all systemd unit config files:
mkdir -p ~/.config/systemd/user
MongoDB service file
First thing to do is choosing a MongoDB image to use as database. You could use either the official MongoDB image or any other MongoDB image you prefer. For the sake of this documentation, let's use the lightweight MongoDB image(mvertes/alpine-mongo). Pull the image from Docker Hub:
podman pull mvertes/alpine-mongo
Assign the image a name, so it will be later used in the systemd service file. In this case the name will be beacon-mongo:
podman run --security-opt=seccomp=unconfined -d --name beacon-mongo -p 27017:27017 alpine-mongo
Create a service file for MongoDB with the following command:
podman generate systemd --name beacon-mongo
The content of this file will look like this:
# container-beacon-mongo.service
# autogenerated by Podman 3.2.3
# Mon Mar 21 08:51:43 UTC 2022
[Unit]
Description=Podman container-beacon-mongo.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
RequiresMountsFor=/run/user/1000/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start beacon-mongo
ExecStop=/usr/bin/podman stop -t 10 beacon-mongo
ExecStopPost=/usr/bin/podman stop -t 10 beacon-mongo
PIDFile=/run/user/1000/containers/overlay-containers/2414fc2edfaf56869d7f31367ba23caf5f2a247d2ae88b62fc8d797362232878/userdata/conmon.pid
Type=forking
[Install]
WantedBy=multi-user.target default.target
Add the following line to this file, in the [Unit] section:
BindsTo=beacon-mongo.service
Create a service config file under ~/.config/systemd/user:
touch ~/.config/systemd/user/beacon-mongo.service
And copy the generated file content into this service file.
After creating the unit file, to start the container automatically at boot time, type the following:
systemctl --user daemon-reload
systemctl --user enable beacon-mongo.service
Once the service is enabled, it will start at boot time. To start it immediately and check the status of the service, type the following:
systemctl --user start beacon-mongo.service
systemctl --user status beacon-mongo.service
To stop the service type the following command:
systemctl --user stop beacon-mongo.service
Beacon cli service file
podman create --name beacon clinicalgenomics/cgbeacon2
Create the service file under ~/.config/systemd/user:
touch ~/.config/systemd/user/beacon-cli.service
Generate the systemd file content:
podman generate systemd --name beacon
Add the content of the service file to the service file:
vi ~/.config/systemd/user/beacon-cli.service
Don't forget to include this line under the [Unit] section:
Requires= beacon-mongo.service
Reload services and enable beacon-cli
systemctl --user daemon-reload
systemctl --user enable beacon-cli.service
Beacon web service file
Let's create a service config file to start the Beacon web app and keep it running.
podman create --name beacon-web clinicalgenomics/cgbeacon2-server
Create the service file under ~/.config/systemd/user: Let's add the following unit file to the ~/.config/systemd/user folder:
touch ~/.config/systemd/user/beacon-web.service
Let's add the following content to the file
# beacon-web.service
[Unit]
Description=Podman beacon-web.service
Documentation=man:podman-generate-systemd(1)
Requires= beacon-mongo.service
Wants=network.target
After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=no # Eventually turn this into on-failure
ExecStart=/usr/bin/podman run \
--env "MONGODB_HOST=mongodb" \
--security-opt=seccomp=unconfined \
--log-driver=journald \
--name beacon-web \
--tz local \
-p 8000:8000 \
clinicalgenomics/cgbeacon2-server
ExecStop=/usr/bin/podman stop beacon-web
ExecStopPost=/usr/bin/podman rm --ignore -f beacon-web
TimeoutStartSec=1800s
Type=forking
[Install]
WantedBy=multi-user.target default.target
Reload services and enable beacon-cli
systemctl --user daemon-reload
systemctl --user enable beacon-web.service
Once the service is enabled, it will start at boot time. To start it immediately and check the status of the service, type the following:
systemctl --user start beacon-web.service
systemctl --user status beacon-web.service
Output from the command above:
● beacon-web.service - Podman beacon-web.service
Loaded: loaded (/home/vagrant/.config/systemd/user/beacon-web.service; enabled; vendor preset: enabled)
Active: activating (start) since Mon 2022-03-21 10:48:00 UTC; 3min 23s ago
Docs: man:podman-generate-systemd(1)
Cntrl PID: 5390 (podman)
CGroup: /user.slice/user-1000.slice/user@1000.service/beacon-web.service
├─5390 /usr/bin/podman run --env MONGODB_HOST=mongodb --security-opt=seccomp=unconfined --log-driver=journald --name beacon-web --tz local -p 8000:>
├─5402 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520 --enable-sandbox --enable-seccomp -c -e 3 -r 4 --netns-type=path /run/user/1000/net>
├─5404 containers-rootlessport
├─5408 /usr/bin/fuse-overlayfs -o ,lowerdir=/home/vagrant/.local/share/containers/storage/overlay/l/UVIOW4TMABJJK5NP2TTAZQXCND:/home/vagrant/.local>
├─5412 containers-rootlessport-child
├─5419 /usr/bin/conmon --api-version 1 -c 5fc523663bdf26efee7af191ad4c70e184e05c3c1ec43bfd2c8541b23638c599 -u 5fc523663bdf26efee7af191ad4c70e184e05>
└─5fc523663bdf26efee7af191ad4c70e184e05c3c1ec43bfd2c8541b23638c599
├─5427 /bin/sh -c gunicorn --workers=$GUNICORN_WORKERS --bind=$GUNICORN_BIND --threads=$GUNICORN_THREADS --timeout=$GUNICORN_TIM>
├─5438 /venv/bin/python /venv/bin/gunicorn --workers=1 --bind=0.0.0.0:8000 --threads=1 --timeout=400 --proxy-protocol --forwarded-allow-ips=10.0.>
└─5440 /venv/bin/python /venv/bin/gunicorn --workers=1 --bind=0.0.0.0:8000 --thread
To stop the service type the following command:
systemctl --user stop beacon-web.service