Change to use nginx instead of Caddy for docker registry
Some checks are pending
CI/CD Pipeline (Fully Isolated DinD) / Run Tests (DinD) (push) Waiting to run
CI/CD Pipeline (Fully Isolated DinD) / Build and Push Docker Images (DinD) (push) Blocked by required conditions
CI/CD Pipeline (Fully Isolated DinD) / Deploy to Production (push) Blocked by required conditions
Some checks are pending
CI/CD Pipeline (Fully Isolated DinD) / Run Tests (DinD) (push) Waiting to run
CI/CD Pipeline (Fully Isolated DinD) / Build and Push Docker Images (DinD) (push) Blocked by required conditions
CI/CD Pipeline (Fully Isolated DinD) / Deploy to Production (push) Blocked by required conditions
This commit is contained in:
parent
bf41839b8c
commit
0b4fb89e77
5 changed files with 163 additions and 90 deletions
|
@ -65,10 +65,10 @@ This guide covers setting up a complete Continuous Integration/Continuous Deploy
|
||||||
### CI/CD Linode Features
|
### CI/CD Linode Features
|
||||||
- Forgejo Actions runner for automated builds
|
- Forgejo Actions runner for automated builds
|
||||||
- **Docker-in-Docker (DinD) container** for isolated CI operations
|
- **Docker-in-Docker (DinD) container** for isolated CI operations
|
||||||
- Docker Registry with Caddy reverse proxy for image storage
|
- Docker Registry with nginx reverse proxy for image storage
|
||||||
- **FHS-compliant directory structure** for data, certificates, and logs
|
- **FHS-compliant directory structure** for data, certificates, and logs
|
||||||
- Unauthenticated pulls, authenticated pushes
|
- Unauthenticated pulls, authenticated pushes
|
||||||
- Automatic HTTPS with Caddy
|
- Automatic HTTPS with nginx
|
||||||
- Secure SSH communication with production
|
- Secure SSH communication with production
|
||||||
- **Simplified cleanup** - just restart DinD container
|
- **Simplified cleanup** - just restart DinD container
|
||||||
|
|
||||||
|
@ -654,9 +654,9 @@ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
sudo usermod -aG docker CI_SERVICE_USER
|
sudo usermod -aG docker CI_SERVICE_USER
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 5: Set Up Docker Registry with Caddy
|
### Step 5: Set Up Docker Registry with nginx
|
||||||
|
|
||||||
We'll set up a basic Docker Registry with Caddy as a reverse proxy, configured to allow unauthenticated pulls but require authentication for pushes.
|
We'll set up a basic Docker Registry with nginx as a reverse proxy, configured to allow unauthenticated pulls but require authentication for pushes.
|
||||||
|
|
||||||
#### 5.1 Configure FHS-Compliant Registry Directories
|
#### 5.1 Configure FHS-Compliant Registry Directories
|
||||||
|
|
||||||
|
@ -679,38 +679,34 @@ sudo chmod 755 /var/log/registry
|
||||||
# Navigate to the cloned application directory
|
# Navigate to the cloned application directory
|
||||||
cd /opt/APP_NAME/registry
|
cd /opt/APP_NAME/registry
|
||||||
|
|
||||||
# Update Caddyfile with your actual IP address
|
# Update nginx.conf with your actual IP address
|
||||||
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/Caddyfile
|
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/nginx.conf
|
||||||
|
|
||||||
# Update openssl.conf with your actual IP address and registry name
|
# Update openssl.conf with your actual IP address and registry name
|
||||||
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/openssl.conf
|
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/openssl.conf
|
||||||
sudo sed -i "s/YOUR_REGISTRY_NAME/APP_NAME-Registry/g" /opt/APP_NAME/registry/openssl.conf
|
sudo sed -i "s/YOUR_REGISTRY_NAME/APP_NAME-Registry/g" /opt/APP_NAME/registry/openssl.conf
|
||||||
|
|
||||||
# Create FHS-compliant environment directory
|
# Create FHS-compliant authentication directory
|
||||||
sudo mkdir -p /etc/registry/env
|
sudo mkdir -p /etc/registry/auth
|
||||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/env
|
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/auth
|
||||||
sudo chmod 755 /etc/registry/env
|
sudo chmod 755 /etc/registry/auth
|
||||||
|
|
||||||
# Create secure environment file for registry authentication
|
# Create htpasswd file for nginx authentication
|
||||||
# First, create a secure password hash
|
|
||||||
# Save this password somewhere safe
|
# Save this password somewhere safe
|
||||||
REGISTRY_PASSWORD="your-secure-registry-password"
|
REGISTRY_PASSWORD="your-secure-registry-password"
|
||||||
REGISTRY_PASSWORD_HASH=$(htpasswd -nbB registry-user "$REGISTRY_PASSWORD" | cut -d: -f2)
|
|
||||||
|
|
||||||
# Create the .env file in FHS-compliant location
|
# Create htpasswd file in FHS-compliant location
|
||||||
sudo tee /etc/registry/env/.env > /dev/null <<EOF
|
sudo htpasswd -cb /etc/registry/auth/.htpasswd registry-user "$REGISTRY_PASSWORD"
|
||||||
REGISTRY_PASSWORD_HASH=$REGISTRY_PASSWORD_HASH
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Set secure permissions on .env file (owner read/write only)
|
# Set secure permissions on htpasswd file (owner read/write only)
|
||||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/env/.env
|
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/auth/.htpasswd
|
||||||
sudo chmod 600 /etc/registry/env/.env
|
sudo chmod 600 /etc/registry/auth/.htpasswd
|
||||||
|
|
||||||
# Set proper permissions for configuration files
|
# Set proper permissions for configuration files
|
||||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/Caddyfile
|
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/nginx.conf
|
||||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/openssl.conf
|
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/openssl.conf
|
||||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/docker-compose.registry.yml
|
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/docker-compose.registry.yml
|
||||||
sudo chmod 644 /opt/APP_NAME/registry/Caddyfile
|
sudo chmod 644 /opt/APP_NAME/registry/nginx.conf
|
||||||
sudo chmod 644 /opt/APP_NAME/registry/openssl.conf
|
sudo chmod 644 /opt/APP_NAME/registry/openssl.conf
|
||||||
sudo chmod 644 /opt/APP_NAME/registry/docker-compose.registry.yml
|
sudo chmod 644 /opt/APP_NAME/registry/docker-compose.registry.yml
|
||||||
```
|
```
|
||||||
|
@ -928,8 +924,8 @@ sudo systemctl status docker-registry.service
|
||||||
# Check that containers are running
|
# Check that containers are running
|
||||||
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml ps"
|
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml ps"
|
||||||
|
|
||||||
# Check Caddy logs
|
# Check nginx logs
|
||||||
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml logs caddy"
|
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml logs nginx"
|
||||||
|
|
||||||
# Check Registry logs
|
# Check Registry logs
|
||||||
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml logs registry"
|
sudo su - CI_SERVICE_USER -c "cd /opt/APP_NAME/registry && docker compose -f docker-compose.registry.yml logs registry"
|
||||||
|
@ -1031,8 +1027,8 @@ openssl verify -CAfile /etc/registry/certs/ca/ca.crt /etc/registry/certs/registr
|
||||||
# Test the certificate connection
|
# Test the certificate connection
|
||||||
openssl s_client -connect YOUR_ACTUAL_IP_ADDRESS:4443 -servername YOUR_ACTUAL_IP_ADDRESS < /dev/null
|
openssl s_client -connect YOUR_ACTUAL_IP_ADDRESS:4443 -servername YOUR_ACTUAL_IP_ADDRESS < /dev/null
|
||||||
|
|
||||||
# Verify Caddy is using the correct certificates
|
# Verify nginx is using the correct certificates
|
||||||
docker exec caddy ls -la /etc/certs/
|
docker exec nginx ls -la /etc/registry/certs/
|
||||||
|
|
||||||
# If issues persist, restart Docker daemon to reload certificates
|
# If issues persist, restart Docker daemon to reload certificates
|
||||||
sudo systemctl restart docker
|
sudo systemctl restart docker
|
||||||
|
@ -1383,7 +1379,7 @@ The Docker Registry setup now follows the Filesystem Hierarchy Standard (FHS) fo
|
||||||
|
|
||||||
**Application Files** (in `/opt/APP_NAME/registry/`):
|
**Application Files** (in `/opt/APP_NAME/registry/`):
|
||||||
- `docker-compose.registry.yml` - Docker Compose configuration from project repository
|
- `docker-compose.registry.yml` - Docker Compose configuration from project repository
|
||||||
- `Caddyfile` - Caddy reverse proxy configuration from project repository
|
- `nginx.conf` - nginx reverse proxy configuration from project repository
|
||||||
- `openssl.conf` - OpenSSL configuration for certificate generation from project repository
|
- `openssl.conf` - OpenSSL configuration for certificate generation from project repository
|
||||||
- `docker-registry.service` - Systemd service file for Docker Registry
|
- `docker-registry.service` - Systemd service file for Docker Registry
|
||||||
|
|
||||||
|
@ -1394,10 +1390,9 @@ The Docker Registry setup now follows the Filesystem Hierarchy Standard (FHS) fo
|
||||||
- `/etc/registry/certs/ca/` - CA certificates (mode 644)
|
- `/etc/registry/certs/ca/` - CA certificates (mode 644)
|
||||||
- `/etc/registry/certs/requests/` - Certificate requests and configs (mode 644)
|
- `/etc/registry/certs/requests/` - Certificate requests and configs (mode 644)
|
||||||
- `/etc/registry/certs/registry.crt` - Server certificate (mode 644)
|
- `/etc/registry/certs/registry.crt` - Server certificate (mode 644)
|
||||||
- `/etc/registry/env/` - Environment variables and secrets:
|
- `/etc/registry/auth/.htpasswd` - nginx authentication file (mode 600)
|
||||||
- `/etc/registry/env/.env` - Registry authentication secrets (mode 600)
|
|
||||||
- `/etc/systemd/system/docker-registry.service` - Systemd service configuration
|
- `/etc/systemd/system/docker-registry.service` - Systemd service configuration
|
||||||
- `/var/log/registry/` - Registry and Caddy logs
|
- `/var/log/registry/` - Registry and nginx logs
|
||||||
|
|
||||||
**Benefits of FHS Compliance**:
|
**Benefits of FHS Compliance**:
|
||||||
- **Data persistence**: Registry data stored in `/var/lib/registry/data/` survives container restarts
|
- **Data persistence**: Registry data stored in `/var/lib/registry/data/` survives container restarts
|
||||||
|
@ -1538,7 +1533,7 @@ sudo ufw --force enable
|
||||||
sudo ufw default deny incoming
|
sudo ufw default deny incoming
|
||||||
sudo ufw default allow outgoing
|
sudo ufw default allow outgoing
|
||||||
sudo ufw allow ssh
|
sudo ufw allow ssh
|
||||||
sudo ufw allow 443/tcp # Docker Registry via Caddy (public read access)
|
sudo ufw allow 443/tcp # Docker Registry via nginx (public read access)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Security Model**:
|
**Security Model**:
|
||||||
|
@ -1852,7 +1847,7 @@ ls -la /opt/APP_NAME
|
||||||
|
|
||||||
### Step 13: Configure Docker for Docker Registry Access
|
### Step 13: Configure Docker for Docker Registry Access
|
||||||
|
|
||||||
**Important**: The Production Linode needs to be able to pull Docker images from the Docker Registry on the CI/CD Linode. Since we're using Caddy with automatic HTTPS, no additional certificate configuration is needed.
|
**Important**: The Production Linode needs to be able to pull Docker images from the Docker Registry on the CI/CD Linode. Since we're using nginx with automatic HTTPS, no additional certificate configuration is needed.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Change to the PROD_SERVICE_USER
|
# Change to the PROD_SERVICE_USER
|
||||||
|
@ -1873,7 +1868,7 @@ exit
|
||||||
|
|
||||||
**What this does**:
|
**What this does**:
|
||||||
- **Tests Docker Registry access**: Verifies that Docker can successfully pull images from the Docker Registry
|
- **Tests Docker Registry access**: Verifies that Docker can successfully pull images from the Docker Registry
|
||||||
- **No certificate configuration needed**: Caddy handles HTTPS automatically
|
- **No certificate configuration needed**: nginx handles HTTPS automatically
|
||||||
- **Simple setup**: No complex certificate management required
|
- **Simple setup**: No complex certificate management required
|
||||||
|
|
||||||
### Step 14: Set Up Forgejo Runner for Production Deployment
|
### Step 14: Set Up Forgejo Runner for Production Deployment
|
||||||
|
@ -2195,7 +2190,7 @@ Go to your Forgejo repository and add these secrets in **Settings → Secrets an
|
||||||
- `APP_NAME`: Your application name (e.g., `sharenet`)
|
- `APP_NAME`: Your application name (e.g., `sharenet`)
|
||||||
- `POSTGRES_PASSWORD`: A strong password for the PostgreSQL database
|
- `POSTGRES_PASSWORD`: A strong password for the PostgreSQL database
|
||||||
- `REGISTRY_USER`: Docker Registry username for CI operations (e.g., `registry-user`)
|
- `REGISTRY_USER`: Docker Registry username for CI operations (e.g., `registry-user`)
|
||||||
- `REGISTRY_PASSWORD`: Docker Registry password for CI operations (the password you set in the Caddyfile, default: `your-secure-registry-password`)
|
- `REGISTRY_PASSWORD`: Docker Registry password for CI operations (the password you set in the nginx configuration, default: `your-secure-registry-password`)
|
||||||
- `REGISTRY_PUSH_URL`: Docker Registry URL for authenticated pushes (e.g., `YOUR_CI_CD_IP:4443`)
|
- `REGISTRY_PUSH_URL`: Docker Registry URL for authenticated pushes (e.g., `YOUR_CI_CD_IP:4443`)
|
||||||
- `REGISTRY_PULL_URL`: Docker Registry URL for unauthenticated pulls (e.g., `YOUR_CI_CD_IP`)
|
- `REGISTRY_PULL_URL`: Docker Registry URL for unauthenticated pulls (e.g., `YOUR_CI_CD_IP`)
|
||||||
|
|
||||||
|
@ -2402,17 +2397,17 @@ sudo rm -rf /opt/APP_NAME/registry/certs/requests/openssl.conf
|
||||||
|
|
||||||
# Note: DO NOT remove these files as they are needed for operation:
|
# Note: DO NOT remove these files as they are needed for operation:
|
||||||
# - /opt/APP_NAME/registry/docker-compose.registry.yml
|
# - /opt/APP_NAME/registry/docker-compose.registry.yml
|
||||||
# - /opt/APP_NAME/registry/Caddyfile
|
# - /opt/APP_NAME/registry/nginx.conf
|
||||||
# - /opt/APP_NAME/registry/docker-registry.service
|
# - /opt/APP_NAME/registry/docker-registry.service
|
||||||
# - /etc/registry/env/.env (contains the actual secrets)
|
# - /etc/registry/auth/.htpasswd (contains the actual secrets)
|
||||||
# - /etc/systemd/system/docker-registry.service
|
# - /etc/systemd/system/docker-registry.service
|
||||||
```
|
```
|
||||||
|
|
||||||
**Security Note**: The `.env` file in `/etc/registry/env/.env` contains sensitive authentication data and should be:
|
**Security Note**: The `.htpasswd` file in `/etc/registry/auth/.htpasswd` contains sensitive authentication data and should be:
|
||||||
- **Backed up securely** if needed for disaster recovery
|
- **Backed up securely** if needed for disaster recovery
|
||||||
- **Never committed to version control**
|
- **Never committed to version control**
|
||||||
- **Protected with proper permissions** (600 - owner read/write only)
|
- **Protected with proper permissions** (600 - owner read/write only)
|
||||||
- **Rotated regularly** by updating the password and regenerating the hash
|
- **Rotated regularly** by updating the password and regenerating the htpasswd file
|
||||||
|
|
||||||
### Step 8.6 CI/CD Workflow Summary Table
|
### Step 8.6 CI/CD Workflow Summary Table
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Unauthenticated pulls on 443 (GET requests only)
|
|
||||||
:443 {
|
|
||||||
tls /etc/registry/certs/registry.crt /etc/registry/certs/private/registry.key
|
|
||||||
log
|
|
||||||
|
|
||||||
# Block all write operations explicitly
|
|
||||||
@writes method PUT POST PATCH DELETE
|
|
||||||
respond @writes "Method Not Allowed" 405
|
|
||||||
|
|
||||||
# Allow all GET requests to v2 API (Docker Registry itself will handle security)
|
|
||||||
reverse_proxy /v2/* registry:5000
|
|
||||||
}
|
|
||||||
|
|
||||||
# Auth-required pushes on 4443
|
|
||||||
:4443 {
|
|
||||||
tls /etc/registry/certs/registry.crt /etc/registry/certs/private/registry.key
|
|
||||||
log
|
|
||||||
|
|
||||||
# require auth on writes
|
|
||||||
@writes method PUT POST PATCH DELETE
|
|
||||||
basic_auth @writes {
|
|
||||||
registry-user {env.REGISTRY_PASSWORD_HASH}
|
|
||||||
}
|
|
||||||
|
|
||||||
# also require auth on the /v2/ ping so Docker sends creds
|
|
||||||
@v2ping {
|
|
||||||
path /v2/
|
|
||||||
method GET
|
|
||||||
}
|
|
||||||
basic_auth @v2ping {
|
|
||||||
registry-user {env.REGISTRY_PASSWORD_HASH}
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy /v2/* registry:5000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add Option B: Let's Encrypt certificates (Domain name)
|
|
|
@ -4,8 +4,8 @@ This folder contains the configuration files for the Docker Registry setup used
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
|
|
||||||
- **`docker-compose.registry.yml`**: Docker Compose configuration for the registry and Caddy reverse proxy
|
- **`docker-compose.registry.yml`**: Docker Compose configuration for the registry and nginx reverse proxy
|
||||||
- **`Caddyfile`**: Caddy configuration for HTTPS and authentication
|
- **`nginx.conf`**: nginx configuration for HTTPS and authentication
|
||||||
- **`docker-registry.service`**: Systemd service file for Docker Registry
|
- **`docker-registry.service`**: Systemd service file for Docker Registry
|
||||||
- **`README.md`**: This documentation file
|
- **`README.md`**: This documentation file
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ This folder contains the configuration files for the Docker Registry setup used
|
||||||
|
|
||||||
The registry setup uses:
|
The registry setup uses:
|
||||||
- **Docker Registry**: Basic registry for storing Docker images
|
- **Docker Registry**: Basic registry for storing Docker images
|
||||||
- **Caddy**: Reverse proxy with automatic HTTPS and authentication
|
- **nginx**: Reverse proxy with automatic HTTPS and authentication
|
||||||
- **Environment Variables**: For authentication credentials and registry configuration
|
- **Environment Variables**: For authentication credentials and registry configuration
|
||||||
- **Service User**: The registry and Caddy services run as the existing `CI_SERVICE_USER` (not a separate registry user)
|
- **Service User**: The registry and nginx services run as the existing `CI_SERVICE_USER` (not a separate registry user)
|
||||||
|
|
||||||
## Authentication Model
|
## Authentication Model
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ The registry setup uses:
|
||||||
The setup is configured through:
|
The setup is configured through:
|
||||||
1. **Environment Variables**: Stored in `.env` file (created during setup) for authentication
|
1. **Environment Variables**: Stored in `.env` file (created during setup) for authentication
|
||||||
2. **Docker Compose Environment**: Registry configuration via environment variables
|
2. **Docker Compose Environment**: Registry configuration via environment variables
|
||||||
3. **Caddyfile**: Handles HTTPS and authentication
|
3. **nginx.conf**: Handles HTTPS and authentication
|
||||||
4. **Docker Compose**: Orchestrates the registry and Caddy services
|
4. **Docker Compose**: Orchestrates the registry and nginx services
|
||||||
5. **Systemd Service**: Manages the Docker Registry service lifecycle
|
5. **Systemd Service**: Manages the Docker Registry service lifecycle
|
||||||
6. **User/Permissions**: All files and services are owned and run by `CI_SERVICE_USER` for consistency and security
|
6. **User/Permissions**: All files and services are owned and run by `CI_SERVICE_USER` for consistency and security
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ The registry is automatically set up during the CI/CD pipeline setup process. Th
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
- Authentication is handled by Caddy using environment variables
|
- Authentication is handled by nginx using htpasswd file
|
||||||
- HTTPS is automatically managed by Caddy
|
- HTTPS is automatically managed by nginx
|
||||||
- Registry data is persisted in Docker volumes
|
- Registry data is persisted in Docker volumes
|
||||||
- Environment file contains sensitive credentials and should be properly secured
|
- Environment file contains sensitive credentials and should be properly secured
|
||||||
- All files and services are owned by `CI_SERVICE_USER` (not a separate registry user)
|
- All files and services are owned by `CI_SERVICE_USER` (not a separate registry user)
|
|
@ -14,9 +14,9 @@ services:
|
||||||
expose:
|
expose:
|
||||||
- "5000" # internal only, not published
|
- "5000" # internal only, not published
|
||||||
|
|
||||||
caddy:
|
nginx:
|
||||||
image: caddy:2
|
image: nginx:alpine
|
||||||
container_name: caddy
|
container_name: nginx
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- registry
|
- registry
|
||||||
|
@ -25,7 +25,8 @@ services:
|
||||||
- "4443:4443"
|
- "4443:4443"
|
||||||
# deliberately no "80:80" – no HTTP
|
# deliberately no "80:80" – no HTTP
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
- /etc/registry/certs:/etc/registry/certs:ro
|
- /etc/registry/certs:/etc/registry/certs:ro
|
||||||
environment:
|
- /etc/registry/auth/.htpasswd:/etc/nginx/.htpasswd:ro
|
||||||
- REGISTRY_PASSWORD_HASH=${REGISTRY_PASSWORD_HASH}
|
- /var/log/nginx:/var/log/nginx
|
||||||
|
|
||||||
|
|
115
registry/nginx.conf
Normal file
115
registry/nginx.conf
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
# Docker Registry Nginx Configuration
|
||||||
|
# Port 443: Unauthenticated pulls (GET requests only)
|
||||||
|
# Port 4443: Authenticated operations (login, logout, push, delete, etc.)
|
||||||
|
|
||||||
|
# Upstream Docker Registry
|
||||||
|
upstream registry {
|
||||||
|
server registry:5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP server for unauthenticated pulls on port 443
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
# SSL Configuration
|
||||||
|
ssl_certificate /etc/registry/certs/registry.crt;
|
||||||
|
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options DENY;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
|
# Block all write operations explicitly
|
||||||
|
if ($request_method !~ ^(GET|HEAD)$) {
|
||||||
|
return 405 "Method Not Allowed";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow all GET requests to v2 API (Docker Registry itself will handle security)
|
||||||
|
location /v2/ {
|
||||||
|
proxy_pass http://registry;
|
||||||
|
proxy_set_header Host $http_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_read_timeout 900;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_send_timeout 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default location - deny all
|
||||||
|
location / {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
access_log /var/log/nginx/registry_access.log;
|
||||||
|
error_log /var/log/nginx/registry_error.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS server for authenticated operations on port 4443
|
||||||
|
server {
|
||||||
|
listen 4443 ssl http2;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
# SSL Configuration
|
||||||
|
ssl_certificate /etc/registry/certs/registry.crt;
|
||||||
|
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options DENY;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
|
# Basic authentication for write operations
|
||||||
|
location ~ ^/v2/.*$ {
|
||||||
|
# Require auth for all v2 API operations
|
||||||
|
auth_basic "Docker Registry";
|
||||||
|
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||||
|
|
||||||
|
proxy_pass http://registry;
|
||||||
|
proxy_set_header Host $http_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_read_timeout 900;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_send_timeout 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default location - deny all
|
||||||
|
location / {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
access_log /var/log/nginx/registry_auth_access.log;
|
||||||
|
error_log /var/log/nginx/registry_auth_error.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect HTTP to HTTPS (optional - for port 80 if needed)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue