This project sets up a local HTTPS environment using:
- Traefik as a reverse proxy
- Smallstep Step CA for issuing local TLS certificates via ACME
- Automatic trust installation for
root_ca.crt
- Taskfile automation (
task
) for convenience - Zero DNS configuration thanks to sslip.io
- This allows you to access services like
https://traefik.127-0-0-1.sslip.io
without any DNS configuration.
- This allows you to access services like
- 🛡️ Local Dev with Traefik + Step CA + ACME TLS
- Table of Contents
- 🔧 Project Structure
- 🚀 Quick Start
- 🧪 Example: Secure PostgreSQL behind Traefik
- 🌐 Example: HTTP Service (MinIO) Behind Traefik
- 🛠 Available Tasks
- 🌐 Traefik Dashboard
- 🔐 Step CA Access
- 📄 TLS Certificate Details
- 🌐 Network Architecture
- 🛡 Security Notes
- 🧼 Cleanup
- 📦 Requirements
- Screenshots
docker-compose.yaml
: Orchestrates Traefik and Step CAtraefik/traefik-static.yaml
: Static Traefik configuration with ACME resolvertaskfile.yaml
: CLI automation withtask
certs/
: Extracted TLS certificates, including the root CA
> [!NOTE]
> Step CA uses `network_mode: host` to resolve `127.0.0.1` domains during ACME challenges, while Traefik connects via `host.docker.internal` for certificate requests.
First, clone this repository to a local directory where you'll be running your development environment:
git clone https://github.com/teyfix/traefik
cd traefik
Make sure you're inside the cloned folder before running any of the next steps.
task up
This will:
- Start Step CA and Traefik
- Wait until Step CA is healthy
- Traefik will generate and request certs using ACME
task certs:install
This will:
- Copy
root_ca.crt
from the Step CA container - Install it to your system trust store via
update-ca-certificates
✅ Works for WSL, Debian, Ubuntu, etc.
Tip
You can use /usr/local/share/ca-certificates/traefik-stepca-root-ca.crt
as the root certificate for apps that does not use the system trust store.
To make Windows trust the locally issued TLS certificates:
task certs
explorer.exe certs
Then follow these steps to install the certificate:
- In the opened folder, double-click the file named
root_ca.crt
. - A security warning will appear — click "Open".
- The certificate viewer will open. Click "Install Certificate...".
- Choose "Local Machine" (this requires administrator privileges), then click Next.
- Select "Place all certificates in the following store", then click Browse.
- Choose "Trusted Root Certification Authorities", then click OK.
- Click Next, then Finish.
- A final prompt will confirm the installation — click Yes.
🛡️ You should now be able to visit services like
https://traefik.127-0-0-1.sslip.io
in your browser without any certificate warnings.
You can run services like PostgreSQL behind Traefik using TCP with TLS termination:
networks:
traefik_proxy:
name: traefik_proxy
external: true
services:
postgres:
image: teyfix/timescaledb-pgrx:latest
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.teyfix_pg.rule=HostSNI(`pg.teyfix.127-0-0-1.sslip.io`)"
- "traefik.tcp.routers.teyfix_pg.entrypoints=shared"
- "traefik.tcp.routers.teyfix_pg.service=teyfix_pg"
- "traefik.tcp.routers.teyfix_pg.tls=true"
- "traefik.tcp.routers.teyfix_pg.tls.certresolver=stepca"
- "traefik.tcp.services.teyfix_pg.loadbalancer.server.port=5432"
networks:
- traefik_proxy
You can now securely connect to PostgreSQL at pg.teyfix.127-0-0-1.sslip.io:4040
with TLS.
Note
Port 4040
corresponds to the shared
TCP entrypoint defined in Traefik's configuration, which is designed for non-HTTP services like databases.
You can also expose standard HTTP services like MinIO behind Traefik with HTTPS:
networks:
traefik_proxy:
name: traefik_proxy
external: true
services:
minio:
image: minio/minio:latest
environment:
# Prevents redirecting to the console when accessing the API directly
- MINIO_BROWSER_REDIRECT=false
expose:
- 9000 # API
- 9001 # Console
networks:
- traefik_proxy
labels:
- "traefik.enable=true"
# MinIO API
- "traefik.http.routers.teyfix_minio_api.rule=Host(`minio-api.teyfix.127-0-0-1.sslip.io`)"
- "traefik.http.routers.teyfix_minio_api.tls=true"
- "traefik.http.routers.teyfix_minio_api.entrypoints=websecure"
- "traefik.http.routers.teyfix_minio_api.tls.certresolver=stepca"
- "traefik.http.routers.teyfix_minio_api.service=teyfix_minio_api"
- "traefik.http.services.teyfix_minio_api.loadbalancer.server.port=9000"
# MinIO Console
- "traefik.http.routers.teyfix_minio_console.rule=Host(`minio-console.teyfix.127-0-0-1.sslip.io`)"
- "traefik.http.routers.teyfix_minio_console.tls=true"
- "traefik.http.routers.teyfix_minio_console.entrypoints=websecure"
- "traefik.http.routers.teyfix_minio_console.tls.certresolver=stepca"
- "traefik.http.routers.teyfix_minio_console.service=teyfix_minio_console"
- "traefik.http.services.teyfix_minio_console.loadbalancer.server.port=9001"
✅ Once running, you can securely access:
https://minio-api.teyfix.127-0-0-1.sslip.io
for the APIhttps://minio-console.teyfix.127-0-0-1.sslip.io
for the web console
Task | Description |
---|---|
task up |
Start containers with fresh state |
task down |
Stop and remove containers, volumes, orphans |
task recreate |
Fully restart the stack |
task logs |
Follow logs of all containers |
task certs |
Export certs from the Step CA container |
task certs:install |
Install the root CA into your Linux trust store |
Once up, you can access the Traefik dashboard via either:
- HTTPS (recommended):
https://traefik.127-0-0-1.sslip.io
- HTTP (insecure):
http://localhost:8080
Tip
The HTTPS version uses certificates issued by your local Step CA, while the HTTP version runs in insecure mode for development convenience.
If you need direct access to Step CA for advanced certificate management:
https://localhost:9000
Note
Direct Step CA access is typically not needed for normal development workflows, as Traefik handles certificate requests automatically via ACME.
- Root CA is generated by Step CA and used by Traefik's ACME resolver
- Certificates are stored under
/home/step/certs/
in thestepca
container - Traefik mounts these and uses them via
certResolver: stepca
This setup uses a specific networking configuration to handle certificate validation:
- Step CA runs in
network_mode: host
to properly resolve127.0.0.1
domains during ACME challenges - Traefik connects to Step CA via
host.docker.internal:9000
for certificate requests - Services run on the
traefik_proxy
bridge network for proper service discovery
Important
Step CA cannot access Traefik services for ACME validation when both are on Docker bridge networks due to 127.0.0.1
resolution limitations. The host networking mode for Step CA resolves this issue.
- This setup is for local/dev use only
- Certificates are not publicly trusted
- Browsers may still show a warning unless root CA is manually trusted
task down
This will stop and remove everything, including volumes and orphan containers.