Skip to content

A Docker-based Nginx reverse proxy with SSL/HTTPS support using mkcert for local development. Includes dnsmasq for local domain resolution.

Notifications You must be signed in to change notification settings

yhbyun/docker-nginx-ssl-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Docker Nginx SSL Proxy

English ν•œκ΅­μ–΄

A Docker Compose-based Nginx reverse proxy with SSL/HTTPS support using mkcert and dnsmasq DNS server for local development.

πŸ“– ν•œκ΅­μ–΄ λ¬Έμ„œ 보기

✨ Features

  • βœ… SSL/HTTPS Support - Trusted local certificates using mkcert
  • βœ… Independent Domains - example1.test, example2.test, etc.
  • βœ… DNS Server - Local domain resolution via dnsmasq
  • βœ… Docker Network - Shared network for inter-service communication
  • βœ… HTTP/2 Support - Latest protocol support
  • βœ… Auto Redirect - HTTP β†’ HTTPS

πŸ“ Project Structure

project/
β”œβ”€β”€ proxy/                          # Reverse proxy server
β”‚   β”œβ”€β”€ docker-compose.yml          # Proxy container definition
β”‚   β”œβ”€β”€ nginx/
β”‚   β”‚   β”œβ”€β”€ nginx.conf              # Nginx main config
β”‚   β”‚   └── conf.d/
β”‚   β”‚       β”œβ”€β”€ example1.test.conf  # example1.test virtual host
β”‚   β”‚       └── example2.test.conf  # example2.test virtual host
β”‚   β”œβ”€β”€ certs/                      # SSL certificates (mkcert)
β”‚   β”‚   β”œβ”€β”€ example1.test.pem
β”‚   β”‚   β”œβ”€β”€ example1.test-key.pem
β”‚   β”‚   β”œβ”€β”€ example2.test.pem
β”‚   β”‚   └── example2.test-key.pem
β”‚   └── dnsmasq/
β”‚       └── dnsmasq.conf            # DNS server config
β”œβ”€β”€ backend1/                       # Backend service 1
β”‚   β”œβ”€β”€ docker-compose.yml
β”‚   └── html/
β”‚       └── index.html
└── backend2/                       # Backend service 2
    β”œβ”€β”€ docker-compose.yml
    └── html/
        └── index.html

πŸš€ Quick Start

1. Prerequisites

Install mkcert

# macOS
brew install mkcert

# Linux (Ubuntu/Debian)
sudo apt install libnss3-tools
wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
sudo mv mkcert /usr/local/bin/

# Windows
choco install mkcert

Install mkcert CA

mkcert -install

2. Create Project Directories

mkdir -p proxy/{nginx/conf.d,certs,dnsmasq} backend1/html backend2/html

3. Generate SSL Certificates

cd proxy/certs

# Use TRUST_STORES to skip Firefox/Java errors
TRUST_STORES=system mkcert example1.test
TRUST_STORES=system mkcert example2.test

# Verify generated files
ls -la *.pem

4. Configure DNS

macOS (Recommended)

sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/test

Linux/Windows or Simple Method

# Edit /etc/hosts
sudo nano /etc/hosts

# Add these lines
127.0.0.1 example1.test
127.0.0.1 example2.test

5. Start Services

Proxy Server

cd proxy
docker-compose up -d

Backend Services

# Backend 1
cd ../backend1
echo '<h1>Backend 1 - HTTPS Works! πŸŽ‰</h1>' > html/index.html
docker-compose up -d

# Backend 2
cd ../backend2
echo '<h1>Backend 2 - HTTPS Works! πŸš€</h1>' > html/index.html
docker-compose up -d

6. Test Access

Open in browser:

πŸ”§ Troubleshooting

Port 53 Conflict (macOS)

If local dnsmasq or another DNS server is using port 53:

# Check port 53 usage
sudo lsof -i :53

# Check Homebrew services
brew services list

# Stop Homebrew dnsmasq
sudo brew services stop dnsmasq

# Restart Docker dnsmasq
cd proxy
docker-compose restart dnsmasq

Apple Silicon (M1/M2/M3) Compatibility

