dlx-ansible/docs/NPM-REGISTRY-SETUP.md

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