Deploy: serve plain HTTP behind Nginx Proxy Manager
CI / check (push) Successful in 6m11s
Details
CI / check (push) Successful in 6m11s
Details
Caddy listens on port 80 inside the container (the Caddyfile had moved it to 8080, which the port mapping didn't reach). NPM handles the domain and HTTPS, so compose publishes only HTTP_PORT (default 8080) and drops the HTTPS ports, certificate volumes and SITE_ADDRESS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f415227dbf
commit
41cf145135
|
|
@ -1,8 +1,5 @@
|
|||
# Settings for deploy/compose.yml. Copy to deploy/.env and fill in.
|
||||
|
||||
# What Caddy serves: the domain alone gets HTTPS from Let's Encrypt (ports 80
|
||||
# and 443 must reach this machine). Use :80 for plain HTTP on a LAN.
|
||||
SITE_ADDRESS=deadhead.belowland.com
|
||||
# Host ports Caddy listens on.
|
||||
HTTP_PORT=80
|
||||
HTTPS_PORT=443
|
||||
# The port on this machine that serves the game over plain HTTP. In Nginx Proxy
|
||||
# Manager, forward the domain (with its SSL certificate) to http://<this machine>:<port>.
|
||||
HTTP_PORT=8080
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
# The game as static files (CR-014): it runs and saves on the player's device.
|
||||
# SITE_ADDRESS is the public domain (HTTPS via Let's Encrypt), or ":80" for
|
||||
# plain HTTP when testing.
|
||||
{$SITE_ADDRESS} {
|
||||
encode zstd gzip
|
||||
# Static game files
|
||||
# HTTPS is handled by Nginx Proxy Manager, which forwards to this container's port 80
|
||||
|
||||
root * /srv
|
||||
# Client-side routes (/fleet, /contracts…) all load the app.
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
:80 {
|
||||
encode zstd gzip
|
||||
|
||||
# Vite's hashed bundles and fonts never change under the same name.
|
||||
@hashed path_regexp hashed ^/assets/[^/]+-[A-Za-z0-9_-]{8}\.(js|css|woff2?)$
|
||||
header @hashed Cache-Control "public, max-age=31536000, immutable"
|
||||
root * /srv
|
||||
|
||||
# The shell and service worker must always be checked for a new version.
|
||||
@shell path / /index.html /sw.js /registerSW.js /manifest.webmanifest
|
||||
header @shell Cache-Control "no-cache"
|
||||
# Client-side routes all load the app
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
|
||||
# Cache hashed Vite bundles and fonts
|
||||
@hashed path_regexp hashed ^/assets/[^/]+-[A-Za-z0-9_-]{8}\.(js|css|woff2?)$
|
||||
header @hashed Cache-Control "public, max-age=31536000, immutable"
|
||||
|
||||
# Always revalidate app shell and service worker
|
||||
@shell path / /index.html /sw.js /registerSW.js /manifest.webmanifest
|
||||
header @shell Cache-Control "no-cache"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
# Deploying Deadhead
|
||||
|
||||
The game runs and saves on each player's device (CR-014), so deploying it means
|
||||
serving static files. One machine runs Caddy with Docker Compose: it serves the
|
||||
web build and gets HTTPS certificates for the domain automatically. There is no
|
||||
server, database or backup to run; players keep their own saves (Settings →
|
||||
serving static files. One Caddy container serves the web build over plain HTTP;
|
||||
Nginx Proxy Manager (NPM) in front of it handles the domain and HTTPS. There is
|
||||
no server, database or backup to run; players keep their own saves (Settings →
|
||||
Export save).
|
||||
|
||||
## Before the first start
|
||||
|
||||
1. **DNS:** point an `A` record for `deadhead.belowland.com` at the public IP of
|
||||
the network the machine is on.
|
||||
2. **Router:** forward TCP ports 80 and 443 (and UDP 443 for HTTP/3) to the
|
||||
machine. Let's Encrypt checks port 80 before it issues a certificate.
|
||||
3. **Docker:** Docker Engine with the Compose plugin (`docker compose version`).
|
||||
4. **Settings:** in this folder, `cp .env.example .env` and check
|
||||
`SITE_ADDRESS`.
|
||||
1. **Docker:** Docker Engine with the Compose plugin (`docker compose version`).
|
||||
2. **Settings:** in this folder, `cp .env.example .env` and set `HTTP_PORT` (the
|
||||
port on this machine that serves the game; default 8080).
|
||||
3. **NPM:** add a Proxy Host:
|
||||
- Domain: `deadhead.belowland.com`
|
||||
- Scheme `http`, forward hostname = this machine's IP, forward port = `HTTP_PORT`
|
||||
- SSL: request a Let's Encrypt certificate and turn on Force SSL
|
||||
|
||||
DNS and port forwarding (80 and 443 to the NPM machine) are NPM's, as for
|
||||
any other site it serves.
|
||||
|
||||
## Start and update
|
||||
|
||||
|
|
@ -22,17 +25,17 @@ From this folder, on the machine:
|
|||
|
||||
```sh
|
||||
git pull
|
||||
APP_BUILD=$(git rev-parse --short HEAD) docker compose up -d --build
|
||||
APP_BUILD=$(git rev-parse --short HEAD) docker compose --env-file .env up -d --build
|
||||
```
|
||||
|
||||
The About screen in Settings shows the build you deployed. Installed copies pick
|
||||
up the new version the next time they open (the service worker checks the shell
|
||||
on every load).
|
||||
|
||||
## On a LAN only (no domain)
|
||||
## Without NPM
|
||||
|
||||
Set `SITE_ADDRESS=:80` in `.env`. Caddy then serves plain HTTP. Installing the
|
||||
app to a phone home screen needs HTTPS, so this is for testing.
|
||||
The site also works on its own over plain HTTP at `http://<this machine>:<HTTP_PORT>`.
|
||||
Installing the app to a phone home screen needs HTTPS, so that is for testing.
|
||||
|
||||
## Any other static host
|
||||
|
||||
|
|
@ -47,5 +50,5 @@ deploy/check.sh
|
|||
```
|
||||
|
||||
This builds and starts the site under a separate project name on port 8088,
|
||||
checks the app shell, client-side routes and caching, then removes it. It never
|
||||
touches the real site.
|
||||
checks the app shell, client-side routes, caching and compression, then removes
|
||||
it. It never touches the real site.
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ env_file=".check.env"
|
|||
port="${CHECK_PORT:-8088}"
|
||||
site="http://localhost:$port"
|
||||
cat > "$env_file" <<ENV
|
||||
SITE_ADDRESS=:80
|
||||
HTTP_PORT=$port
|
||||
HTTPS_PORT=${CHECK_TLS_PORT:-8443}
|
||||
ENV
|
||||
compose() { docker compose -p "$project" --env-file "$env_file" "$@"; }
|
||||
cleanup() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Static hosting for the web build (CR-014): Caddy serves the app; the game runs
|
||||
# and saves on each player's device, so there is no server or database.
|
||||
# Static hosting for the web build (CR-014): Caddy serves the app over plain
|
||||
# HTTP; Nginx Proxy Manager in front of it handles the domain and HTTPS. The
|
||||
# game runs and saves on each player's device, so there is no server or database.
|
||||
# From this folder: docker compose --env-file .env up -d --build
|
||||
# Settings come from deploy/.env (copy .env.example).
|
||||
name: deadhead
|
||||
|
|
@ -12,16 +13,6 @@ services:
|
|||
args:
|
||||
APP_BUILD: ${APP_BUILD:-dev}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
SITE_ADDRESS: ${SITE_ADDRESS:?set SITE_ADDRESS in deploy/.env}
|
||||
ports:
|
||||
- "${HTTP_PORT:-80}:80"
|
||||
- "${HTTPS_PORT:-443}:443"
|
||||
- "${HTTPS_PORT:-443}:443/udp"
|
||||
volumes:
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
|
||||
volumes:
|
||||
caddy-data:
|
||||
caddy-config:
|
||||
# Host port → Caddy's port 80 in the container. Point NPM at this host port.
|
||||
- "${HTTP_PORT:-8080}:80"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# The web app on Caddy (Step 13.2, static since CR-014). Build from the repository root:
|
||||
# docker build -f deploy/web.Dockerfile --build-arg APP_BUILD=$(git rev-parse --short HEAD) .
|
||||
# Caddy serves the built app and gets HTTPS certificates for SITE_ADDRESS
|
||||
# automatically.
|
||||
# Caddy serves the built app over plain HTTP on port 80; Nginx Proxy Manager
|
||||
# in front of it handles the domain and HTTPS.
|
||||
|
||||
FROM node:24-slim AS build
|
||||
RUN corepack enable
|
||||
|
|
|
|||
|
|
@ -95,10 +95,10 @@ Until Step 14.11 a Fastify API with Postgres (Drizzle), Better Auth guest sessio
|
|||
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| `compose.yml` | One service (project `deadhead`): `web`, Caddy on `HTTP_PORT`/`HTTPS_PORT`, certificate volumes |
|
||||
| `web.Dockerfile`, `Caddyfile` | Caddy image with the built app: client routes fall back to `index.html`, hashed assets cached for a year, shell, service worker and manifest never; HTTPS for `SITE_ADDRESS` |
|
||||
| `README.md` | Setup: DNS, port forwarding, `.env`, start/update, LAN-only mode, other static hosts |
|
||||
| `.env.example` | `SITE_ADDRESS` and host ports; copy to `deploy/.env` |
|
||||
| `compose.yml` | One service (project `deadhead`): `web`, Caddy serving plain HTTP on container port 80, published on `HTTP_PORT` (default 8080) for Nginx Proxy Manager to forward to |
|
||||
| `web.Dockerfile`, `Caddyfile` | Caddy image with the built app on `:80`: client routes fall back to `index.html`, hashed assets cached for a year, shell, service worker and manifest never; HTTPS is NPM's |
|
||||
| `README.md` | Setup behind Nginx Proxy Manager, start/update, other static hosts |
|
||||
| `.env.example` | `HTTP_PORT`; copy to `deploy/.env` |
|
||||
| `check.sh` | Builds and starts the site under a throwaway project, checks shell, routes, caching and compression, removes it |
|
||||
|
||||
## Client (`apps/web`)
|
||||
|
|
|
|||
Loading…
Reference in New Issue