The docker-compose.yml already includes platform: linux/amd64 setting for automatic handling.

mkcert Certificate Generation Error

If Firefox/Java related errors occur:

# Use TRUST_STORES environment variable
TRUST_STORES=system mkcert example1.test

DNS Resolution Failure

# Test DNS
nslookup example1.test 127.0.0.1
dig @127.0.0.1 example1.test

# Flush DNS cache
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

# Linux
sudo systemd-resolve --flush-caches

# Windows
ipconfig /flushdns

βœ… Validation & Testing

Check Container Status

docker ps

Running containers should include:

  • nginx-proxy
  • dnsmasq
  • backend1-nginx
  • backend2-nginx

Check Logs

# All logs
docker-compose logs -f

# Specific service logs
docker logs nginx-proxy
docker logs dnsmasq

Verify HTTP/2

curl -I --http2 https://example1.test

Response header should show HTTP/2 200!

Verify SSL Certificate

# Display certificate info
openssl s_client -connect example1.test:443 -servername example1.test < /dev/null | openssl x509 -noout -text

# Check certificate expiration
openssl s_client -connect example1.test:443 -servername example1.test 2>/dev/null | openssl x509 -noout -dates

Test Nginx Configuration

docker exec nginx-proxy nginx -t

πŸ”„ Service Management

Restart

# Restart proxy only
cd proxy
docker-compose restart

# Reload Nginx config (zero downtime)
docker exec nginx-proxy nginx -s reload

# Restart all services
docker-compose restart

Stop

# Stop proxy
cd proxy
docker-compose down

# Stop backends
cd ../backend1 && docker-compose down
cd ../backend2 && docker-compose down

Complete Removal

# Stop and remove all containers
cd proxy && docker-compose down
cd ../backend1 && docker-compose down
cd ../backend2 && docker-compose down

# Remove network
docker network rm proxy-network

βž• Adding New Domain

1. Generate SSL Certificate

cd proxy/certs
TRUST_STORES=system mkcert example3.test

2. Create Nginx Virtual Host Config

cd ../nginx/conf.d
cp example1.test.conf example3.test.conf

Edit example3.test.conf:

# HTTP -> HTTPS redirect
server {
    listen 80;
    server_name example3.test;

    return 301 https://$server_name$request_uri;
}

# HTTPS
server {
    listen 443 ssl;
    http2 on;
    server_name example3.test;

    ssl_certificate /etc/nginx/certs/example3.test.pem;
    ssl_certificate_key /etc/nginx/certs/example3.test-key.pem;

    access_log /var/log/nginx/example3.test.access.log;
    error_log /var/log/nginx/example3.test.error.log;

    location / {
        proxy_pass http://backend3-nginx:80;
        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";
    }
}

3. Configure DNS (if using hosts file)

# Add to /etc/hosts
sudo nano /etc/hosts
# 127.0.0.1 example3.test

4. Create Backend Service

mkdir -p ../../backend3/html
cd ../../backend3

Create docker-compose.yml:

services:
  backend3-nginx:
    image: nginx:alpine
    container_name: backend3-nginx
    volumes:
      - ./html:/usr/share/nginx/html:ro
    networks:
      - proxy-network
    restart: unless-stopped

networks:
  proxy-network:
    external: true

5. Start Services

# Start backend service
echo '<h1>Backend 3</h1>' > html/index.html
docker-compose up -d

# Restart proxy
cd ../proxy
docker-compose restart

6. Test

curl -I --http2 https://example3.test

πŸ” Advanced Configuration

Load Balancing

upstream backend_servers {
    server backend1-nginx:80;
    server backend2-nginx:80;
}

server {
    location / {
        proxy_pass http://backend_servers;
    }
}

Rate Limiting

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

server {
    location / {
        limit_req zone=mylimit burst=20;
        proxy_pass http://backend1-nginx:80;
    }
}

Static File Caching

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

πŸ“š References

🀝 Contributing

Issues and pull requests are always welcome!

πŸ“„ License

MIT License

About

A Docker-based Nginx reverse proxy with SSL/HTTPS support using mkcert for local development. Includes dnsmasq for local domain resolution.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages