diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..714d0ba --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +versions_to_compare +DEPLOYMENT.md +README.md +CLAUDE.md +LICENSE diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..5ec3010 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,65 @@ +# Hosting with Docker + Caddy 2 + +The game is a single static `index.html`, so it's served from a small nginx +container. Caddy sits in front as a reverse proxy and handles the FQDN + TLS. + +## 1. Build and run the container + +```bash +docker compose up -d --build +``` + +This builds the image from `Dockerfile` (nginx serving `index.html`) and +exposes it on `http://:8080`. Check it directly first: + +```bash +curl http://localhost:8080/healthz # -> ok +``` + +Change the `8080:80` mapping in `docker-compose.yml` if that port is taken. + +## 2. Point Caddy at it + +Caddy can run on the **same host** as the container or on a **different +machine** — either way it just needs a `reverse_proxy` pointed at the +container's exposed port. + +Add a block like this to your existing `Caddyfile` (replace +`drums.example.com` with your real FQDN): + +```caddyfile +drums.example.com { + reverse_proxy localhost:8080 +} +``` + +If Caddy runs on a different machine than the container, use the docker +host's address or internal hostname instead of `localhost`: + +```caddyfile +drums.example.com { + reverse_proxy 10.0.0.5:8080 +} +``` + +Then reload Caddy: + +```bash +caddy reload --config /path/to/Caddyfile +``` + +Caddy 2 automatically requests and renews a TLS certificate for the FQDN +(via Let's Encrypt) the first time it's reloaded with a public domain name +in the block — no extra config needed, as long as the FQDN's DNS A/AAAA +record already points at the Caddy host and ports 80/443 are reachable. + +## 3. Updating + +Since the game is one file, redeploying after a code change is: + +```bash +docker compose up -d --build +``` + +nginx serves the new `index.html` immediately; no Caddy reload needed unless +you changed the Caddyfile itself. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..62fcffd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM nginx:1.27-alpine + +COPY index.html /usr/share/nginx/html/index.html +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 diff --git a/README.md b/README.md index 38443a0..2f1878e 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,13 @@ All sounds are generated in real-time using the Web Audio API — no audio files - localStorage for all persistent data - Works on Windows, Linux, and Mac +## Hosting + +No server is required to play, but if you want it reachable at a URL, a +`Dockerfile` + `docker-compose.yml` are included to serve `index.html` from +nginx in a container, plus a `DEPLOYMENT.md` with a Caddy 2 reverse-proxy +config for putting it behind an FQDN with automatic HTTPS. + ## License [MIT](LICENSE) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6d38fc2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +services: + drum-rhythm-game: + build: . + container_name: drum-rhythm-game + restart: unless-stopped + ports: + - "8080:80" diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..7ba1342 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,19 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + gzip on; + gzip_types text/html text/css application/javascript; + + location = /healthz { + return 200 "ok\n"; + add_header Content-Type text/plain; + } + + location / { + try_files $uri $uri/ /index.html; + } +}