feat(docker): full self-hosted Compose support
Make the web image drop-in for a Honcho docker-compose stack:
- nginx reverse-proxies /v3 and /health to $HONCHO_UPSTREAM (variable +
Docker resolver so it starts even before the upstream resolves), giving
the SPA a same-origin path to Honcho with no browser CORS.
- Runtime config: an entrypoint writes config.js from
OPENCONCHO_DEFAULT_HONCHO_URL, so one prebuilt image targets any backend
("same-origin" | absolute URL | empty). SPA seeds a first-run default
instance from it (additive; no-op in dev/desktop).
- docker-compose.yml example service + GHCR multi-arch publish workflow on
release.
- nginx.conf -> envsubst template; docs rewritten.
Closes #21. Closes #31.
This commit is contained in:
64
docker/nginx.conf.template
Normal file
64
docker/nginx.conf.template
Normal file
@@ -0,0 +1,64 @@
|
||||
# OpenConcho — nginx site config (envsubst template).
|
||||
# The nginx image renders ${HONCHO_UPSTREAM} from the environment at start.
|
||||
# Serves the React SPA and reverse-proxies the Honcho API under the same origin.
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
listen [::]:8080;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Don't leak the nginx version.
|
||||
server_tokens off;
|
||||
|
||||
# Same-origin reverse proxy to Honcho so the browser never sees a
|
||||
# cross-origin request (no CORS). The variable + Docker resolver let nginx
|
||||
# start even when the upstream isn't resolvable yet, re-resolving per request.
|
||||
resolver 127.0.0.11 ipv6=off valid=10s;
|
||||
set $honcho_upstream "${HONCHO_UPSTREAM}";
|
||||
|
||||
# `^~` so these win over the static-asset regex below.
|
||||
location ^~ /v3/ {
|
||||
proxy_pass $honcho_upstream$request_uri;
|
||||
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;
|
||||
}
|
||||
location = /health {
|
||||
proxy_pass $honcho_upstream/health;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# Runtime config — regenerated per container start, must never be cached.
|
||||
location = /config.js {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Long-cache static assets — Vite hashes filenames so they're immutable.
|
||||
location ~* \.(?:js|mjs|css|woff2?|ttf|otf|eot|svg|png|jpg|jpeg|gif|ico|webp|avif|wasm)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Container healthcheck (local; distinct from Honcho's /health).
|
||||
location = /healthz {
|
||||
access_log off;
|
||||
default_type text/plain;
|
||||
return 200 "ok\n";
|
||||
}
|
||||
|
||||
# SPA fallback: unknown paths return index.html so the router resolves them.
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
|
||||
gzip_min_length 1024;
|
||||
}
|
||||
Reference in New Issue
Block a user