Update the CI guide to match the new config files for docker registry + caddy
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
2ec81cd9d1
commit
ed32d5aaaf
2 changed files with 173 additions and 124 deletions
|
@ -682,33 +682,50 @@ cd /opt/APP_NAME/registry
|
|||
# Update Caddyfile with your actual IP address
|
||||
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/Caddyfile
|
||||
|
||||
# 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_REGISTRY_NAME/APP_NAME-Registry/g" /opt/APP_NAME/registry/openssl.conf
|
||||
|
||||
# Create environment file for registry authentication
|
||||
# First, create a secure password hash
|
||||
# Save this password somewhere safe
|
||||
REGISTRY_PASSWORD="your-secure-registry-password"
|
||||
REGISTRY_PASSWORD_HASH=$(htpasswd -nbB registry-user "$REGISTRY_PASSWORD" | cut -d: -f2)
|
||||
|
||||
sudo tee .env << EOF
|
||||
REGISTRY_USERNAME=registry-user
|
||||
REGISTRY_PASSWORD_HASH=$REGISTRY_PASSWORD_HASH
|
||||
EOF
|
||||
# Update Caddyfile with the actual password hash
|
||||
sudo sed -i "s/DOCKER_REGISTRY_PASSWORD/$REGISTRY_PASSWORD_HASH/g" /opt/APP_NAME/registry/Caddyfile
|
||||
|
||||
# Set proper permissions
|
||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER .env
|
||||
sudo chmod 600 .env
|
||||
# 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/openssl.conf
|
||||
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/openssl.conf
|
||||
sudo chmod 644 /opt/APP_NAME/registry/docker-compose.registry.yml
|
||||
```
|
||||
|
||||
#### 5.3 Configure Docker Registry
|
||||
#### 5.3 Create FHS-Compliant Certificate Directory Structure
|
||||
|
||||
```bash
|
||||
# Update the baseurl with your actual IP address
|
||||
sudo sed -i "s/YOUR_CI_CD_IP/YOUR_ACTUAL_IP_ADDRESS/g" /opt/APP_NAME/registry/config.yml
|
||||
# Create FHS-compliant certificate directory structure
|
||||
sudo mkdir -p /etc/registry/certs/private
|
||||
sudo mkdir -p /etc/registry/certs/requests
|
||||
sudo mkdir -p /etc/registry/certs/ca
|
||||
sudo mkdir -p /var/lib/registry/data
|
||||
|
||||
# Note: For Option B (domain-based setup), you'll need to update this again later
|
||||
# with: sudo sed -i "s/YOUR_ACTUAL_IP_ADDRESS/YOUR_DOMAIN_NAME/g" /opt/APP_NAME/registry/config.yml
|
||||
# Set proper ownership for certificate directories
|
||||
sudo chown -R CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/certs
|
||||
sudo chown -R CI_SERVICE_USER:CI_SERVICE_USER /var/lib/registry/data
|
||||
|
||||
# Set proper permissions
|
||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/config.yml
|
||||
# Set proper permissions for certificate directories
|
||||
sudo chmod 755 /etc/registry/certs
|
||||
sudo chmod 700 /etc/registry/certs/private # Private keys - restricted access
|
||||
sudo chmod 755 /etc/registry/certs/requests # Certificate requests
|
||||
sudo chmod 755 /etc/registry/certs/ca # CA certificates
|
||||
sudo chmod 755 /var/lib/registry/data # Registry data
|
||||
|
||||
# Create registry data directory symlink for docker-compose
|
||||
sudo ln -sf /var/lib/registry/data /opt/APP_NAME/registry/registry
|
||||
```
|
||||
|
||||
#### 5.4 Generate TLS Certificate and Install in Docker Trust Store
|
||||
|
@ -722,47 +739,57 @@ sudo chown CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/config.yml
|
|||
**Perform all of these steps if you do NOT have a domain name:**
|
||||
|
||||
```bash
|
||||
# 1. Generate self-signed certificate with proper CA chain
|
||||
# 1. Generate self-signed certificate with proper CA chain using FHS-compliant structure
|
||||
cd /etc/registry/certs
|
||||
|
||||
# Generate CA private key
|
||||
sudo -u CI_SERVICE_USER openssl genrsa -out ca.key 4096
|
||||
# Generate CA private key in private subdirectory
|
||||
sudo -u CI_SERVICE_USER openssl genrsa -out private/ca.key 4096
|
||||
|
||||
# Generate CA certificate
|
||||
sudo -u CI_SERVICE_USER openssl req -new -x509 -key ca.key \
|
||||
-out ca.crt \
|
||||
# Generate CA certificate in ca subdirectory
|
||||
sudo -u CI_SERVICE_USER openssl req -new -x509 -key private/ca.key \
|
||||
-out ca/ca.crt \
|
||||
-days 365 \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=YOUR_DESIRED_CA"
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=APP_NAME-Registry-CA"
|
||||
|
||||
# Generate server private key
|
||||
sudo -u CI_SERVICE_USER openssl genrsa -out registry.key 4096
|
||||
# Generate server private key in private subdirectory
|
||||
sudo -u CI_SERVICE_USER openssl genrsa -out private/registry.key 4096
|
||||
|
||||
# Generate server certificate signing request
|
||||
sudo -u CI_SERVICE_USER openssl req -new -key registry.key \
|
||||
-out registry.csr \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=YOUR_ACTUAL_IP_ADDRESS"
|
||||
# Copy and use the project's OpenSSL configuration file
|
||||
sudo cp /opt/APP_NAME/registry/openssl.conf /etc/registry/certs/requests/
|
||||
sudo chown CI_SERVICE_USER:CI_SERVICE_USER /etc/registry/certs/requests/openssl.conf
|
||||
|
||||
# Copy and customize the OpenSSL configuration file
|
||||
sudo cp /opt/APP_NAME/registry/openssl.conf /etc/registry/certs/
|
||||
sudo sed -i "s/YOUR_ACTUAL_IP_ADDRESS/YOUR_ACTUAL_IP_ADDRESS/g" /etc/registry/certs/openssl.conf
|
||||
# Generate server certificate signing request in requests subdirectory
|
||||
sudo -u CI_SERVICE_USER openssl req -new -key private/registry.key \
|
||||
-out requests/registry.csr \
|
||||
-config requests/openssl.conf
|
||||
|
||||
# Sign server certificate with CA
|
||||
sudo -u CI_SERVICE_USER openssl x509 -req -in registry.csr \
|
||||
-CA ca.crt -CAkey ca.key -CAcreateserial \
|
||||
sudo -u CI_SERVICE_USER openssl x509 -req -in requests/registry.csr \
|
||||
-CA ca/ca.crt -CAkey private/ca.key -CAcreateserial \
|
||||
-out registry.crt \
|
||||
-days 365 \
|
||||
-extensions v3_req \
|
||||
-extfile /etc/registry/certs/openssl.conf
|
||||
-extensions req_ext \
|
||||
-extfile requests/openssl.conf
|
||||
|
||||
# Set proper permissions
|
||||
sudo chmod 600 ca.key registry.key
|
||||
sudo chmod 644 ca.crt registry.crt
|
||||
sudo -u CI_SERVICE_USER openssl x509 -in registry.crt -text -noout
|
||||
# Set proper FHS-compliant permissions
|
||||
sudo chmod 600 private/ca.key private/registry.key # Private keys - owner read/write only
|
||||
sudo chmod 644 ca/ca.crt registry.crt # Certificates - world readable
|
||||
sudo chmod 644 requests/registry.csr requests/openssl.conf # Requests - world readable
|
||||
|
||||
# Create certificate symlinks for Caddy (in certs subdirectory for docker-compose)
|
||||
sudo mkdir -p /opt/APP_NAME/registry/certs
|
||||
sudo ln -sf /etc/registry/certs/registry.crt /opt/APP_NAME/registry/certs/registry.crt
|
||||
sudo ln -sf /etc/registry/certs/private/registry.key /opt/APP_NAME/registry/certs/registry.key
|
||||
sudo chown -h CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/certs/registry.crt
|
||||
sudo chown -h CI_SERVICE_USER:CI_SERVICE_USER /opt/APP_NAME/registry/certs/registry.key
|
||||
|
||||
# Verify certificate creation
|
||||
sudo -u CI_SERVICE_USER openssl x509 -in registry.crt -text -noout | grep -E "(Subject:|DNS:|IP Address:)"
|
||||
|
||||
# 2. Install CA certificate into Docker trust store
|
||||
sudo mkdir -p /etc/docker/certs.d/registry
|
||||
sudo cp /etc/registry/certs/ca.crt /etc/docker/certs.d/registry/ca.crt
|
||||
sudo cp /etc/registry/certs/ca.crt /usr/local/share/ca-certificates/registry-ca.crt
|
||||
sudo mkdir -p /etc/docker/certs.d/YOUR_ACTUAL_IP_ADDRESS
|
||||
sudo cp /etc/registry/certs/ca/ca.crt /etc/docker/certs.d/YOUR_ACTUAL_IP_ADDRESS/ca.crt
|
||||
sudo cp /etc/registry/certs/ca/ca.crt /usr/local/share/ca-certificates/registry-ca.crt
|
||||
sudo update-ca-certificates
|
||||
sudo systemctl restart docker
|
||||
```
|
||||
|
@ -858,12 +885,16 @@ sudo su - CI_SERVICE_USER
|
|||
# Navigate to the application directory
|
||||
cd /opt/APP_NAME/registry
|
||||
|
||||
# Start the Docker Registry and Caddy services using the registry compose file
|
||||
# Start the Docker Registry and Caddy services using the project's registry compose file
|
||||
docker compose -f docker-compose.registry.yml up -d
|
||||
|
||||
# Verify services are running
|
||||
docker compose -f docker-compose.registry.yml ps
|
||||
|
||||
# Check service logs for any issues
|
||||
docker compose -f docker-compose.registry.yml logs caddy
|
||||
docker compose -f docker-compose.registry.yml logs registry
|
||||
|
||||
# Exit CI_SERVICE_USER shell
|
||||
exit
|
||||
```
|
||||
|
@ -900,27 +931,28 @@ sudo su - CI_SERVICE_USER
|
|||
# Navigate to the application directory
|
||||
cd /opt/APP_NAME
|
||||
|
||||
# Test Docker login and push using IP address with self-signed certificate
|
||||
echo "your-secure-registry-password" | docker login YOUR_ACTUAL_IP_ADDRESS -u registry-user --password-stdin
|
||||
# Test authenticated push using the project's registry configuration (port 4443)
|
||||
echo "your-secure-registry-password" | docker login YOUR_ACTUAL_IP_ADDRESS:4443 -u registry-user --password-stdin
|
||||
|
||||
# Create and push test image
|
||||
# Create and push test image to authenticated endpoint
|
||||
echo "FROM alpine:latest" > /tmp/test.Dockerfile
|
||||
docker build -f /tmp/test.Dockerfile -t YOUR_ACTUAL_IP_ADDRESS/APP_NAME/test:latest /tmp
|
||||
docker push YOUR_ACTUAL_IP_ADDRESS/APP_NAME/test:latest
|
||||
docker build -f /tmp/test.Dockerfile -t YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/test:latest /tmp
|
||||
docker push YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/test:latest
|
||||
|
||||
# Test public pull (no authentication)
|
||||
docker logout YOUR_ACTUAL_IP_ADDRESS
|
||||
# Test unauthenticated pull from standard HTTPS endpoint (port 443)
|
||||
docker logout YOUR_ACTUAL_IP_ADDRESS:4443
|
||||
docker pull YOUR_ACTUAL_IP_ADDRESS/APP_NAME/test:latest
|
||||
|
||||
# Test that unauthorized push is blocked
|
||||
# Test that unauthorized push to authenticated endpoint is blocked
|
||||
echo "FROM alpine:latest" > /tmp/unauthorized.Dockerfile
|
||||
docker build -f /tmp/unauthorized.Dockerfile -t YOUR_ACTUAL_IP_ADDRESS/APP_NAME/unauthorized:latest /tmp
|
||||
docker push YOUR_ACTUAL_IP_ADDRESS/APP_NAME/unauthorized:latest
|
||||
docker build -f /tmp/unauthorized.Dockerfile -t YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/unauthorized:latest /tmp
|
||||
docker push YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/unauthorized:latest
|
||||
# Expected: This should fail with authentication error
|
||||
|
||||
# Clean up
|
||||
docker rmi YOUR_ACTUAL_IP_ADDRESS/APP_NAME/test:latest
|
||||
docker rmi YOUR_ACTUAL_IP_ADDRESS/APP_NAME/unauthorized:latest
|
||||
docker rmi YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/test:latest 2>/dev/null || true
|
||||
docker rmi YOUR_ACTUAL_IP_ADDRESS/APP_NAME/test:latest 2>/dev/null || true
|
||||
docker rmi YOUR_ACTUAL_IP_ADDRESS:4443/APP_NAME/unauthorized:latest 2>/dev/null || true
|
||||
exit
|
||||
```
|
||||
|
||||
|
@ -965,65 +997,57 @@ sudo sed -i "s/YOUR_ACTUAL_IP_ADDRESS/YOUR_DOMAIN_NAME/g" /opt/APP_NAME/registry
|
|||
```
|
||||
|
||||
**Expected behavior**:
|
||||
- ✅ Push requires authentication with `registry-user` credentials
|
||||
- ✅ Pull works without authentication (public read access)
|
||||
- ✅ Unauthorized push is blocked
|
||||
- ✅ Registry accessible at `https://YOUR_ACTUAL_IP_ADDRESS` with self-signed certificate (Option A)
|
||||
- ✅ Push requires authentication with `registry-user` credentials on port 4443
|
||||
- ✅ Pull works without authentication (public read access) on port 443
|
||||
- ✅ Unauthorized push is blocked on authenticated endpoint
|
||||
- ✅ Registry accessible at `https://YOUR_ACTUAL_IP_ADDRESS:4443` for authenticated operations (Option A)
|
||||
- ✅ Registry accessible at `https://YOUR_ACTUAL_IP_ADDRESS` for unauthenticated pulls (Option A)
|
||||
- ✅ Registry accessible at `https://YOUR_DOMAIN_NAME` with valid Let's Encrypt certificate (Option B)
|
||||
- ✅ Certificate automatically renews every 60 days (Option B only)
|
||||
- ✅ Proper certificate chain management for both options
|
||||
- ✅ Proper FHS-compliant certificate structure with secure permissions
|
||||
|
||||
**Troubleshooting TLS Errors (Option A only):**
|
||||
|
||||
If you get a TLS error like `remote error: tls: internal error` when using self-signed certificates, you need to configure Docker to trust the certificate. Since Caddy automatically generates its own certificates, we need to configure Docker to accept the insecure registry:
|
||||
If you get a TLS error like `remote error: tls: internal error` when using self-signed certificates, verify the certificate installation and Docker configuration:
|
||||
|
||||
```bash
|
||||
# Verify the certificate was installed correctly
|
||||
ls -la /etc/docker/certs.d/registry/
|
||||
# Verify the certificate was installed correctly in Docker trust store
|
||||
ls -la /etc/docker/certs.d/YOUR_ACTUAL_IP_ADDRESS/
|
||||
ls -la /usr/local/share/ca-certificates/registry-ca.crt
|
||||
|
||||
# Configure Docker to accept the insecure registry (Caddy-generated certificates)
|
||||
sudo tee /etc/docker/daemon.json << EOF
|
||||
{
|
||||
"insecure-registries": ["YOUR_ACTUAL_IP_ADDRESS:443"]
|
||||
}
|
||||
EOF
|
||||
# Verify certificate chain is valid
|
||||
openssl verify -CAfile /etc/registry/certs/ca/ca.crt /etc/registry/certs/registry.crt
|
||||
|
||||
# Test the certificate connection
|
||||
openssl s_client -connect YOUR_ACTUAL_IP_ADDRESS:4443 -servername YOUR_ACTUAL_IP_ADDRESS < /dev/null
|
||||
|
||||
# Verify Caddy is using the correct certificates
|
||||
docker exec caddy ls -la /etc/certs/
|
||||
|
||||
# If issues persist, restart Docker daemon to reload certificates
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Test the certificate
|
||||
openssl s_client -connect YOUR_ACTUAL_IP_ADDRESS:443 -servername YOUR_ACTUAL_IP_ADDRESS < /dev/null
|
||||
# Wait for Docker Registry to restart, then test again
|
||||
sleep 10
|
||||
cd /opt/APP_NAME/registry
|
||||
docker compose -f docker-compose.registry.yml restart
|
||||
|
||||
# Test Docker login again
|
||||
echo "your-secure-registry-password" | docker login YOUR_ACTUAL_IP_ADDRESS -u registry-user --password-stdin
|
||||
|
||||
**Configure Caddy to Use Our Certificates**
|
||||
|
||||
Since we're creating our own certificate chain, we need to configure Caddy to use our certificates instead of generating its own:
|
||||
|
||||
```bash
|
||||
# Update Caddyfile to use our certificates
|
||||
sudo tee /opt/APP_NAME/registry/Caddyfile << EOF
|
||||
YOUR_ACTUAL_IP_ADDRESS {
|
||||
tls /etc/registry/certs/registry.crt /etc/registry/certs/registry.key
|
||||
|
||||
reverse_proxy registry:5000 {
|
||||
header_up Host {host}
|
||||
header_up X-Real-IP {remote}
|
||||
header_up X-Forwarded-For {remote}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Restart the registry services
|
||||
cd /opt/APP_NAME
|
||||
docker compose -f docker-compose.registry.yml down
|
||||
docker compose -f docker-compose.registry.yml up -d
|
||||
|
||||
# Test Docker login
|
||||
echo "your-secure-registry-password" | docker login YOUR_ACTUAL_IP_ADDRESS -u registry-user --password-stdin
|
||||
# Test Docker login to authenticated endpoint
|
||||
echo "your-secure-registry-password" | docker login YOUR_ACTUAL_IP_ADDRESS:4443 -u registry-user --password-stdin
|
||||
```
|
||||
|
||||
**Note**: This approach uses our own certificate chain, which Docker already trusts, eliminating the need to extract or trust Caddy's certificates.
|
||||
**Certificate Structure Summary:**
|
||||
|
||||
The project uses a two-port configuration:
|
||||
- **Port 443**: Unauthenticated pulls (public read access)
|
||||
- **Port 4443**: Authenticated pushes (registry-user credentials required)
|
||||
|
||||
**FHS-Compliant Certificate Locations:**
|
||||
- **Private Keys**: `/etc/registry/certs/private/` (mode 600)
|
||||
- **CA Certificates**: `/etc/registry/certs/ca/` (mode 644)
|
||||
- **Certificate Requests**: `/etc/registry/certs/requests/` (mode 644)
|
||||
- **Server Certificates**: `/etc/registry/certs/` (mode 644)
|
||||
- **Docker Trust Store**: `/etc/docker/certs.d/YOUR_ACTUAL_IP_ADDRESS/`
|
||||
|
||||
### Step 6: Install Forgejo Actions Runner
|
||||
|
||||
|
@ -1298,15 +1322,19 @@ docker exec ci-dind docker version
|
|||
# Navigate to the application directory
|
||||
cd /opt/APP_NAME
|
||||
|
||||
# Login to Docker Registry from within DinD
|
||||
echo "your-registry-password" | docker exec -i ci-dind docker login YOUR_CI_CD_IP -u registry-user --password-stdin
|
||||
# Login to Docker Registry from within DinD (using authenticated port 4443)
|
||||
echo "your-registry-password" | docker exec -i ci-dind docker login YOUR_CI_CD_IP:4443 -u registry-user --password-stdin
|
||||
|
||||
# Test Docker Registry connectivity from DinD
|
||||
docker exec ci-dind docker pull alpine:latest
|
||||
docker exec ci-dind docker tag alpine:latest YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
docker exec ci-dind docker push YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
docker exec ci-dind docker tag alpine:latest YOUR_CI_CD_IP:4443/APP_NAME/test:latest
|
||||
docker exec ci-dind docker push YOUR_CI_CD_IP:4443/APP_NAME/test:latest
|
||||
|
||||
# Clean up test image
|
||||
# Test unauthenticated pull from standard port 443
|
||||
docker exec ci-dind docker pull YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
|
||||
# Clean up test images
|
||||
docker exec ci-dind docker rmi YOUR_CI_CD_IP:4443/APP_NAME/test:latest
|
||||
docker exec ci-dind docker rmi YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
|
||||
#### 7.3 Set Up Workspace Directory
|
||||
|
@ -1344,19 +1372,24 @@ ls -la /tmp/ci-workspace
|
|||
The Docker Registry setup now follows the Filesystem Hierarchy Standard (FHS) for better organization and security:
|
||||
|
||||
**Application Files** (in `/opt/APP_NAME/registry/`):
|
||||
- `docker-compose.registry.yml` - Docker Compose configuration
|
||||
- `Caddyfile` - Caddy reverse proxy configuration
|
||||
- `config.yml` - Docker Registry configuration
|
||||
- `.env` - Environment variables for authentication
|
||||
- `docker-compose.registry.yml` - Docker Compose configuration from project repository
|
||||
- `Caddyfile` - Caddy reverse proxy configuration from project repository
|
||||
- `openssl.conf` - OpenSSL configuration for certificate generation from project repository
|
||||
- `certs/` - Symbolic links to FHS-compliant certificate locations
|
||||
|
||||
**System Files** (FHS-compliant locations):
|
||||
- `/var/lib/registry/` - Registry data storage
|
||||
- `/etc/registry/certs/` - SSL/TLS certificates
|
||||
- `/var/lib/registry/data/` - Registry data storage
|
||||
- `/etc/registry/certs/` - SSL/TLS certificate hierarchy:
|
||||
- `/etc/registry/certs/private/` - Private keys (mode 600)
|
||||
- `/etc/registry/certs/ca/` - CA certificates (mode 644)
|
||||
- `/etc/registry/certs/requests/` - Certificate requests and configs (mode 644)
|
||||
- `/etc/registry/certs/registry.crt` - Server certificate (mode 644)
|
||||
- `/var/log/registry/` - Registry and Caddy logs
|
||||
|
||||
**Benefits of FHS Compliance**:
|
||||
- **Data persistence**: Registry data stored in `/var/lib/registry/` survives container restarts
|
||||
- **Certificate security**: Certificates in `/etc/registry/certs/` with proper permissions
|
||||
- **Data persistence**: Registry data stored in `/var/lib/registry/data/` survives container restarts
|
||||
- **Certificate security**: Hierarchical certificate structure with proper permissions
|
||||
- **Separation of concerns**: Private keys isolated from public certificates
|
||||
- **Log management**: Logs in `/var/log/registry/` for centralized logging
|
||||
- **Configuration separation**: App configs in app directory, system data in system directories
|
||||
```
|
||||
|
@ -1416,12 +1449,16 @@ The CI/CD pipeline uses a three-stage approach with dedicated environments for e
|
|||
# Test DinD functionality
|
||||
docker exec ci-dind docker run --rm alpine:latest echo "DinD is working!"
|
||||
|
||||
# Test Docker Registry integration
|
||||
# Test Docker Registry integration (using authenticated port for push)
|
||||
docker exec ci-dind docker pull alpine:latest
|
||||
docker exec ci-dind docker tag alpine:latest YOUR_CI_CD_IP/APP_NAME/dind-test:latest
|
||||
docker exec ci-dind docker push YOUR_CI_CD_IP/APP_NAME/dind-test:latest
|
||||
docker exec ci-dind docker tag alpine:latest YOUR_CI_CD_IP:4443/APP_NAME/dind-test:latest
|
||||
docker exec ci-dind docker push YOUR_CI_CD_IP:4443/APP_NAME/dind-test:latest
|
||||
|
||||
# Test unauthenticated pull
|
||||
docker exec ci-dind docker pull YOUR_CI_CD_IP/APP_NAME/dind-test:latest
|
||||
|
||||
# Clean up test
|
||||
docker exec ci-dind docker rmi YOUR_CI_CD_IP:4443/APP_NAME/dind-test:latest
|
||||
docker exec ci-dind docker rmi YOUR_CI_CD_IP/APP_NAME/dind-test:latest
|
||||
```
|
||||
|
||||
|
@ -1806,10 +1843,10 @@ ls -la /opt/APP_NAME
|
|||
# Change to the PROD_SERVICE_USER
|
||||
sudo su - PROD_SERVICE_USER
|
||||
|
||||
# Test that Docker can pull images from the Docker Registry
|
||||
# Test that Docker can pull images from the Docker Registry (unauthenticated port 443)
|
||||
docker pull YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
|
||||
# If the pull succeeds, the Docker Registry is accessible
|
||||
# If the pull succeeds, the Docker Registry is accessible for production deployments
|
||||
|
||||
# Change back to PROD_DEPLOY_USER
|
||||
exit
|
||||
|
@ -1817,6 +1854,8 @@ exit
|
|||
|
||||
**Important**: Replace `YOUR_CI_CD_IP` with your actual CI/CD Linode IP address.
|
||||
|
||||
**Note**: Production deployments use unauthenticated pulls from port 443, while CI/CD operations use authenticated pushes to port 4443.
|
||||
|
||||
**What this does**:
|
||||
- **Tests Docker Registry access**: Verifies that Docker can successfully pull images from the Docker Registry
|
||||
- **No certificate configuration needed**: Caddy handles HTTPS automatically
|
||||
|
@ -2115,12 +2154,14 @@ docker compose --version
|
|||
#### 16.2 Test Docker Registry Access
|
||||
|
||||
```bash
|
||||
# Test pulling an image from the CI/CD Docker Registry
|
||||
# Test pulling an image from the CI/CD Docker Registry (unauthenticated port 443)
|
||||
docker pull YOUR_CI_CD_IP/APP_NAME/test:latest
|
||||
```
|
||||
|
||||
**Important**: Replace `YOUR_CI_CD_IP` with your actual CI/CD Linode IP address.
|
||||
|
||||
**Note**: Production uses unauthenticated pulls from the standard HTTPS port (443) for deployment operations.
|
||||
|
||||
**Note**: Application deployment testing will be done in Step 20 after the complete CI/CD pipeline is set up.
|
||||
|
||||
---
|
||||
|
@ -2139,7 +2180,9 @@ Go to your Forgejo repository and add these secrets in **Settings → Secrets an
|
|||
- `APP_NAME`: Your application name (e.g., `sharenet`)
|
||||
- `POSTGRES_PASSWORD`: A strong password for the PostgreSQL database
|
||||
- `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 environment file, default: `your-secure-registry-password`)
|
||||
- `REGISTRY_PASSWORD`: Docker Registry password for CI operations (the password you set in the Caddyfile, default: `your-secure-registry-password`)
|
||||
- `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`)
|
||||
|
||||
**Optional Secrets (for domain users):**
|
||||
- `DOMAIN`: Your domain name (e.g., `example.com`)
|
||||
|
@ -2174,15 +2217,19 @@ The pipeline should execute these steps in order:
|
|||
# On CI/CD Linode
|
||||
cd /opt/APP_NAME
|
||||
|
||||
# Check if new images were pushed (using correct registry port 443)
|
||||
# Check if new images were pushed (using unauthenticated port 443)
|
||||
curl -k https://localhost:443/v2/_catalog
|
||||
|
||||
# Check specific repository tags
|
||||
curl -k https://localhost:443/v2/APP_NAME/backend/tags/list
|
||||
curl -k https://localhost:443/v2/APP_NAME/frontend/tags/list
|
||||
|
||||
# Alternative: Check registry via Caddy
|
||||
# Open https://YOUR_CI_CD_IP in your browser
|
||||
# Alternative: Check registry via public endpoint
|
||||
curl -k https://YOUR_CI_CD_IP/v2/_catalog
|
||||
|
||||
# Check authenticated endpoint (should require authentication)
|
||||
curl -k https://YOUR_CI_CD_IP:4443/v2/_catalog
|
||||
# Expected: This should return authentication error without credentials
|
||||
```
|
||||
|
||||
#### 18.4 Verify Production Deployment
|
||||
|
|
|
@ -13,4 +13,6 @@ CN=YOUR_CI_CD_IP
|
|||
subjectAltName = @alt_names
|
||||
|
||||
[ alt_names ]
|
||||
IP.1 = YOUR_CI_CD_IP
|
||||
DNS.1 = localhost
|
||||
IP.1 = YOUR_CI_CD_IP
|
||||
IP.2 = 127.0.0.1
|
Loading…
Add table
Reference in a new issue