Sets up everything needed to deploy behind Cloudflare with a self-hosted git server: multi-stage prod Dockerfiles (non-root), docker-compose.prod.yml (Postgres/Redis with no host ports, Nginx reverse proxy, Gitea with public-read/admin-write access control), scripts/bootstrap-env.sh to auto-generate required secrets on first clone, and DEPLOYMENT.md covering the full runbook. Provider API keys (Anthropic/Brave/NinjaPear/USPTO/ Turnstile) are deliberately kept out of .env in favor of the existing DB-backed Settings UI, so the public repo stays safe to expose. Also fixes two bugs only surfaced by live-testing the prod stack: Celery beat couldn't write its schedule file as a non-root user, and Gitea's embedded SSH server conflicted with the base image's own sshd on port 22. Co-Authored-By: Claude Sonnet 5 <[email protected]>
83 lines
2.7 KiB
Nginx Configuration File
83 lines
2.7 KiB
Nginx Configuration File
# Reverse proxy for the three ciagent.org subdomains, sitting between
|
|
# Cloudflare (which terminates public-facing TLS and hides this origin's
|
|
# real IP) and the app's own containers. TLS here is a Cloudflare Origin CA
|
|
# certificate (Cloudflare dashboard -> SSL/TLS -> Origin Server -> Create
|
|
# Certificate; covers ciagent.org + *.ciagent.org, up to 15yr validity, only
|
|
# trusted by Cloudflare - no ACME/renewal machinery needed). Cloudflare SSL
|
|
# mode must be "Full (strict)" for this to be meaningful. See DEPLOYMENT.md.
|
|
#
|
|
# CF-Connecting-IP (the header app.core.security.get_client_ip reads once
|
|
# TRUSTED_PROXY_IP_HEADER=CF-Connecting-IP is set) needs no special handling
|
|
# here - Nginx forwards any header it doesn't explicitly touch straight
|
|
# through to the upstream unmodified.
|
|
|
|
user nginx;
|
|
worker_processes auto;
|
|
|
|
events {
|
|
worker_connections 1024;
|
|
}
|
|
|
|
http {
|
|
include mime.types;
|
|
default_type application/octet-stream;
|
|
sendfile on;
|
|
server_tokens off;
|
|
|
|
# Bare :80 hits get redirected to :443 - Cloudflare already enforces
|
|
# HTTPS at the edge, but the origin shouldn't 400 a direct :80 probe.
|
|
server {
|
|
listen 80;
|
|
server_name ciagent.org api.ciagent.org git.ciagent.org;
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
server_name ciagent.org;
|
|
|
|
ssl_certificate /etc/nginx/certs/cloudflare-origin.pem;
|
|
ssl_certificate_key /etc/nginx/certs/cloudflare-origin.key;
|
|
|
|
location / {
|
|
proxy_pass http://web:3000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
server_name api.ciagent.org;
|
|
|
|
ssl_certificate /etc/nginx/certs/cloudflare-origin.pem;
|
|
ssl_certificate_key /etc/nginx/certs/cloudflare-origin.key;
|
|
|
|
location / {
|
|
proxy_pass http://api:8000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
server_name git.ciagent.org;
|
|
|
|
ssl_certificate /etc/nginx/certs/cloudflare-origin.pem;
|
|
ssl_certificate_key /etc/nginx/certs/cloudflare-origin.key;
|
|
|
|
# Large git pushes (Gitea's HTTPS push path).
|
|
client_max_body_size 512m;
|
|
|
|
location / {
|
|
proxy_pass http://gitea:3000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
}
|
|
}
|
|
}
|