Files
RolemasterDB/docs/vserver_docker_deploy.md
2026-04-26 19:41:21 +02:00

5.1 KiB

Docker Deployment To A Linux VServer

This repo now includes a deployment script for shipping RolemasterDb.App to a remote Linux server that you reach as root, for example with:

ssh myvserver

The intended public URL is:

https://rolemasterdb.franktovar.de

The script publishes the app locally, uploads a release bundle over scp, builds the Docker image on the server, and replaces the running container. Nginx remains a one-time manual setup on the host and proxies to the container over localhost.

Files

  • scripts/deploy-vserver.sh
  • deploy/vserver.Dockerfile
  • deploy/vserver.env.example

Remote Prerequisites

On the vserver:

  1. Install Docker.
  2. Install nginx.
  3. Install a certificate tool such as certbot plus the nginx plugin if you want automated certificate provisioning.
  4. Make sure rolemasterdb.franktovar.de resolves to this server. Your wildcard A and AAAA records already satisfy that.

The deploy script stores releases under REMOTE_APP_DIR/releases/<timestamp> and keeps the SQLite database in REMOTE_DATA_DIR/rolemaster.db. The container should stay behind nginx, so the default deploy config binds it to 127.0.0.1:8080.

Local Setup

Create a local deploy config from the example:

cp deploy/vserver.env.example deploy/vserver.env

Adjust the values in deploy/vserver.env as needed:

  • REMOTE_HOST: your SSH host or alias, for example root@myvserver
  • REMOTE_APP_DIR: base directory on the server, default /root/docker/rolemasterdb
  • REMOTE_DATA_DIR: persistent directory for the SQLite database
  • HOST_BIND_ADDRESS: default 127.0.0.1 so only nginx can reach the container
  • HOST_PORT: nginx upstream port on the host, default 8080
  • REMOTE_USE_SUDO: keep 0 when you deploy as root
  • REMOTE_ENV_FILE: optional existing env file on the server to pass through to docker run

One-Time Server Setup

Create the base directories on the server:

ssh myvserver
mkdir -p /root/docker/rolemasterdb/data

Deploy once so the container exists:

./scripts/deploy-vserver.sh

Create an nginx site config at /etc/nginx/sites-available/rolemasterdb.franktovar.de:

server {
    listen 80;
    listen [::]:80;
    server_name rolemasterdb.franktovar.de;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 300;
    }
}

Enable it and reload nginx:

ln -s /etc/nginx/sites-available/rolemasterdb.franktovar.de /etc/nginx/sites-enabled/rolemasterdb.franktovar.de
nginx -t
systemctl reload nginx

At this point http://rolemasterdb.franktovar.de should work.

HTTPS Setup

If certbot and the nginx plugin are installed, request the certificate:

certbot --nginx -d rolemasterdb.franktovar.de

That should update the nginx config to serve HTTPS and normally also install an HTTP-to-HTTPS redirect. Verify the generated config and then reload nginx if needed:

nginx -t
systemctl reload nginx

After that, https://rolemasterdb.franktovar.de should terminate TLS in nginx and proxy traffic to 127.0.0.1:8080.

Deploy

Run:

./scripts/deploy-vserver.sh

Or point at a different config file:

./scripts/deploy-vserver.sh /path/to/custom.env

What The Script Does

  1. Publishes src/RolemasterDb.App/RolemasterDb.App.csproj in Release.
  2. Precreates publish/wwwroot/components/layout and publish/wwwroot/components/shared before publish. This is required because the current project otherwise fails to publish two JavaScript static assets.
  3. Bundles the publish output, src/RolemasterDb.App/rolemaster.db, and the runtime Dockerfile into artifacts/deploy/<release-id>/. The publish output already includes src/RolemasterDb.App/import-artifacts, so those files are shipped as part of every release bundle.
  4. Uploads the bundle to the vserver.
  5. Extracts the bundle on the vserver.
  6. Seeds REMOTE_DATA_DIR/rolemaster.db on first deploy only.
  7. Builds the Docker image on the vserver.
  8. Recreates the container with:
--restart unless-stopped
-p HOST_BIND_ADDRESS:HOST_PORT:CONTAINER_PORT
-v REMOTE_DATA_DIR:/app/data
ConnectionStrings__RolemasterDb=Data Source=/app/data/rolemaster.db

Updating The App Later

Running the same deploy command again will:

  • publish a fresh release bundle
  • upload a new timestamped release
  • keep the existing database in REMOTE_DATA_DIR
  • keep the imported artifact files inside the image for that release
  • rebuild the image and restart the container
  • leave the nginx config and TLS setup untouched

Useful Remote Commands

Check the running container:

ssh myvserver docker ps

Follow logs:

ssh myvserver docker logs -f rolemasterdb

Check nginx:

ssh myvserver nginx -t
ssh myvserver systemctl status nginx