Every self-hosted infrastructure eventually runs into the same problem: TLS certificates. You set up a home lab, deploy a dozen services behind a reverse proxy, and suddenly you are wrestling with expired certs, self-signed warnings, and Let’s Encrypt rate limits. If you manage internal services that are not publicly accessible — databases, monitoring dashboards, container registries — public CAs cannot help you at all.
This is where a self-hosted Public Key Infrastructure (PKI) becomes essential. Running your own certificate authority gives you complete control over certificate issuance, lifecycles, trust chains, and revocation — without depending on external services.
Why Self-Host Your Certificate Authority
The case for running your own CA grows stronger every year:
- Internal services need TLS too. Every service in your homelab or corporate network benefits from encrypted connections. A self-hosted CA issues certificates for services that have no public domain name.
- No rate limits. Let’s Encrypt enforces strict issuance limits per domain per week. With your own CA, you can issue unlimited certificates.
- Short-lived certificates by default. Modern security best practices favor certificates that expire in hours or days rather than years. Your own CA can automate this without cost.
- Zero external dependencies. No OCSP responders calling home, no Certificate Transparency logs exposing your internal hostnames, no reliance on a third-party service staying online.
- Unified trust. Install one root certificate on all your devices and every internal service is trusted automatically. No more clicking “Proceed Anyway” in your browser.
- Compliance and audit. Many security frameworks (SOC 2, ISO 27001) require documented certificate management processes. A self-hosted CA gives you full audit trails.
- Cost savings at scale. If you manage dozens or hundreds of services, wildcard certificates from commercial CAs get expensive quickly.
In 2026, three solutions stand out for self-hosted certificate management: Step CA, Caddy, and nginx Proxy Manager with ACME integration. Each takes a fundamentally different approach.
Option 1: Step CA — The Dedicated Certificate Authority
Step CA by Smallstep is the most powerful and purpose-built self-hosted certificate authority available. Written in Go, it implements the full ACME protocol, supports SCEP for legacy device enrollment, and provides a CLI tool (step) that makes certificate management trivial.
Architecture
Step CA runs as a lightweight daemon that listens on a configurable port. It manages its own root CA key pair, intermediate CA, certificate database, and revocation list. Clients communicate with it over HTTPS using the ACME protocol or the native Step CA protocol.
Key features:
- Full ACME v2 support (HTTP-01, TLS-ALPN-01, DNS-01 challenges)
- SCEP support for enrolling routers, switches, and IoT devices
- Automatic certificate renewal via
step-caagent - X.509 and SSH certificate issuance from the same CA
- Provisioners for OIDC, JWK, AWS IAM, Azure, GCP, and X.509 bootstrap
- Certificate revocation with CRL and OCSP
- Webhook-based authorization for custom policy enforcement
- Runs on a Raspberry Pi with minimal resources
Installation and Setup
The fastest way to deploy Step CA is with docker:
| |
Initialize the CA:
| |
Bootstrap a client machine to trust your CA:
| |
Issue your first certificate:
| |
ACME Integration
Step CA fully supports ACME, which means any ACME-compatible client can use it as a drop-in replacement for Let’s Encrypt:
| |
SSH Certificates
One of Step CA’s standout features is unified X.509 and SSH certificate management:
| |
With SSH certificates, you eliminate SSH key distribution entirely. The CA signs user keys on demand, and any server that trusts the CA automatically accepts them.
Option 2: Caddy — The Self-Healing Web Server
Caddy is a web server and reverse proxy with built-in automatic TLS certificate management. While not a full CA in the traditional sense, Caddy’s certificate automation capabilities make it an excellent choice for self-hosted environments that primarily need public-facing TLS.
Architecture
Caddy integrates directly with Let’s Encrypt and ZeroSSL for public certificates, and can also use Step CA or other ACME servers for internal certificates. Its standout feature is fully automatic certificate issuance and renewal — you never need to think about certificates again.
Key features:
- Automatic HTTPS with zero configuration
- Built-in ACME client for Let’s Encrypt, ZeroSSL, and custom CAs
- On-demand TLS — issues certificates at connection time for unknown domains
- OCSP stapling enabled by default
- DNS challenge support for 50+ providers (Cloudflare, Route 53, GoDaddy, etc.)
- Graceful certificate reloading with zero downtime
- JSON API for dynamic configuration
- Written in Go, single binary deployment
Installation and Setup
Install Caddy and configure it to issue certificates automatically:
| |
Configure with a Caddyfile:
| |
On-Demand TLS
Caddy’s on-demand TLS feature is unique — it issues certificates the first time a client connects to a new domain:
| |
This is incredibly useful for multi-tenant environments where new subdomains are created dynamically. Caddy checks with your backend whether the domain is authorized, then issues and caches the certificate automatically.
Docker Deployment
| |
Option 3: Nginx Proxy Manager — The GUI Approach
Nginx Proxy Manager provides a web-based interface for managing Nginx reverse proxies with integrated Let’s Encrypt certificate management. It is the most beginner-friendly option and perfect for homelab users who prefer a graphical interface over configuration files.
Architecture
NPM wrapostgresqlith a Vue.js web UI and a SQLite/MySQL/PostgreSQL database for configuration storage. Certificate requests are handled through a built-in ACME client that talks to Let’s Encrypt.
Key features:
- Web-based management interface
- One-click Let’s Encrypt certificate issuance
- Automatic certificate renewal
- DNS challenge support for popular providers
- Access lists with basic authentication
- Stream (TCP/UDP) proxy support
- Custom Nginx configuration overrides
- SSL certificate import for custom CA certs
Installation and Setup
| |
Access the web UI at http://your-server:81 (default credentials: admin@example.com / changeme).
Issuing Certificates via the UI
- Navigate to SSL Certificates in the sidebar
- Click Add SSL Certificate
- Choose Let’s Encrypt
- Enter your domain name(s)
- Select DNS challenge if the domain is not publicly accessible
- Click Save — NPM handles the ACME challenge and stores the certificate
Using Custom CA Certificates
For internal services, you can upload certificates issued by your own CA:
- Go to SSL Certificates → Add SSL Certificate → Custom
- Upload the certificate key, certificate, and intermediate chain
- Assign the certificate to any proxy host
This works well in combination with Step CA: use Step CA to issue internal certificates, then upload them to NPM for use with your reverse proxy rules.
Comparison: Step CA vs Caddy vs Nginx Proxy Manager
| Feature | Step CA | Caddy | Nginx Proxy Manager |
|---|---|---|---|
| Type | Dedicated CA | Web server + ACME client | GUI proxy manager |
| Root CA | Self-hosted root | Uses Let’s Encrypt / ZeroSSL | Uses Let’s Encrypt |
| ACME Server | Yes (full ACME v2) | ACME client only | ACME client only |
| ACME Client | Built-in step CLI | Built-in | Built-in (certbot) |
| Internal Certs | Native — primary use case | Via custom ACME CA | Manual import only |
| Auto Renewal | Via step-ca agent | Built-in (default 30 days) | Built-in (daily check) |
| SSH Certificates | Yes | No | No |
| SCEP Support | Yes | No | No |
| DNS Challenges | ACME DNS-01 | 50+ providers | Limited set |
| On-Demand TLS | No | Yes | No |
| Web UI | No (CLI only) | No (JSON API) | Yes (Vue.js) |
| Beginner Friendly | Moderate | Moderate | Excellent |
| Resource Usage | ~50 MB RAM | ~30 MB RAM | ~100 MB RAM |
| Written In | Go | Go | Node.js + Nginx |
| Best For | Enterprise PKI, SSH | Public-facing services | Homelabs, beginners |
Recommended Architecture: Combining All Three
The most robust self-hosted PKI setup combines these tools:
| |
Full Deployment Example
Here is a complete Docker Compose setup that ties everything together:
| |
Corresponding Caddyfile:
| |
Certificate Lifecycle Best Practices
Regardless of which tool you choose, follow these principles:
1. Use Short-Lived Certificates
Certificates should expire in hours or days, not years. Step CA makes this easy:
| |
Short-lived certificates eliminate the need for revocation — if a key is compromised, the certificate expires before an attacker can do much damage.
2. Automate Renewal
Never manually renew certificates. Use automated agents:
| |
3. Distribute the Root CA Properly
Install your root CA on all client devices:
| |
4. Monitor Certificate Expiry
Even with automation, monitor your certificates:
| |
5. Back Up Your Root CA
Your root CA key is the most critical secret in your infrastructure. Back it up securely:
| |
Which Should You Choose?
The decision depends on your needs:
Choose Step CA if: You run internal services that need TLS, want SSH certificates, require short-lived certificates, or need enterprise-grade PKI with SCEP and webhook support. It is the gold standard for self-hosted certificate authorities.
Choose Caddy if: Your primary need is public-facing TLS with zero configuration, you want on-demand certificate issuance for dynamic domains, or you need a reverse proxy that handles HTTPS automatically.
Choose Nginx Proxy Manager if: You prefer a web interface, manage a homelab with a handful of services, want the simplest possible setup, or are new to TLS certificate management.
Best practice: Run Step CA as your internal certificate authority and use Caddy as your edge reverse proxy. Caddy handles public-facing Let’s Encrypt certificates while using Step CA for any internal domains. This gives you the best of both worlds — automatic public TLS and complete control over your internal PKI.
The days of self-signed certificate warnings and manual certificate management are over. Pick a tool, deploy it once, and let automation handle the rest.
Frequently Asked Questions (FAQ)
Which one should I choose in 2026?
The best choice depends on your specific requirements:
- For beginners: Start with the simplest option that covers your core use case
- For production: Choose the solution with the most active community and documentation
- For teams: Look for collaboration features and user management
- For privacy: Prefer fully open-source, self-hosted options with no telemetry
Refer to the comparison table above for detailed feature breakdowns.
Can I migrate between these tools?
Most tools support data import/export. Always:
- Backup your current data
- Test the migration on a staging environment
- Check official migration guides in the documentation
Are there free versions available?
All tools in this guide offer free, open-source editions. Some also provide paid plans with additional features, priority support, or managed hosting.
How do I get started?
- Review the comparison table to identify your requirements
- Visit the official documentation (links provided above)
- Start with a Docker Compose setup for easy testing
- Join the community forums for troubleshooting