Skip to main content

Domain + HTTPS setup for Docker services (Nginx + Certbot)

Project description

DomainUp – config-driven reverse proxy for Docker

DomainUp turns a simple YAML file into a running reverse-proxy with HTTPS for your Docker services. It renders Nginx (by default) and obtains Let’s Encrypt certificates via webroot. A Traefik renderer (POC) is included; DNS-01 is planned.

Overview

Why this exists: I kept repeating the same steps when provisioning a server on Hetzner — creating a reverse-proxy, wiring domains, getting HTTPS, and keeping things maintainable. DomainUp captures that workflow in a single, reproducible tool so any developer deploying on Hetzner (or any Docker host) can set up domains with minimal friction and no headaches.

Key ideas:

  • Single domainup.yaml governs everything.
  • Arbitrary number of domains; each maps to one or more Docker upstreams.
  • Generic Jinja2 templates for Nginx vhosts (and Traefik dynamic files with basic middlewares).
  • Let’s Encrypt via webroot (DNS-01 coming), HSTS optional.
  • Per-domain options: websockets, path routes, headers, basic auth (htpasswd files supported), allow-list, simple rate-limit, gzip, CORS passthrough, LB strategy, sticky cookie.
  • No hardcoded “types” like monitoring/otlp — fully generic.

Quick Start

Install (editable for local development):

pipx install -e .

Minimal flow:

domainup init --email contact@cirrondly.com   # creates domainup.yaml skeleton
domainup plan                                 # validate + print plan
domainup render                               # generate Nginx configs from YAML
domainup up                                   # start Nginx reverse proxy
domainup cert                                 # obtain certs (webroot)
domainup reload                               # reload Nginx
domainup deploy                               # render -> up -> cert -> reload
domainup check --domain api.example.com       # quick diagnostics

Local testing tips:

  • If ports 80/443 are busy, adjust host ports in domainup.yaml under runtime.http_port/https_port then render + up.
  • For HTTPS locally, use mkcert and place certs under ./letsencrypt/live/<host>/.

Configuration (domainup.yaml)

version: 1
email: contact@cirrondly.com
engine: nginx   # nginx | traefik (poc)
cert:
	method: webroot   # webroot | dns01 (todo)
	webroot_dir: ./www/certbot
	staging: false    # true to test with LE staging
network: proxy_net
runtime:
	http_port: 80
	https_port: 443
domains:
	- host: api.example.com
		upstreams:
			- name: app1
				target: back_web_1:8000
				weight: 1
		paths:
			- path: /
				upstream: app1
				websocket: true
				strip_prefix: false
		headers:
			hsts: true
			extra:
				X-Frame-Options: DENY
				X-Content-Type-Options: nosniff
		security:
			basic_auth:
				enabled: false
				users: []
			allow_ips: []
			rate_limit:
				enabled: false
				requests_per_minute: 600
		tls: { enabled: true }
		gzip: true
		cors_passthrough: false

	- host: console.example.com
		upstreams:
			- name: console
				target: console:3000
		paths:
			- path: "/"
				upstream: console
		security:
			basic_auth:
				enabled: true
				users: ["admin:{SHA}..."]
		tls: { enabled: true }

	- host: data.example.com
		upstreams:
			- name: otel
				target: otel:4318
		paths:
			- path: "~* ^/(v1/|otlp/v1/)(traces|logs|metrics)"
				upstream: otel
				body_size: 20m
		tls: { enabled: true }

Usage Examples

  • Generate configs for Nginx and start the proxy:
domainup render && domainup up
  • Obtain certificates (webroot):
domainup cert && domainup reload
  • Check DNS and TLS quickly:
domainup check --domain api.example.com
  • Print DNS records to create in your provider (e.g., Hetzner DNS, Vercel DNS, Cloudflare):
domainup dns --ipv4 203.0.113.10 --ipv6 2001:db8::10

Files generated (Nginx engine)

  • nginx/nginx.conf
  • nginx/conf.d/00-redirect.conf (http→https + ACME webroot for all TLS hosts)
  • nginx/conf.d/<host>.conf per domain
  • runtime/docker-compose.nginx.yml to run the proxy

Files generated (Traefik engine)

  • traefik/traefik.yml (static)
  • traefik/dynamic/<host>.yml per domain with middlewares
  • traefik/htpasswd/<host>.htpasswd when basic auth enabled
  • runtime/docker-compose.traefik.yml to run the proxy

Contributing

Set up dev environment:

pip install -e .[dev]
pytest -q

Coding standards:

  • Format: black, lint: ruff, types: mypy
  • Tests: pytest; add unit tests for new behaviors
  • PRs: include a brief description, motivation (what problem you solved), and tests

Security

  • Don’t expose Basic Auth user/passwords in the repo; use htpasswd files or safe secret storage.
  • HTTP-01 requires port 80. If you can’t open it, prefer DNS-01 (on roadmap).
  • Review Nginx config before going to production; adjust rate limits and headers as needed for your threat model.

License & Branding

MIT License. See LICENSE for details.

Created by Cirrondly (cirrondly.com) — a tiny startup by José MARIN.

Roadmap

  • DNS provider API integrations (Vercel, Cloudflare)
  • ACME DNS-01 support
  • Traefik middlewares parity (rate-limit, sticky, advanced headers)

Delivered from roadmap in this release:

  • Hetzner DNS automation (A/AAAA upsert) via domainup dns --provider hetzner --token ...
  • Cloudflare DNS automation (A/AAAA upsert) via domainup dns --provider cloudflare --token ...
  • Optional htpasswd file generation for basic auth (render-time)
  • Better CORS passthrough controls
  • Traefik basic middlewares: BasicAuth + CORS + RateLimit + Sticky cookie

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

domainup-0.1.1.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

domainup-0.1.1-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file domainup-0.1.1.tar.gz.

File metadata

  • Download URL: domainup-0.1.1.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for domainup-0.1.1.tar.gz
Algorithm Hash digest
SHA256 64c9f45536fb7ecea3757a5dde907aa3e2ffb496e4b3279d05c9b53b88f057ff
MD5 24516a68e7b6bc15eba3c6150bec80c6
BLAKE2b-256 1756a70be9cb272c6fc975428c74880020ad75d889a3b8d7e7f4083ebe2a80dd

See more details on using hashes here.

File details

Details for the file domainup-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: domainup-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for domainup-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e6bdd2b1f4fbfc03c13f59536b657a5eb3f1b2a27d538113f3942fa43f6490c8
MD5 e79fd38b3d77a0195df5e530c39266b5
BLAKE2b-256 99ea9612ccf557431542f54cc793c179a32cb0d6b678d3d42ad6c6a3e67103d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page