# 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: ```bash ssh myvserver ``` The intended public URL is: ```text 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/` 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: ```bash 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: ```bash ssh myvserver mkdir -p /root/docker/rolemasterdb/data ``` Deploy once so the container exists: ```bash ./scripts/deploy-vserver.sh ``` Create an nginx site config at `/etc/nginx/sites-available/rolemasterdb.franktovar.de`: ```nginx 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: ```bash 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: ```bash 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: ```bash 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: ```bash ./scripts/deploy-vserver.sh ``` Or point at a different config file: ```bash ./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. Replaces `publish/import-artifacts` with a full copy of `src/RolemasterDb.App/import-artifacts`. This is required because the current publish output does not reliably include deep artifact folders such as `cells/` and `pages/`. 4. Bundles the publish output, `src/RolemasterDb.App/rolemaster.db`, and the runtime Dockerfile into `artifacts/deploy//`. 5. Uploads the bundle to the vserver. 6. Extracts the bundle on the vserver. 7. Seeds `REMOTE_DATA_DIR/rolemaster.db` on first deploy only. 8. Builds the Docker image on the vserver. 9. Recreates the container with: ```text --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 complete imported artifact tree 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: ```bash ssh myvserver docker ps ``` Follow logs: ```bash ssh myvserver docker logs -f rolemasterdb ``` Check nginx: ```bash ssh myvserver nginx -t ssh myvserver systemctl status nginx ```