4.9 KiB
4.9 KiB
Nginx + Certbot + ACME‑DNS Proxy Stack
A batteries‑included reverse‑proxy scaffold that Just Works™ on a single node or a Docker Swarm.
Old‑school Unix philosophy under the hood, modern container workflow on top.
✨ What you get
Component | Job |
---|---|
Nginx | Serves HTTP/S, terminates TLS, proxies upstreams, handles TCP/UDP streams |
Certbot | Automates Let’s Encrypt certificate issuance / renewal |
acme‑dns‑auth.py | ACME‑DNS helper for DNS‑01 challenges (wildcards, no public port 80 needed) |
Docker (image & compose) | Reproducible environment; optional Swarm placement rules |
🗺️ Repo layout
.
├── acme-dns-auth.py # DNS‑01 hook script (public upstream helper)
├── certbot-runner # Convenience wrapper for interactive work inside the image
├── new-domain-runner # Example one‑shot script for ad‑hoc certs
├── compose.yml # Single‑service stack definition
├── dockerfile.debian # Image build (Debian slim + Nginx + Certbot)
├── conf.d/ # Per‑vhost HTTP configs
├── stream.d/ # TCP/UDP proxy configs (PostgreSQL, MQTT, …)
├── letsencrypt/ # **Empty dir – private keys & certs live here at runtime**
├── work/ # Certbot working directory (also ignored by Git)
└── lib/backups/ # Optional local backup dumps (ignored by Git)
🚀 Quick start
Prerequisites: Docker (24 +) & Docker Compose v2, or Docker Swarm if you want clustering.
# 1. Clone
$ git clone https://github.com/youruser/proxy-stack.git
$ cd proxy-stack
# 2. Create empty state dirs so the volume binds succeed
$ mkdir -p letsencrypt work lib/backups
$ touch letsencrypt/.gitkeep work/.gitkeep lib/backups/.gitkeep
# 3. (Optional) Build your own image
$ docker build -t my-proxy:latest -f dockerfile.debian .
# 4. Launch the stack (Compose)
$ IMAGE_NAME=my-proxy:latest docker compose up -d
# 5. Obtain the first certificate (DNS‑01)
$ DOMAIN=my.example.com ./new-domain-runner
# Follow the prompts → add the TXT record → hit <Enter>
Swarm mode
# Initialize swarm once per host (if not already a manager)
$ docker swarm init
# Deploy with placement label (edit compose.yml if needed)
$ docker stack deploy -c compose.yml proxy
🔐 TLS & certificates
- Automatic renewals – A cron inside the container runs
certbot renew
and hot‑reloads Nginx. - No secrets in Git –
letsencrypt/
isgitignored
; keys stay on disk only. - acme‑dns – Ideal when ports 80/443 are busy or you need wildcard certs. Change
ACMEDNS_URL
via env var if you self‑host acme‑dns.
⚙️ Configuration knobs
Variable | Default | Purpose |
---|---|---|
IMAGE_NAME |
ghcr.io/youruser/proxy:latest |
Override in scripts / compose to point at your own build |
ACMEDNS_URL |
https://auth.acme-dns.io |
Where acme-dns-auth.py registers & updates records |
CERTBOT_EMAIL |
– | Address Certbot uses for expiry mails |
Swarm label | node.labels.server_id==lnd1 |
Example placement constraint – comment or change |
Edit conf.d/*.conf
and stream.d/*.conf
to define your virtual hosts and upstreams.
🛠️ Maintenance
Task | Old‑school command | Modern alternative |
---|---|---|
Rebuild image after Nginx or OpenSSL CVE | docker build -t my-proxy . |
GitHub Actions → docker buildx build --push |
List certs expiring in ≤30 days | docker exec proxy certbot certificates |
Prometheus + exporter |
Tail logs | docker compose logs -f proxy |
Grafana Loki |
🤝 Contributing
Patches and issues are welcome – just follow the kernel‑style rule: one patch, one purpose.
- Fork → branch → commit (signed‑off)
- Make sure
pre-commit run --all
passes (gitleaks, shellcheck, etc.) - Open a PR.
📜 License
This project is released under the GNU General Public License v2.0 – see LICENSE
for details.