Document nginx vserver setup

This commit is contained in:
2026-04-26 19:41:21 +02:00
parent 26960a8a15
commit 61f11eed38
3 changed files with 117 additions and 18 deletions

View File

@@ -1,12 +1,18 @@
# 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 with:
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 script publishes the app locally, uploads a release bundle over `scp`, builds the Docker image on the server, and replaces the running container.
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
@@ -19,10 +25,12 @@ The script publishes the app locally, uploads a release bundle over `scp`, build
On the vserver:
1. Install Docker.
2. Make sure the SSH user can run `docker`, or set `REMOTE_USE_SUDO=1` in the deploy config.
3. Open the host port you want to expose, for example `8080`.
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
@@ -34,13 +42,78 @@ 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 `myvserver`
- `REMOTE_APP_DIR`: base directory on the server, for example `/opt/rolemasterdb`
- `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_PORT`: public port on the vserver
- `REMOTE_USE_SUDO`: set to `1` if remote Docker commands need `sudo`
- `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:
@@ -61,6 +134,7 @@ Or point at a different config file:
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.
@@ -69,7 +143,7 @@ Or point at a different config file:
```text
--restart unless-stopped
-p HOST_PORT:CONTAINER_PORT
-p HOST_BIND_ADDRESS:HOST_PORT:CONTAINER_PORT
-v REMOTE_DATA_DIR:/app/data
ConnectionStrings__RolemasterDb=Data Source=/app/data/rolemaster.db
```
@@ -81,7 +155,9 @@ 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
@@ -96,3 +172,10 @@ Follow logs:
```bash
ssh myvserver docker logs -f rolemasterdb
```
Check nginx:
```bash
ssh myvserver nginx -t
ssh myvserver systemctl status nginx
```