361 lines
7.5 KiB
Markdown
361 lines
7.5 KiB
Markdown
# NPM Configuration for Docker Registry (registry.directlx.dev)
|
|
|
|
## Overview
|
|
|
|
This guide configures Nginx Proxy Manager to proxy `registry.directlx.dev` to the backend Docker registry at `192.168.200.200:5000` with HTTPS/SSL termination.
|
|
|
|
## Prerequisites
|
|
|
|
- ✅ DNS configured: registry.directlx.dev → 192.168.200.71
|
|
- ✅ NPM running at 192.168.200.71
|
|
- ✅ Docker registry running at 192.168.200.200:5000
|
|
- ⚠️ NPM admin access required
|
|
|
|
## Step-by-Step Configuration
|
|
|
|
### 1. Access NPM Admin Panel
|
|
|
|
```bash
|
|
# Open in browser
|
|
http://192.168.200.71:81/
|
|
|
|
# Default credentials (if first time):
|
|
# Email: admin@example.com
|
|
# Password: changeme
|
|
```
|
|
|
|
### 2. Create Proxy Host
|
|
|
|
Navigate to: **Hosts** → **Proxy Hosts** → **Add Proxy Host**
|
|
|
|
#### Details Tab
|
|
|
|
**Domain Names:**
|
|
```
|
|
registry.directlx.dev
|
|
```
|
|
|
|
**Scheme:** `http`
|
|
|
|
**Forward Hostname / IP:** `192.168.200.200`
|
|
|
|
**Forward Port:** `5000`
|
|
|
|
**Options:**
|
|
- ☐ Cache Assets
|
|
- ☑ Block Common Exploits
|
|
- ☑ Websockets Support (for Docker registry v2 API)
|
|
- ☐ Access List
|
|
|
|
#### SSL Tab
|
|
|
|
**SSL Certificate:**
|
|
- Select existing Let's Encrypt certificate for `*.directlx.dev`, OR
|
|
- Request New SSL Certificate:
|
|
- ☑ Force SSL
|
|
- ☑ HTTP/2 Support
|
|
- ☑ HSTS Enabled
|
|
- ☑ HSTS Subdomains
|
|
- Email: `your-email@example.com`
|
|
- ☑ I Agree to the Let's Encrypt Terms of Service
|
|
|
|
**Note:** If using wildcard certificate, ensure DNS challenge is configured.
|
|
|
|
#### Advanced Tab (IMPORTANT for Docker Registry)
|
|
|
|
Add the following custom Nginx configuration:
|
|
|
|
```nginx
|
|
# Docker Registry v2 API requires specific headers
|
|
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;
|
|
|
|
# Increase timeouts for large image pushes
|
|
proxy_connect_timeout 300;
|
|
proxy_send_timeout 300;
|
|
proxy_read_timeout 300;
|
|
send_timeout 300;
|
|
|
|
# Disable buffering for chunked uploads
|
|
proxy_request_buffering off;
|
|
|
|
# Allow large body sizes for Docker images (5GB max)
|
|
client_max_body_size 5120M;
|
|
|
|
# Disable access log for registry (too verbose)
|
|
access_log off;
|
|
```
|
|
|
|
### 3. Save and Test
|
|
|
|
Click **Save** to create the proxy host.
|
|
|
|
### 4. Verify Configuration
|
|
|
|
#### Test DNS Resolution
|
|
|
|
```bash
|
|
nslookup registry.directlx.dev
|
|
# Should return: 192.168.200.71
|
|
```
|
|
|
|
#### Test HTTPS Access
|
|
|
|
```bash
|
|
curl -I https://registry.directlx.dev/v2/
|
|
# Expected: HTTP/2 200
|
|
```
|
|
|
|
#### Test Docker Registry API
|
|
|
|
```bash
|
|
# List repositories
|
|
curl -s https://registry.directlx.dev/v2/_catalog | jq '.'
|
|
|
|
# Expected output:
|
|
# {
|
|
# "repositories": [
|
|
# "atm-incident-backend",
|
|
# "hiveops-incident",
|
|
# ...
|
|
# ]
|
|
# }
|
|
```
|
|
|
|
#### Test Docker Pull
|
|
|
|
```bash
|
|
docker pull registry.directlx.dev/hiveops-incident:latest
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### 502 Bad Gateway
|
|
|
|
**Cause:** NPM can't reach backend registry
|
|
|
|
**Check backend is running:**
|
|
```bash
|
|
ansible docker -m shell -a "docker ps | grep registry"
|
|
ansible docker -m shell -a "curl -I http://localhost:5000/v2/"
|
|
```
|
|
|
|
**Check firewall:**
|
|
```bash
|
|
ansible docker -m shell -a "ufw status" -b
|
|
```
|
|
|
|
### SSL Certificate Error
|
|
|
|
**Cause:** Let's Encrypt can't verify domain
|
|
|
|
**Solution:**
|
|
1. Ensure port 80/443 are open on NPM server
|
|
2. Verify DNS propagation: `nslookup registry.directlx.dev`
|
|
3. Check NPM logs: **Tools** → **Error Logs**
|
|
|
|
### 413 Request Entity Too Large
|
|
|
|
**Cause:** `client_max_body_size` too small
|
|
|
|
**Solution:** Add to Advanced tab:
|
|
```nginx
|
|
client_max_body_size 5120M;
|
|
```
|
|
|
|
### Connection Timeout on Large Pushes
|
|
|
|
**Cause:** Timeout values too low
|
|
|
|
**Solution:** Add to Advanced tab:
|
|
```nginx
|
|
proxy_connect_timeout 300;
|
|
proxy_send_timeout 300;
|
|
proxy_read_timeout 300;
|
|
send_timeout 300;
|
|
```
|
|
|
|
### Docker Push Hangs
|
|
|
|
**Cause:** Request buffering enabled
|
|
|
|
**Solution:** Add to Advanced tab:
|
|
```nginx
|
|
proxy_request_buffering off;
|
|
```
|
|
|
|
## Docker Client Configuration
|
|
|
|
### No Additional Configuration Required
|
|
|
|
With HTTPS enabled, Docker will work without insecure registry configuration:
|
|
|
|
```bash
|
|
# Just works!
|
|
docker pull registry.directlx.dev/my-image:latest
|
|
docker push registry.directlx.dev/my-image:latest
|
|
```
|
|
|
|
### Legacy HTTP Configuration (NOT RECOMMENDED)
|
|
|
|
If you need HTTP-only access (not recommended):
|
|
|
|
Edit `/etc/docker/daemon.json`:
|
|
```json
|
|
{
|
|
"insecure-registries": ["registry.directlx.dev"]
|
|
}
|
|
```
|
|
|
|
Restart Docker:
|
|
```bash
|
|
sudo systemctl restart docker
|
|
```
|
|
|
|
## Testing the Complete Setup
|
|
|
|
### 1. Tag and Push Test Image
|
|
|
|
```bash
|
|
# Pull a small test image
|
|
docker pull alpine:latest
|
|
|
|
# Tag for your registry
|
|
docker tag alpine:latest registry.directlx.dev/test-alpine:latest
|
|
|
|
# Push to registry
|
|
docker push registry.directlx.dev/test-alpine:latest
|
|
```
|
|
|
|
### 2. Verify Upload
|
|
|
|
```bash
|
|
# Check repository exists
|
|
curl -s https://registry.directlx.dev/v2/_catalog | jq '.repositories[] | select(. == "test-alpine")'
|
|
|
|
# Check tags
|
|
curl -s https://registry.directlx.dev/v2/test-alpine/tags/list | jq '.'
|
|
```
|
|
|
|
### 3. Pull from Another Machine
|
|
|
|
```bash
|
|
# Remove local image
|
|
docker rmi registry.directlx.dev/test-alpine:latest
|
|
|
|
# Pull from registry
|
|
docker pull registry.directlx.dev/test-alpine:latest
|
|
|
|
# Verify
|
|
docker images | grep test-alpine
|
|
```
|
|
|
|
### 4. Cleanup
|
|
|
|
```bash
|
|
# Remove test image from local
|
|
docker rmi alpine:latest registry.directlx.dev/test-alpine:latest
|
|
```
|
|
|
|
## NPM Configuration Summary
|
|
|
|
| Setting | Value |
|
|
|---------|-------|
|
|
| Domain | registry.directlx.dev |
|
|
| Scheme | http |
|
|
| Forward Host | 192.168.200.200 |
|
|
| Forward Port | 5000 |
|
|
| SSL | Enabled (Let's Encrypt) |
|
|
| Force SSL | Yes |
|
|
| HTTP/2 | Yes |
|
|
| HSTS | Yes |
|
|
| Max Body Size | 5120M |
|
|
| Timeouts | 300s |
|
|
|
|
## Security Considerations
|
|
|
|
### ✅ Implemented
|
|
- HTTPS/TLS encryption (via Let's Encrypt)
|
|
- SSL certificate validation
|
|
- Block common exploits enabled
|
|
- Large body size limits (prevents DoS)
|
|
- Access logging disabled (prevents log spam)
|
|
|
|
### ⚠️ Not Implemented (Consider for Production)
|
|
- Authentication (Docker registry supports basic auth, tokens, OAuth)
|
|
- Access lists (NPM can restrict by IP/network)
|
|
- Rate limiting (prevent abuse)
|
|
- Image scanning (vulnerability detection)
|
|
- Content trust (signed images)
|
|
|
|
### Authentication Setup (Optional)
|
|
|
|
To add basic authentication to the registry:
|
|
|
|
1. Generate htpasswd file on docker server:
|
|
```bash
|
|
ansible docker -m shell -a "docker run --rm --entrypoint htpasswd httpd:alpine -Bbn username password > /opt/docker-registry/auth/htpasswd"
|
|
```
|
|
|
|
2. Update registry configuration to use auth:
|
|
```yaml
|
|
auth:
|
|
htpasswd:
|
|
realm: Registry Realm
|
|
path: /auth/htpasswd
|
|
```
|
|
|
|
3. Restart registry container
|
|
|
|
4. Docker login:
|
|
```bash
|
|
docker login registry.directlx.dev
|
|
```
|
|
|
|
## Related Documentation
|
|
|
|
- [Docker Registry DNS Configuration](DOCKER-REGISTRY-DNS.md)
|
|
- [Local DNS Configuration](LOCAL-DNS-CONFIGURATION.md)
|
|
- [SSL Offloading Fix](SSL-OFFLOADING-FIX.md)
|
|
|
|
## Maintenance
|
|
|
|
### Update SSL Certificate
|
|
|
|
Certificates auto-renew via Let's Encrypt. To force renewal:
|
|
|
|
1. NPM Admin → **SSL Certificates**
|
|
2. Find `registry.directlx.dev` certificate
|
|
3. Click **...** → **Renew Certificate**
|
|
|
|
### Monitor Logs
|
|
|
|
```bash
|
|
# NPM access logs (if enabled)
|
|
ansible npm -m shell -a "tail -f /data/logs/proxy-host-*.log"
|
|
|
|
# NPM error logs
|
|
ansible npm -m shell -a "tail -f /data/logs/error.log"
|
|
|
|
# Registry logs
|
|
ansible docker -m shell -a "docker logs -f registry" -b
|
|
```
|
|
|
|
### Backup Configuration
|
|
|
|
```bash
|
|
# Backup NPM database
|
|
ansible npm -m shell -a "sqlite3 /data/database.sqlite .dump > /tmp/npm-backup.sql"
|
|
|
|
# Download backup
|
|
ansible npm -m fetch -a "src=/tmp/npm-backup.sql dest=./backups/"
|
|
```
|
|
|
|
---
|
|
|
|
**Created**: 2026-02-14
|
|
**Last Updated**: 2026-02-14
|
|
**Author**: DirectLX Infrastructure Team
|