mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration and creates certificates that work with:
- ✅ localhost
- ✅ IP addresses (192.168.1.100)
- ✅ Custom domains (timetracker.local)
- ✅ NO browser warnings!
Perfect for development and local network deployment.
Option 1: Chocolatey
choco install mkcertOption 2: Scoop
scoop bucket add extras
scoop install mkcertbrew install mkcertUbuntu/Debian:
sudo apt install libnss3-tools
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcertArch Linux:
sudo pacman -S mkcertWindows:
setup-https-mkcert.batLinux/Mac:
bash setup-https-mkcert.shThis will:
- Install local Certificate Authority (CA)
- Generate certificates for localhost + your IP
- Create nginx configuration
- Create docker-compose.https.yml
- Update .env with secure settings
docker-compose -f docker-compose.yml -f docker-compose.https.yml up -dhttps://localhost
https://192.168.1.100 (your IP)
https://timetracker.local
No certificate warnings! 🎉
If you prefer to do it manually:
mkcert -installThis installs a local Certificate Authority on your system that browsers will trust.
# Create directories
mkdir -p nginx/ssl
# Generate certs (replace 192.168.1.100 with your IP)
mkcert -key-file nginx/ssl/key.pem \
-cert-file nginx/ssl/cert.pem \
localhost 127.0.0.1 ::1 192.168.1.100 *.localWindows PowerShell:
mkdir nginx\ssl -Force
mkcert -key-file nginx\ssl\key.pem -cert-file nginx\ssl\cert.pem localhost 127.0.0.1 ::1 192.168.1.100 *.localCreate nginx/conf.d/https.conf:
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name _;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://app:8080;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}services:
nginx:
image: nginx:alpine
container_name: timetracker-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: unless-stopped
app:
ports: [] # nginx handles ports
environment:
- WTF_CSRF_SSL_STRICT=true
- SESSION_COOKIE_SECURE=true
- CSRF_COOKIE_SECURE=trueWTF_CSRF_SSL_STRICT=true
SESSION_COOKIE_SECURE=true
CSRF_COOKIE_SECURE=truedocker-compose -f docker-compose.yml -f docker-compose.https.yml up -dTo access from phones, tablets, or other computers on your network without certificate warnings:
mkcert -CAROOTThis shows the directory containing rootCA.pem
Example output:
/Users/username/Library/Application Support/mkcert
C:\Users\username\AppData\Local\mkcert
Transfer the rootCA.pem file to your device via:
- USB drive
- Network share
- Cloud storage
iOS/iPadOS:
- Open
rootCA.pemfile - Install profile
- Settings → General → About → Certificate Trust Settings
- Enable the certificate
Android:
- Settings → Security → Encryption & credentials
- Install certificate from storage
- Select
rootCA.pem
Windows:
- Double-click
rootCA.pem - Install Certificate
- Store: Local Machine → Trusted Root Certification Authorities
macOS:
- Double-click
rootCA.pem - Add to Keychain
- Trust for SSL
Linux:
sudo cp rootCA.pem /usr/local/share/ca-certificates/mkcert-rootCA.crt
sudo update-ca-certificateshttps://192.168.1.100
✅ No certificate warning!
- Navigate to
https://localhost - Click the padlock icon
- View certificate details
- Should show:
- ✅ Issued by: mkcert
- ✅ Valid for: localhost, 127.0.0.1, your IP
- ✅ No warnings
# Should redirect to HTTPS
curl -I http://localhost
# Should show 301 redirect# Check nginx is running
docker-compose ps nginx
# Check nginx logs
docker-compose logs nginx- Access via HTTPS
- Open DevTools (F12) → Application → Cookies
- Verify cookies have
Secureflag - Test form submissions (login, create project)
- Should work without CSRF errors
Cause: CA not installed or browser not restarted
Solution:
# Reinstall CA
mkcert -install
# Restart browser completely (close all windows)
# Clear browser cache and cookiesCause: Browser doesn't trust the CA
Solution:
- Check CA is installed:
mkcert -CAROOT - Reinstall:
mkcert -install - On Linux, may need
libnss3-tools - Restart browser
Cause: Port 80 or 443 already in use
Check:
# Windows
netstat -ano | findstr :443
# Linux/Mac
lsof -i :443Solution:
# Stop conflicting service or change ports in docker-compose.https.yml
ports:
- "8080:80"
- "8443:443"Cause: IP not included when generating cert
Solution:
# Regenerate with your IP
mkcert -key-file nginx/ssl/key.pem \
-cert-file nginx/ssl/cert.pem \
localhost 127.0.0.1 ::1 YOUR_IP_HERE *.local
# Restart nginx
docker-compose restart nginxCause: CA not installed on device
Solution:
- Follow "Access from Other Devices" section above
- Install rootCA.pem on each device
- Restart browser/app on device
mkcert certificates are valid for 10 years by default. No renewal needed for development use!
To check expiration:
openssl x509 -in nginx/ssl/cert.pem -noout -datesTo regenerate:
# Re-run setup script
bash setup-https-mkcert.sh
# Or manually
mkcert -key-file nginx/ssl/key.pem -cert-file nginx/ssl/cert.pem localhost 127.0.0.1 ::1 YOUR_IP *.local
# Restart nginx
docker-compose restart nginxmkcert is designed for development and testing:
- ✅ Perfect for local development
- ✅ Great for LAN/home network
- ✅ Safe for trusted networks
- ❌ NOT for production internet-facing apps
Use real certificates:
- Let's Encrypt (free, automated)
- Commercial CA (paid)
- Use Caddy for automatic HTTPS
See production deployment guides for details.
- ✅ Keep rootCA.pem secure (anyone with it can create trusted certs)
- ✅ Don't commit
nginx/ssl/*.pemto git (add to .gitignore) - ✅ Use different certs for each project
- ✅ Uninstall CA when not needed:
mkcert -uninstall
# Install CA
mkcert -install
# Find CA location
mkcert -CAROOT
# Generate certificate
mkcert -key-file KEY.pem -cert-file CERT.pem DOMAIN1 DOMAIN2
# Uninstall CA
mkcert -uninstall
# Check certificate
openssl x509 -in CERT.pem -text -noout✅ Local HTTPS with NO warnings ✅ Works with IP addresses ✅ Trusted by all browsers ✅ Valid for 10 years ✅ Perfect for development
# Install mkcert
# Windows: choco install mkcert
# Mac: brew install mkcert
# Run setup
bash setup-https-mkcert.sh
# Start with HTTPS
docker-compose -f docker-compose.yml -f docker-compose.https.yml up -d
# Access
https://localhost
https://192.168.1.100That's it! Enjoy secure HTTPS! 🔒