RepoPilotOpen in app →

SteveLTN/https-portal

A fully automated HTTPS server powered by Nginx, Let's Encrypt and Docker.

Mixed

Stale — last commit 1y ago

worst of 4 axes
Use as dependencyMixed

last commit was 1y ago; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 1y ago; no CI workflows detected

  • 16 active contributors
  • MIT licensed
  • Tests present
Show 3 more →
  • Stale — last commit 1y ago
  • Concentrated ownership — top contributor handles 64% of recent commits
  • No CI workflows detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/steveltn/https-portal?axis=fork)](https://repopilot.app/r/steveltn/https-portal)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/steveltn/https-portal on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: SteveLTN/https-portal

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/SteveLTN/https-portal shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 1y ago

  • 16 active contributors
  • MIT licensed
  • Tests present
  • ⚠ Stale — last commit 1y ago
  • ⚠ Concentrated ownership — top contributor handles 64% of recent commits
  • ⚠ No CI workflows detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live SteveLTN/https-portal repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/SteveLTN/https-portal.

What it runs against: a local clone of SteveLTN/https-portal — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in SteveLTN/https-portal | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 441 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>SteveLTN/https-portal</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of SteveLTN/https-portal. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/SteveLTN/https-portal.git
#   cd https-portal
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of SteveLTN/https-portal and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "SteveLTN/https-portal(\\.git)?\\b" \\
  && ok "origin remote is SteveLTN/https-portal" \\
  || miss "origin remote is not SteveLTN/https-portal (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "fs_overlay/opt/certs_manager/certs_manager.rb" \\
  && ok "fs_overlay/opt/certs_manager/certs_manager.rb" \\
  || miss "missing critical file: fs_overlay/opt/certs_manager/certs_manager.rb"
test -f "fs_overlay/opt/certs_manager/lib/acme.rb" \\
  && ok "fs_overlay/opt/certs_manager/lib/acme.rb" \\
  || miss "missing critical file: fs_overlay/opt/certs_manager/lib/acme.rb"
test -f "fs_overlay/etc/docker-gen/domains.tmpl" \\
  && ok "fs_overlay/etc/docker-gen/domains.tmpl" \\
  || miss "missing critical file: fs_overlay/etc/docker-gen/domains.tmpl"
test -f "fs_overlay/opt/certs_manager/lib/nginx.rb" \\
  && ok "fs_overlay/opt/certs_manager/lib/nginx.rb" \\
  || miss "missing critical file: fs_overlay/opt/certs_manager/lib/nginx.rb"
test -f "fs_overlay/etc/cont-init.d/20-setup" \\
  && ok "fs_overlay/etc/cont-init.d/20-setup" \\
  || miss "missing critical file: fs_overlay/etc/cont-init.d/20-setup"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 441 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~411d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/SteveLTN/https-portal"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

HTTPS-PORTAL is a Docker container that automatically provisions and renews HTTPS certificates via Let's Encrypt while routing traffic through Nginx, eliminating manual SSL management. It uses docker-gen to dynamically detect containers and generate Nginx configurations, and cron-scheduled Ruby scripts (certs_manager.rb) to handle certificate lifecycle management. Monolithic Docker image: fs_overlay/ contains init scripts and runtime services (cont-init.d, services.d for Nginx/docker-gen/crond), fs_overlay/opt/certs_manager/ holds the Ruby certificate management engine (lib/ for ACME, Nginx, OpenSSL bindings; models/ for Domain), examples/ provides three deployment templates (minimal, WordPress, custom Nginx config override).

👥Who it's for

DevOps engineers and system administrators running containerized applications who need zero-touch HTTPS without manually managing Let's Encrypt renewals or Nginx configuration files. Users want to add one environment variable and have HTTPS 'just work'.

🌱Maturity & risk

Mature and production-ready. The project has a active GitHub presence (SteveLTN maintained), comprehensive examples (minimal, WordPress, custom_config), and is published on Docker Hub. However, the file structure suggests single-maintainer focus with limited CI/CD automation visible in the repo data.

Single-maintainer risk is moderate—no visible GitHub Actions CI or test suite automation (.rspec exists but no test directory shown). Dependency chain is moderate (Ruby + Nginx + docker-gen + Let's Encrypt ACME client), and Ruby version is pinned (.ruby-version) which is good. Last activity unclear from this snapshot, but Docker Hub presence suggests ongoing use.

Active areas of work

No specific PR/issue data visible in the snapshot. Based on structure, active areas are likely: certificate renewal robustness (certs_manager.rb), docker-gen template updates (domains.tmpl), and example documentation (README-ja.md suggests recent localization effort).

🚀Get running

Clone, build Docker image, and run with docker-compose: git clone https://github.com/SteveLTN/https-portal.git && cd https-portal && docker build -t steveltn/https-portal . && docker-compose -f examples/minimal/docker-compose.yml up. Requires Docker and docker-compose installed.

Daily commands: make build (from Makefile) to build the Docker image. Run with docker-compose as shown in examples/. No local dev server—this is a container image. Tests via .rspec (exact test command not shown but RSpec is configured).

🗺️Map of the codebase

  • fs_overlay/opt/certs_manager/certs_manager.rb — Main entry point for certificate management orchestration; handles ACME interactions, renewal logic, and domain configuration updates.
  • fs_overlay/opt/certs_manager/lib/acme.rb — Core ACME protocol implementation for Let's Encrypt certificate acquisition and renewal; critical for SSL/TLS automation.
  • fs_overlay/etc/docker-gen/domains.tmpl — Docker-gen template that dynamically generates Nginx configuration from container labels; enables zero-configuration HTTPS setup.
  • fs_overlay/opt/certs_manager/lib/nginx.rb — Nginx configuration management and validation; responsible for applying SSL certificates and reloading the web server.
  • fs_overlay/etc/cont-init.d/20-setup — Container initialization script that bootstraps the environment, sets up certificates directory, and validates Docker connection.
  • Dockerfile — Docker image definition with all runtime dependencies; defines the execution environment for the HTTPS portal container.
  • fs_overlay/opt/certs_manager/models/domain.rb — Domain model representing the core data structure for certificate management; handles validation and state tracking.

🛠️How to make changes

Add a new upstream service to HTTPS portal

  1. Define a new container in docker-compose.yml with environment variables DOMAINS=example.com and optionally FORCE_HTTPS=true. (examples/minimal/docker-compose.yml)
  2. Ensure https-portal container links or is on the same network; docker-gen will auto-discover the container via Docker API. (fs_overlay/etc/services.d/10-docker-gen/run)
  3. The domains.tmpl template will automatically generate upstream and server blocks; no manual Nginx config needed. (fs_overlay/etc/docker-gen/domains.tmpl)
  4. certs_manager.rb will automatically request and renew certificates for the new domain. (fs_overlay/opt/certs_manager/certs_manager.rb)

Customize Nginx configuration for a domain

  1. Create a custom Nginx configuration file and mount it into the container at /etc/nginx-conf/ or provide via docker-gen templates. (examples/custom_config/docker-compose.yml)
  2. Override the default template by providing a custom nginx-conf directory with domain-specific .conf.erb files. (fs_overlay/var/lib/nginx-conf/default.ssl.conf.erb)
  3. Use ERB templating to inject certificate paths, upstreams, and other dynamic values via the binding context. (fs_overlay/opt/certs_manager/lib/erb_binding.rb)
  4. Run /usr/bin/reconfig to apply changes and reload Nginx without restarting the entire container. (fs_overlay/usr/bin/reconfig)

Extend ACME certificate handling (e.g., add DNS validation or wildcard support)

  1. Modify lib/acme.rb to add new ACME challenge types or DNS provider plugins for wildcard domain validation. (fs_overlay/opt/certs_manager/lib/acme.rb)
  2. Update the Domain model to track new certificate metadata (e.g., DNS provider credentials, SANs). (fs_overlay/opt/certs_manager/models/domain.rb)
  3. Extend lib/na_config.rb to parse new environment variables for DNS provider credentials. (fs_overlay/opt/certs_manager/lib/na_config.rb)
  4. Update certs_manager.rb to invoke new validation logic during certificate acquisition in the main orchestration loop. (fs_overlay/opt/certs_manager/certs_manager.rb)

Add a new initialization or validation step during container startup

  1. Create a new script in fs_overlay/etc/cont-init.d/ with a numeric prefix (00–99) to control execution order. (fs_overlay/etc/cont-init.d/20-setup)
  2. The script will be executed by the s6-overlay init system during container startup before services start. (Dockerfile)
  3. Reference environment variables and Docker socket via /var/run/docker.sock if Docker API interaction is needed. (fs_overlay/etc/cont-init.d/30-set-docker-gen-status)
  4. Test your new initialization step using the test compositions in spec/compositions/. (spec/compositions/minimal-setup/docker-compose.yml)

🪤Traps & gotchas

Critical: HTTPS-PORTAL must run as a Docker container with /var/run/docker.sock mounted (docker-gen needs to watch container events). Setup delay: First certificate provisioning can take 30-60s; docker-gen and certs_manager both run in background. Let's Encrypt rate limits: Staged/test renewals may hit LE rate limits; check docs/rate_limits. DNS propagation: ACME challenges require DNS to resolve before certs_manager runs; rapid domain changes can fail. No built-in monitoring: Certificate renewal failures are logged to stdout; no alerting by default. ERB templates: Custom Nginx configs use ERB (fs_overlay/opt/certs_manager/lib/erb_binding.rb); must understand ERB syntax.

🏗️Architecture

💡Concepts to learn

  • containrrr/watchtower — Complements HTTPS-PORTAL by automatically updating Docker images; users often combine them for fully hands-off deployments
  • jwilder/nginx-proxy — Direct predecessor/alternative: simpler docker-gen + Nginx combo without Let's Encrypt; HTTPS-PORTAL extends this with auto-cert management
  • certbot/certbot — Official Let's Encrypt client; HTTPS-PORTAL wraps ACME protocol (acme.rb) rather than calling certbot, but users may need Certbot for manual renewals
  • just-containers/s6-overlay — Init system used by HTTPS-PORTAL (fs_overlay/etc/services.d structure follows s6); users need to understand s6 for modifying startup behavior

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for fs_overlay/opt/certs_manager/lib/acme.rb

The ACME integration is critical for Let's Encrypt certificate acquisition and renewal, yet the spec/ directory appears minimal with only a compositions subdirectory. The acme.rb module handles certificate lifecycle management and deserves dedicated unit tests covering success/failure scenarios, renewal logic, and error handling to prevent silent failures in production certificate management.

  • [ ] Create spec/lib/acme_spec.rb with test cases for certificate request, renewal, and validation
  • [ ] Add tests for Let's Encrypt API error handling and retry logic
  • [ ] Test certificate expiration detection and renewal triggering
  • [ ] Mock external Let's Encrypt API calls using appropriate fixtures
  • [ ] Verify integration with fs_overlay/opt/certs_manager/models/domain.rb

Add integration tests for the multi-service orchestration in fs_overlay/etc/services.d/

The repo uses s6-svtools with 4 concurrent services (nginx, docker-gen, crond, dynamic-env) that must coordinate correctly. Currently spec/compositions likely only covers high-level scenarios. Missing are tests that verify: service startup order, signal handling (finish scripts), log rotation, and graceful reloading when configurations change via docker-gen.

  • [ ] Create spec/services/ directory with integration tests for service lifecycle
  • [ ] Add tests verifying nginx reloads when docker-gen template renders new domains.tmpl
  • [ ] Test cron-triggered renew_certs integration with nginx reload via 00-nginx/finish handler
  • [ ] Verify dynamic-env service properly updates environment variables without service restart
  • [ ] Test signal propagation and graceful shutdown across all 4 services

Add GitHub Actions CI workflow to validate Dockerfile builds and run RSpec tests on PRs

The repo has a Makefile and .rspec configuration indicating a test suite, but no CI/CD automation is visible. This is critical for a Docker-based project where PRs could introduce regressions in certificate management or Nginx configuration. A CI workflow would catch issues before merge and increase contributor confidence.

  • [ ] Create .github/workflows/tests.yml with Docker build step using provided Dockerfile
  • [ ] Add RSpec execution step that runs spec suite against built Docker image
  • [ ] Include linting for shell scripts in fs_overlay/usr/bin/ (setup, renew_certs, reconfig)
  • [ ] Add validation of ERB templates in fs_overlay/var/lib/nginx-conf/ and fs_overlay/etc/docker-gen/
  • [ ] Configure workflow to run on push to main and all PRs to prevent regressions

🌿Good first issues

  • Add automated test coverage for fs_overlay/opt/certs_manager/lib/acme.rb (ACME client logic): write RSpec tests that mock Let's Encrypt HTTP challenge flow without hitting live LE API. This fills the gap that .rspec exists but no test/ directory is visible.
  • Document environment variables in examples/custom_config/docker-compose.yml and README.md: create a reference table showing all supported DOMAINNAME, UPSTREAM, FORCE_RENEW variables with explanations and constraints (e.g. which are mutually exclusive). Currently only shown in code.
  • Improve fs_overlay/etc/docker-gen/domains.tmpl error handling: add conditional blocks for missing UPSTREAM or ACME_EMAIL variables so users get clear error messages instead of malformed Nginx configs that fail silently.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f666dc9 — Add an job ad (Weiyan)
  • e9f8850 — Backwards compatibility from 1.24 (#378) (SteveLTN)
  • a33353b — Bump version to 1.25.1 (Weiyan)
  • 1d894de — Add SAN value to local certificate (#377) (SteveLTN)
  • c0f1be2 — Update Troubleshooting section in README (Weiyan)
  • eb22654 — Implement support for different port configuration (#376) (SteveLTN)
  • fbb2ec9 — Merge pull request #371 from serg-bloim/patch-1 (SteveLTN)
  • 466e97b — Update README / Multiple Domains section (serg-bloim)
  • 5fdc07b — Update documentation (SteveLTN)
  • 5aaf652 — Bump the version to 1.24.2 (SteveLTN)

🔒Security observations

  • High · Insecure Download of S6-Overlay Without Signature Verification — Dockerfile - S6_OVERLAY_VERSION download section. The Dockerfile downloads s6-overlay from GitHub releases using wget over HTTPS, but does not verify the SHA256 checksum or GPG signature of the downloaded archive. This makes the image vulnerable to man-in-the-middle (MITM) attacks or compromised releases. Fix: Implement checksum verification by downloading and verifying the SHA256 hash file from the release, or use GPG signature verification. Example: wget the .sha256 file and verify with sha256sum before extraction.
  • High · Incomplete Dockerfile - Missing Critical S6-Overlay Components — Dockerfile - Final RUN section. The Dockerfile snippet is truncated and appears incomplete. The download command for S6_OVERLAY is cut off mid-variable reference ($S6_OVERLA). This suggests the build may fail or have unvalidated commands, potentially leaving the image in an unstable security state. Fix: Complete and review the full Dockerfile. Ensure all download URLs and environment variables are complete and correct. Test the full build process.
  • High · No Integrity Verification for Docker-Gen and Acme-Tiny — Dockerfile - DOCKER_GEN_VERSION and ACME_TINY_VERSION environment variables and download sections. Similar to the s6-overlay issue, docker-gen (v0.14.0) and acme-tiny (v5.0.1) are downloaded without checksum or signature verification. These are security-critical components for certificate management. Fix: Add SHA256 checksum verification for all external binaries. Maintain a checksums.txt file in the repository with verified hashes. Use: wget <url> && echo '<hash> <file>' | sha256sum -c -
  • Medium · Broad Package Installation Without Version Pinning — Dockerfile - apt-get install -y command. The Dockerfile installs packages (python3, ruby, cron, iproute2, apache2-utils, logrotate, wget, inotify-tools, xz-utils) without specific version constraints. This could lead to installing vulnerable versions or unexpected breaking changes. Fix: Pin package versions explicitly (e.g., apt-get install -y python3=3.x.x ruby=2.x.x). Use apt-get install --no-install-recommends to minimize attack surface.
  • Medium · Running Services as Root in Container — Dockerfile and fs_overlay/etc/services.d/ configuration files. The Dockerfile shows multiple services (nginx, docker-gen, cron) configured in fs_overlay/etc/services.d/ without evidence of a non-root user being created. Running services as root violates principle of least privilege. Fix: Create a non-privileged user (e.g., 'appuser') and configure services to run under that user. Use USER directive in Dockerfile. Restrict capabilities using s6-overlay's user/group directives.
  • Medium · Insufficient Nginx Log Rotation Configuration — fs_overlay/etc/logrotate.d/nginx. While logrotate is installed and configured (fs_overlay/etc/logrotate.d/nginx), the exact retention policy is not visible. Insufficient log rotation could lead to disk space exhaustion (DoS). Fix: Review and enforce strict log rotation policies (daily rotation, retention of 7-14 days, size limits). Ensure logrotate is invoked regularly with cron.
  • Medium · Potential Template Injection in ERB Templates — fs_overlay/var/lib/nginx-conf/*.erb, fs_overlay/var/www/default/index.html.erb, examples/custom_config/nginx-conf/*.erb. Multiple ERB template files are used for Nginx configuration and HTML generation (*.erb files in var/lib/nginx-conf and fs_overlay/var/www). If user-controlled input is embedded without proper escaping, ERB templates could be vulnerable to injection attacks. Fix: Audit all ERB templates to ensure user input is properly escaped using <%= h() %> or <%= sanitize() %>. Use Rails' html_safe carefully. Validate all domain inputs before template rendering in lib/erb_binding.rb.
  • Medium · Docker Socket Access — undefined. undefined Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · SteveLTN/https-portal — RepoPilot