Skip to content

Introduction

If your web applications hosted on the pubapps infrastructure is architected to run as a backend process that is then reverse proxied via the pubweb webservers you will need a way to start the application when a server in the pubapps infrastructure (pubcontainer node, individual VM, or pubweb* webservers for lightweight backends) is restarted. We encourage you to consider using a systemd in user mode, which can automate the start/stop/restart process. This help article should help you create and use such a user systemd script for a web application.

Configuration

Systemd has two modes of operation - system-wide, which requires the service scripts to be in a system location and operated by root and a user mode. You will be using the user mode in pubapps.

  • Create a user systemd directory under your /pubapps/PROJECT/ $HOME directory in pubapps mkdir -p .config/systemd/user/
  • Add a service script for the application, e.g. ~/.config/systemd/user/project.service or devproject.service

Script examples for two commonly deployed types of apps are shown below:

Containerized Web Application

Example systemd script for running an application out of a podman container

Systemd scripts for containerized applications are placed into the ~/.config/containers/systemd/ directory and are named as project.container as opposed to a .service extension described above.

Variables

  • Description = Free form description of the service
  • Image = container image, whether from a remote registry or locahost if built right in the VM from a Dockerfile
  • ContainerName = concise readable name for a running container. If not specified a randomly generated name will be used.
  • PublishPort = SOURCE:TARGET. The SOURCE is the port inside the container. The TARGET is the port exposed on the host system that can be reverse proxied. They don't have to match.
  • Volume = 'bind-mounted' directories in the SOURCE:TARGET format. See https://docs.podman.io/en/v4.4/markdown/options/volume.html for reference.

This is arguably the simplest and most portable approach as a containerized deployment of the application makes it portable i.e. not dependent on the host environment and software dependencies. Many base images are available to build a container from.

[Unit]
Description=MyProject Prod Container
After=local-fs.target 

[Container]
Image=docker.io/someproject/imagename:latest
ContainerName=myproject
PublishPort=8000:8080
Volume=%h/myproject/prod/tmp:/tmp

[Install]
# Start by default on boot
WantedBy= default.target

Python Web Application

Example generic python web application systemd script

[Unit]
Description=MyProject (Production)
After=network.target

[Service]
Type=simple

WorkingDirectory=/pubapps/myinstance/myproject/prod/
ExecStart=/pubapps/myinstance/myproject/prod/conda/bin/python3 run/runserver.py
TimeoutSec=30
RestartSec=15s
Restart=always

[Install]
WantedBy=multi-user.target

R Shiny Web Application

[Unit]
Description=MyShinyApp
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=5
WorkingDirectory=/pubapps/myproject/shinyapp/prod/app
ExecStart=nohup R --no-echo --no-restore --file=run.R > /pubapps/myproject/shinyapp/prod/logs/app.log 2>&1
EnvironmentFile=/pubapps/myproject/shinyapp/prod/env.sh

[Install]
WantedBy=multi-user.target

Use

Login linger mode

  • Enable user linger mode to avoid having your application be shut down when you log out:
    loginctl enable-linger $USER
    

Manage the application

  • Initial load of the configuration to enable the service
    systemctl --user enable projprod
    
  • Reload configuration (after every change of the systemd service script)
    systemctl --user daemon-reload
    
  • Start service
    systemctl --user start projprod
    
  • Stop service
    systemctl --user stop projprod
    
  • Restart service
    systemctl --user restart projprod
    
  • Check if the service is running
    systemctl --user status projprod
    

HA Setup on pubweb servers

We recommend that systemd served apps are started on the pubcontainer server that was listed in the support ticket.

We have two pubapps web/proxy servers providing a HA (High Availability) setup for serving your web application(s). If the main webserver goes down a secondary pubweb webserver will automatically take over.

If your application is running directly on the webserver then you will need to have a copy of the app running on both pubweb[1,2] servers to account for the HA (High Availability) configuration.

Additional Information

For additional information search web for 'systemd user mode'. E.g. https://wiki.archlinux.org/title/Systemd/User.