SSL Certificate Management System - 22 DNS providers, Multi-CA support, Enterprise-ready
50K+
CertMate is an SSL certificate management system for modern infrastructure. Multi-DNS provider support, Docker-ready, comprehensive REST API.
Full Documentation: https://github.com/fabriziosalmi/certmate
One file, this image, nothing to build:
mkdir certmate && cd certmate
curl -fsSLO https://raw.githubusercontent.com/fabriziosalmi/certmate/main/deploy/docker-compose.yml
printf 'API_BEARER_TOKEN=%s\nSECRET_KEY=%s\nCERTMATE_BACKUP_PASSPHRASE=%s\n' \
"$(openssl rand -hex 32)" "$(openssl rand -hex 32)" "$(openssl rand -hex 32)" > .env
chmod 600 .env
docker compose up -d
Open http://127.0.0.1:8000. The first page creates the administrator account and asks for the API_BEARER_TOKEN from .env to authorize it. The file pins the latest release, keeps its data in named volumes and listens on loopback only. What each setting does, and how to upgrade.
docker run -d --name certmate \
-p 127.0.0.1:8000:8000 \
-e API_BEARER_TOKEN="$(openssl rand -hex 32)" \
-e SECRET_KEY="$(openssl rand -hex 32)" \
-v certmate_certificates:/app/certificates \
-v certmate_data:/app/data \
-v certmate_logs:/app/logs \
-v certmate_backups:/app/backups \
fabriziosalmi/certmate:latest
Write the two values down (or use an env file): the first-run screen asks for the token, and a new SECRET_KEY signs everyone out.
| Provider | Multi-Account | Status |
|---|---|---|
| Cloudflare | Stable | |
| AWS Route53 | Stable | |
| Azure DNS | Stable | |
| Google Cloud DNS | Stable | |
| DigitalOcean | Stable | |
| PowerDNS | Stable | |
| RFC2136 | Stable | |
| Linode | Stable | |
| Gandi | Stable | |
| OVH | Stable | |
| Namecheap | Stable | |
| Vultr | Stable | |
| DNS Made Easy | Stable | |
| NS1 | Stable | |
| Hetzner | Stable | |
| Porkbun | Stable | |
| GoDaddy | Stable | |
| Hurricane Electric | Stable | |
| Dynu | Stable | |
| ArvanCloud | Stable | |
| Infomaniak | Stable | |
| ACME-DNS | Stable |
# Create certificate
curl -X POST "http://localhost:8000/api/certificates/create" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domain": "example.com",
"email": "[email protected]"
}'
# Download certificate (ZIP)
curl "http://localhost:8000/api/certificates/example.com/download" \
-H "Authorization: Bearer YOUR_TOKEN" \
-o certificate.zip
# Renew certificate
curl -X POST "http://localhost:8000/api/certificates/example.com/renew" \
-H "Authorization: Bearer YOUR_TOKEN"
# List certificates
curl "http://localhost:8000/api/certificates" \
-H "Authorization: Bearer YOUR_TOKEN"
API_BEARER_TOKEN - Bearer token for the API; the first-run screen asks for it to create the admin. API_BEARER_TOKEN_FILE reads it from a file instead and takes precedenceSECRET_KEY - Key that signs login sessions. SECRET_KEY_FILE reads it from a file instead and takes precedenceCERTMATE_BACKUP_PASSPHRASE - Without it, automatic backups are masked and cannot restore the instance; with it they are complete and encrypted at restCLOUDFLARE_TOKEN - Optional: creates a Cloudflare DNS account on first startLETSENCRYPT_EMAIL - Optional: overrides the ACME contact email set in the UIBEHIND_PROXY - true when a trusted reverse proxy sets X-Forwarded-*PORT - Listen port inside the container (default 8000)FLASK_ENV - Environment mode (default: production)DNS providers other than Cloudflare are not configured through environment variables. Route53, Azure, Google Cloud DNS, DigitalOcean, Hetzner and the rest are added in the web UI (Settings → DNS Providers) or through the API. See the DNS provider guide.
The bind address is fixed to 0.0.0.0 inside the container; publish it as -p 127.0.0.1:8000:8000 to reach it on loopback only.
| Path | Holds |
|---|---|
/app/certificates | Certificates and their private keys |
/app/data | Settings, users, inventory, audit chain |
/app/backups | Backup archives |
/app/logs | Application logs |
Use named volumes: Docker creates them with the ownership CertMate needs. A bind mount to a host directory must be prepared first (chgrp -R 0 <dir> && chmod -R g+rwX <dir>), because CertMate runs as a non-root user and refuses to start on a directory it cannot write.
Images available for:
linux/amd64 - x86_64 systemslinux/arm64 - ARM64/Apple SiliconDocker automatically pulls the correct architecture.
CertMate includes unified atomic backups:
# Create backup via API
curl -X POST "http://localhost:8000/api/backups/create" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"type": "unified"}'
# List backups
curl "http://localhost:8000/api/backups" \
-H "Authorization: Bearer YOUR_TOKEN"
# Restore from backup
curl -X POST "http://localhost:8000/api/backups/restore/unified" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"filename": "backup_20240101_120000.tar.gz"}'
# Health check endpoint
curl http://localhost:8000/health
# Response
{
"status": "healthy",
"version": "2.48.0",
"checks": {
"cert_dir": "ok",
"disk_space": "ok",
"disk_free_mb": 94504,
"scheduler": "running"
}
}
# Check logs
docker logs certmate
# Verify permissions
ls -la data/ certificates/ letsencrypt/
dig _acme-challenge.example.com TXT/api/certificates/{domain}/renewContributions welcome! See CONTRIBUTING.md
MIT License - see LICENSE
Content type
Image
Digest
sha256:ffed75287…
Size
143.2 MB
Last updated
about 6 hours ago
docker pull fabriziosalmi/certmate