diff --git a/CI_CD_PIPELINE_SETUP_GUIDE.md b/CI_CD_PIPELINE_SETUP_GUIDE.md index b1aa76d..47fab67 100644 --- a/CI_CD_PIPELINE_SETUP_GUIDE.md +++ b/CI_CD_PIPELINE_SETUP_GUIDE.md @@ -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 diff --git a/registry/openssl.conf b/registry/openssl.conf index 04827e7..0b1225a 100644 --- a/registry/openssl.conf +++ b/registry/openssl.conf @@ -13,4 +13,6 @@ CN=YOUR_CI_CD_IP subjectAltName = @alt_names [ alt_names ] -IP.1 = YOUR_CI_CD_IP \ No newline at end of file +DNS.1 = localhost +IP.1 = YOUR_CI_CD_IP +IP.2 = 127.0.0.1 \ No newline at end of file