{"id":31585050,"url":"https://github.com/hjaltiatla/lan-nginx-reverse-proxy-cloudflare","last_synced_at":"2026-04-29T16:33:10.268Z","repository":{"id":314776289,"uuid":"1056712482","full_name":"hjaltiatla/lan-nginx-reverse-proxy-cloudflare","owner":"hjaltiatla","description":"LAN-only NGINX reverse proxy with Let’s Encrypt wildcard certs via Cloudflare DNS-01 (Docker Compose).","archived":false,"fork":false,"pushed_at":"2025-09-14T18:04:12.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-14T19:12:19.750Z","etag":null,"topics":["certbot","cloudflare","docker","letsencrypt","nginx","reverse-proxy","self-hosted"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hjaltiatla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-14T16:49:28.000Z","updated_at":"2025-09-14T18:04:15.000Z","dependencies_parsed_at":"2025-09-14T19:12:21.610Z","dependency_job_id":"c478861a-1a4a-4c92-b712-8dafe21701ae","html_url":"https://github.com/hjaltiatla/lan-nginx-reverse-proxy-cloudflare","commit_stats":null,"previous_names":["hjaltiatla/lan-nginx-reverse-proxy-cloudflare"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hjaltiatla/lan-nginx-reverse-proxy-cloudflare","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjaltiatla%2Flan-nginx-reverse-proxy-cloudflare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjaltiatla%2Flan-nginx-reverse-proxy-cloudflare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjaltiatla%2Flan-nginx-reverse-proxy-cloudflare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjaltiatla%2Flan-nginx-reverse-proxy-cloudflare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hjaltiatla","download_url":"https://codeload.github.com/hjaltiatla/lan-nginx-reverse-proxy-cloudflare/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hjaltiatla%2Flan-nginx-reverse-proxy-cloudflare/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547778,"owners_count":26004772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certbot","cloudflare","docker","letsencrypt","nginx","reverse-proxy","self-hosted"],"created_at":"2025-10-06T01:26:46.388Z","updated_at":"2025-10-06T01:26:48.537Z","avatar_url":"https://github.com/hjaltiatla.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lan-nginx-reverse-proxy-cloudflare\n\nReverse proxy for a **home LAN** using **NGINX** and **Let’s Encrypt** wildcard certs via **Cloudflare DNS-01**.  \nDesigned for **LAN-only** access (no WAN port-forwarding). Each vhost is allowlisted to `192.168.144.0/24`.\n\n**Highlights**\n- Rootful `nginx:1.27-alpine` (simple cert permissions)\n- Host ports **80/443** bound to `LAN_BIND` only → container listens on **8080/8443**\n- Per-host servers: `pfsense.hjalti.me`, `unifi.hjalti.me`, `pve.hjalti.me`, `plex.hjalti.me`\n- **Wildcard** certificate for `hjalti.me` + `*.hjalti.me` via Cloudflare DNS-01\n- `certbot` runs **on-demand** (no long-running container)\n- **Healthcheck uses `nginx -t`** (config test); `/healthz` is provided for manual checks\n- Uses `http2 on;` (newer nginx syntax)\n\n\u003e Full guide: **[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)** • Troubleshooting: **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)**\n\n---\n\n## Quick start\n\n1) **pfSense DNS → Host Overrides**  \n   Point these to your Docker host LAN IP (e.g., `192.168.144.50`):\n   - `pfsense.hjalti.me`, `unifi.hjalti.me`, `pve.hjalti.me`, `plex.hjalti.me` → `192.168.144.50`\n\n2) **Configure env + secrets**\n```bash\ncp .env.example .env\ncp secrets/cloudflare.ini.example secrets/cloudflare.ini\nchmod 600 secrets/cloudflare.ini\n# edit .env\n#   LE_BASE_DOMAIN=hjalti.me\n#   LAN_BIND=192.168.144.50\n#   TZ=Atlantic/Reykjavik\n# paste your Cloudflare token (Zone.DNS:Edit on hjalti.me) into secrets/cloudflare.ini:\n#   dns_cloudflare_api_token = \u003ctoken\u003e\n```\n\n3) **Start services**\n```bash\ndocker compose up -d\n```\n\n4) **Issue the wildcard certificate**\n```bash\ndocker compose run --rm certbot certonly   --dns-cloudflare   --dns-cloudflare-credentials /secrets/cloudflare.ini   -d hjalti.me -d '*.hjalti.me'   --agree-tos --email you@hjalti.me --no-eff-email --non-interactive\n\ndocker exec nginx-rproxy nginx -t \u0026\u0026 docker exec nginx-rproxy nginx -s reload\n```\n\n5) **Verify from LAN**\n```bash\ncurl -I https://pfsense.hjalti.me\ncurl -I https://unifi.hjalti.me\ncurl -I https://pve.hjalti.me     # Proxmox may 501 on HEAD; GET returns 200\ncurl -I https://plex.hjalti.me\n```\n\n6) **Auto-renew (cron on the Docker host)**\n```bash\ncrontab -e\n```\nAdd:\n```\n0 2,14 * * * cd /path/to/lan-nginx-reverse-proxy-cloudflare \u0026\u0026   docker compose run --rm certbot renew     --dns-cloudflare --dns-cloudflare-credentials /secrets/cloudflare.ini     --quiet \u0026\u0026 docker exec nginx-rproxy nginx -s reload\n```\n\n---\n\n## Healthcheck\n\n- **Docker healthcheck:** uses a configuration test (robust across environments):\n```yaml\nhealthcheck:\n  test: [\"CMD\", \"nginx\", \"-t\"]\n  interval: 30s\n  timeout: 5s\n  retries: 5\n  start_period: 10s\n```\n- **Manual check (from host/LAN):** `/healthz` returns `ok` on port 8080:\n```bash\ncurl -s http://$LAN_BIND/healthz\n```\n\n---\n\n## Repo layout (key files)\n\n```\nconf.d/\n  00-global.conf\n  20-http-redirect.conf          # /healthz (200) + redirect everything else → HTTPS\n  pfsense.hjalti.me.conf         # LAN-only\n  unifi.hjalti.me.conf           # LAN-only + WebSockets\n  pve.hjalti.me.conf             # LAN-only + WebSockets\n  plex.hjalti.me.conf            # LAN-only + streaming opts\n  includes/\n    cloudflare-real-ip.conf      # optional (if ever proxying via Cloudflare)\ndocker-compose.yml               # binds host 80/443 to LAN_BIND -\u003e container 8080/8443\n.env.example\nsecrets/cloudflare.ini.example\ndocs/DEPLOYMENT.md\ndocs/TROUBLESHOOTING.md\nMakefile                          # helper targets (up/down/reload/issue-cert/renew/...)\n```\n\n---\n\n## Notes\n- Keep the Cloudflare token **scoped to a single zone** with **Zone → DNS → Edit** privileges.\n- No WAN port-forward is required; DNS-01 works with outbound-only API calls.\n- Back up the Let’s Encrypt Docker volume (`letsencrypt-backup.tgz` via `make backup-certs`).\n\n---\n\n## License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhjaltiatla%2Flan-nginx-reverse-proxy-cloudflare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhjaltiatla%2Flan-nginx-reverse-proxy-cloudflare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhjaltiatla%2Flan-nginx-reverse-proxy-cloudflare/lists"}