Cloudflare Origin Certificate Setup Guide
Overview
This guide covers setting up Cloudflare Origin Certificates with custom SSL paths for Docker Compose applications. Origin Certificates are free and included in Cloudflare’s free tier.
Prerequisites
- Domain managed by Cloudflare (free plan or higher)
- Docker Compose application with Nginx
- Server with directory structure access
Understanding Cloudflare SSL
Two-Layer Certificate System
- Edge Certificate (Cloudflare ↔ Visitors)
- Issued by: Google Trust Services or Let’s Encrypt
- Validity: 3 months (auto-renewed by Cloudflare)
- Managed by: Cloudflare (no action required)
- What browsers see
- Origin Certificate (Cloudflare ↔ Your Server)
- Issued by: Cloudflare
- Validity: 15 years
- Managed by: You
- What you configure on your server
Step 1: Create Origin Certificate
Navigate to Cloudflare Dashboard
- Login to dash.cloudflare.com
- Select your domain
- Go to: SSL/TLS → Origin Server
- Click “Create Certificate”
Certificate Configuration
- Private key type: RSA (2048) – recommended
- Certificate format: PEM
- Hostnames:
*.yourdomain.comyourdomain.com(Wildcard covers all subdomains) - Certificate Validity: 15 years (recommended)
Generate Certificate
Click “Create”
You will see TWO text boxes:
Box 1: Origin Certificate
-----BEGIN CERTIFICATE-----
MIIEpDCCA4ygAwIBAgIUd...
(multiple lines)
...
-----END CERTIFICATE-----
Box 2: Private Key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0...
(multiple lines)
...
-----END PRIVATE KEY-----
CRITICAL: The private key is shown ONLY ONCE. Save it immediately or you’ll need to regenerate.
Step 2: Save Certificates to Server
Create SSL Directory
mkdir -p nginx/ssl
Save Origin Certificate
nano nginx/ssl/nginx.crt
Paste the entire Origin Certificate including:
-----BEGIN CERTIFICATE------ All certificate content
-----END CERTIFICATE-----
Save and exit (Ctrl+X, Y, Enter)
Save Private Key
nano nginx/ssl/nginx.key
Paste the entire Private Key including:
-----BEGIN PRIVATE KEY------ All key content
-----END PRIVATE KEY-----
Save and exit (Ctrl+X, Y, Enter)
Set Proper Permissions
chmod 644 nginx/ssl/nginx.crt
chmod 600 nginx/ssl/nginx.key
Security Note: Private key should only be readable by owner (600).
Step 3: Configure Docker Compose
Update docker-compose.yml
Add volume mounts to your nginx service:
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl/nginx.crt:/etc/nginx/ssl/nginx.crt:ro
- ./nginx/ssl/nginx.key:/etc/nginx/ssl/nginx.key:ro
restart: unless-stopped
Notes:
:roflag makes files read-only inside container- Paths on left are host system paths
- Paths on right are container internal paths
Step 4: Configure Nginx
Basic SSL Configuration
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
# SSL Certificate paths (inside container)
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Your application configuration
location / {
proxy_pass http://your-app:port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Step 5: Deploy
Start Services
docker compose up -d
or
docker-compose up -d
Verify Deployment
# Check nginx container logs
docker compose logs nginx
# Verify certificate files inside container
docker compose exec nginx ls -la /etc/nginx/ssl/
# Test HTTPS connection
curl -I https://yourdomain.com
Cloudflare SSL/TLS Settings
Required Cloudflare Configuration
In Cloudflare dashboard → SSL/TLS → Overview:
Set encryption mode to: Full (strict)
SSL/TLS Modes Explained:
- Off: No encryption (not recommended)
- Flexible: Cloudflare ↔ Visitor encrypted, Cloudflare ↔ Server unencrypted
- Full: End-to-end encryption, accepts self-signed certificates
- Full (strict): End-to-end encryption, requires valid certificate ✅
Troubleshooting
Error: Cannot load certificate
Symptom:
cannot load certificate "/etc/nginx/ssl/nginx.crt":
BIO_new_file() failed (SSL: error:80000002:system library::No such file or directory)
Solutions:
- Verify files exist on host:
ls -la nginx/ssl/ - Check file permissions:
chmod 644 nginx/ssl/nginx.crt chmod 600 nginx/ssl/nginx.key - Verify files are not empty:
cat nginx/ssl/nginx.crt cat nginx/ssl/nginx.key - Restart nginx:
docker compose restart nginx
Error: Empty certificate files
If you forgot to paste content or files are 0 bytes:
# Check file sizes
ls -lh nginx/ssl/
# If empty, re-paste certificate content
nano nginx/ssl/nginx.crt
nano nginx/ssl/nginx.key
Lost Private Key
If you lost the private key:
- Go to Cloudflare → SSL/TLS → Origin Server
- Delete the old certificate
- Create a new certificate
- Save BOTH the certificate and private key immediately
Certificate Verification
Test your SSL setup:
# Test SSL handshake
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
# Check certificate expiry
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates
Certificate Renewal
Origin Certificate (15 years)
- Validity: 15 years from creation
- Action required: Regenerate before expiry
- Reminder: Set calendar reminder for year 2040 (or your expiry date)
Edge Certificate (3 months)
- Validity: 90 days
- Action required: None (auto-renewed by Cloudflare)
- Note: This is the certificate browsers see
Security Best Practices
File Permissions
# Certificate (public) - readable by all
chmod 644 nginx/ssl/nginx.crt
# Private key (secret) - readable only by owner
chmod 600 nginx/ssl/nginx.key
Directory Structure
Recommended structure:
project/
├── docker-compose.yml
├── nginx/
│ ├── nginx.conf
│ └── ssl/
│ ├── nginx.crt (644 permissions)
│ └── nginx.key (600 permissions)
Version Control
NEVER commit private keys to Git:
# Add to .gitignore
echo "nginx/ssl/*.key" >> .gitignore
Consider committing certificates (public):
# Certificates are public, safe to commit
git add nginx/ssl/nginx.crt
Backup
Backup your private key securely:
# Encrypt and backup
gpg -c nginx/ssl/nginx.key
# Store nginx.key.gpg in secure locationFAQ
Q: Do I need to pay for Cloudflare Origin Certificates?
A: No, they’re included in the free plan.
Q: Can I use Certbot with Cloudflare?
A: Not needed. Cloudflare Origin Certificates are simpler and last 15 years.
Q: Why does my browser show a 3-month certificate?
A: That’s the Edge Certificate between Cloudflare and visitors. It’s auto-renewed. Your 15-year Origin Certificate is for Cloudflare-to-server encryption.
Q: What happens if my Origin Certificate expires?
A: Your site will show SSL errors. Regenerate before expiry (15 years).
Q: Can I use the same certificate for multiple servers?
A: Yes, but each server needs both the certificate AND private key files.
Q: Do wildcards cost extra?
A: No, wildcard Origin Certificates are free.
Resources
Summary
- Generate Origin Certificate in Cloudflare (free)
- Save certificate as
nginx.crtand private key asnginx.key - Mount files in Docker Compose with
:roflag - Configure Nginx to use certificates
- Set Cloudflare SSL mode to “Full (strict)”
- Certificates last 15 years, no renewal automation needed







