fix registry link

This commit is contained in:
root
2026-06-02 15:17:09 -04:00
parent da1841e6b9
commit a9305fa4a2
8 changed files with 134 additions and 9 deletions
+2
View File
@@ -5,6 +5,7 @@ PUBLIC_SITE_DOMAIN=example.com
PGMANAGE_DOMAIN=pgmanage.example.com
PORTAINER_DOMAIN=portainer.example.com
REGISTRY_DOMAIN=registry.rentaldrivego.ma
REGISTRY_UPSTREAM_URL=http://10.0.0.10:5000
# ── Optional prebuilt image source ────────────────────────────────────────────
# Used for pull-based deployments. CI injects APP_IMAGE and APP_VERSION
@@ -15,6 +16,7 @@ REGISTRY_HOST=registry.rentaldrivego.ma
REGISTRY_USER=rentaldrivego_registry
REGISTRY_PASSWORD=PMPS5k0D7rUeJOk0NkhI5bRtoGjkUqjK
REGISTRY_IMAGE=registry.rentaldrivego.ma/rentaldrivego/car_management_system
REGISTRY_HTTP_SECRET=PMPS5k0D7rUeJOk0NkhI5bRtoGjkUqjK
# ── Database ──────────────────────────────────────────────────────────────────
# Full connection URL (used when DATABASE_URL_FROM_POSTGRES=false)
+1
View File
@@ -5,6 +5,7 @@ PUBLIC_SITE_DOMAIN=example.com
PGMANAGE_DOMAIN=pgmanage.example.com
PORTAINER_DOMAIN=portainer.example.com
REGISTRY_DOMAIN=registry.example.com
REGISTRY_UPSTREAM_URL=http://10.0.0.10:5000
# Database
DATABASE_URL_FROM_POSTGRES=true
+3 -3
View File
@@ -147,10 +147,10 @@ deploy_to_vps:
echo "-- Syncing deployment assets --"
ssh $VPS_USER@$VPS_IP "
set -e
mkdir -p '$DEPLOY_ROOT/scripts' '$DEPLOY_ROOT/docker/pgmanage' '$DEPLOY_ROOT/docker/registry/auth'
mkdir -p '$DEPLOY_ROOT/scripts' '$DEPLOY_ROOT/docker/pgmanage' '$DEPLOY_ROOT/docker/registry/auth' '$DEPLOY_ROOT/dynamic'
"
scp docker-compose.production.yml docker-compose.portainer.production.yml docker-compose.registry.production.yml traefik.yaml $VPS_USER@$VPS_IP:$DEPLOY_ROOT/
scp scripts/docker-prod-common.sh scripts/docker-prod-deploy.sh scripts/docker-prod-up-registry.sh $VPS_USER@$VPS_IP:$DEPLOY_ROOT/scripts/
scp docker-compose.production.yml docker-compose.portainer.production.yml docker-compose.registry.production.yml docker-compose.registry.local.yml traefik.yaml $VPS_USER@$VPS_IP:$DEPLOY_ROOT/
scp scripts/docker-prod-common.sh scripts/docker-prod-deploy.sh scripts/docker-prod-up-registry.sh scripts/docker-registry-local-up.sh $VPS_USER@$VPS_IP:$DEPLOY_ROOT/scripts/
scp docker/pgmanage/override.py $VPS_USER@$VPS_IP:$DEPLOY_ROOT/docker/pgmanage/
echo "-- Running deploy script on VPS --"
+22
View File
@@ -0,0 +1,22 @@
name: rentaldrivego-registry-local
services:
registry:
image: registry:2
restart: unless-stopped
ports:
- 5000:5000
environment:
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
REGISTRY_HTTP_RELATIVEURLS: "true"
REGISTRY_HTTP_SECRET: ${REGISTRY_HTTP_SECRET:-change-me}
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_STORAGE_DELETE_ENABLED: "true"
volumes:
- registry_local_data:/var/lib/registry
- ./docker/registry/auth:/auth:ro
volumes:
registry_local_data:
+34 -6
View File
@@ -8,6 +8,7 @@ Three Docker environments are available:
- `docker-compose.pgmanage.yml` for a standalone pgManage container
- `docker-compose.portainer.production.yml` for a standalone production Portainer deployment behind Traefik
- `docker-compose.registry.production.yml` for a standalone production Docker registry behind Traefik
- `docker-compose.registry.local.yml` for a Docker registry running on a separate local server with port `5000` exposed directly
### Development
@@ -165,7 +166,8 @@ Production now derives `DATABASE_URL` inside the app container from `POSTGRES_HO
The example file uses `rentaldrivego.ma` for the marketplace and public site. The dashboard and admin panel are routed under that same host at `/dashboard` and `/admin`.
Set `PORTAINER_DOMAIN=portainer.rentaldrivego.ma` in `.env.docker.production` to expose Portainer through Traefik.
Set `PGMANAGE_DOMAIN=pgmanage.rentaldrivego.ma` to expose pgManage through Traefik, and set `PGMANAGE_LICENSE_KEY` if you are running the enterprise image.
Set `REGISTRY_DOMAIN=registry.rentaldrivego.ma` to expose the local Docker registry through Traefik.
Set `REGISTRY_DOMAIN=registry.rentaldrivego.ma` to expose the Docker registry through Traefik.
Set `REGISTRY_UPSTREAM_URL=http://<local-registry-server-ip>:5000` on the VPS when the registry itself runs on a different server and Traefik should reverse-proxy to it.
If you want to use a self-hosted registry on the same VPS, also set these values in `.env.docker.production`:
@@ -265,21 +267,47 @@ Equivalent raw Docker Compose command:
docker compose -p rentaldrivego-portainer-prod --env-file .env.docker.production -f docker-compose.portainer.production.yml up -d
```
#### 6b. Deploy the local registry
#### 6b. Deploy the registry on a separate local server
The registry is deployed separately from the main app stack and reuses the shared `traefik-proxy` network managed by Traefik.
For the split setup:
1. Run the registry on your local server with port `5000` exposed directly.
2. Set `REGISTRY_UPSTREAM_URL` on the VPS to `http://<local-registry-server-ip>:5000`.
3. Restart Traefik on the VPS so it renders the dynamic registry upstream file and serves TLS for `REGISTRY_DOMAIN`.
On the local registry server:
```bash
npm run docker:prod:start:registry
npm run docker:registry:local:start
```
Equivalent raw Docker Compose command:
```bash
docker compose -p rentaldrivego-registry-prod --env-file .env.docker.production -f docker-compose.registry.production.yml up -d
docker compose -p rentaldrivego-registry-local --env-file .env.docker.production -f docker-compose.registry.local.yml up -d
```
On first start, the script generates `docker/registry/auth/htpasswd` from `REGISTRY_USER` and `REGISTRY_PASSWORD` in `.env.docker.production`. After the registry is up, verify it with:
On first start, the script generates `docker/registry/auth/htpasswd` from `REGISTRY_USER` and `REGISTRY_PASSWORD` in `.env.docker.production`.
From the VPS, verify the upstream directly before involving Traefik:
```bash
curl -I http://<local-registry-server-ip>:5000/v2/
```
Expected response:
```text
HTTP/1.1 401 Unauthorized
```
Then on the VPS restart Traefik:
```bash
bash scripts/docker-prod-up-traefik.sh
```
After that, verify the public route and login flow:
```bash
docker login registry.rentaldrivego.ma
+1
View File
@@ -35,6 +35,7 @@
"docker:prod:start:pgmanage": "bash scripts/docker-prod-up-pgmanage.sh",
"docker:prod:start:portainer": "bash scripts/docker-prod-up-portainer.sh",
"docker:prod:start:registry": "bash scripts/docker-prod-up-registry.sh",
"docker:registry:local:start": "bash scripts/docker-registry-local-up.sh",
"docker:prod:deploy": "bash scripts/docker-prod-deploy.sh",
"docker:prod:up": "bash scripts/docker-prod-up-all.sh",
"docker:prod:down": "docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml down",
+39
View File
@@ -8,6 +8,8 @@ PORTAINER_COMPOSE_FILE="${ROOT_DIR}/docker-compose.portainer.production.yml"
REGISTRY_COMPOSE_FILE="${ROOT_DIR}/docker-compose.registry.production.yml"
TRAEFIK_COMPOSE_FILE="${ROOT_DIR}/traefik.yaml"
ENV_FILE="${ROOT_DIR}/.env.docker.production"
DYNAMIC_DIR="${ROOT_DIR}/dynamic"
REGISTRY_DYNAMIC_FILE="${DYNAMIC_DIR}/registry-upstream.yml"
PROJECT_NAME="${DOCKER_PROD_PROJECT_NAME:-rentaldrivego-prod}"
PORTAINER_PROJECT_NAME="${DOCKER_PORTAINER_PROJECT_NAME:-rentaldrivego-portainer-prod}"
REGISTRY_PROJECT_NAME="${DOCKER_REGISTRY_PROJECT_NAME:-rentaldrivego-registry-prod}"
@@ -39,6 +41,10 @@ ensure_api_uploads_volume() {
fi
}
ensure_dynamic_dir() {
mkdir -p "${DYNAMIC_DIR}"
}
prod_compose() {
docker compose -p "${PROJECT_NAME}" --env-file "${ENV_FILE}" -f "${PROD_COMPOSE_FILE}" "$@"
}
@@ -149,6 +155,38 @@ start_portainer() {
portainer_compose up -d
}
render_registry_proxy_config() {
ensure_dynamic_dir
if [[ -z "${REGISTRY_DOMAIN:-}" && -z "${REGISTRY_UPSTREAM_URL:-}" ]]; then
rm -f "${REGISTRY_DYNAMIC_FILE}"
return 0
fi
if [[ -z "${REGISTRY_DOMAIN:-}" || -z "${REGISTRY_UPSTREAM_URL:-}" ]]; then
echo "REGISTRY_DOMAIN and REGISTRY_UPSTREAM_URL must either both be set or both be unset." >&2
exit 1
fi
cat > "${REGISTRY_DYNAMIC_FILE}" <<EOF
http:
routers:
registry:
rule: Host(\`${REGISTRY_DOMAIN}\`)
entryPoints:
- websecure
tls:
certResolver: letsencrypt
service: registry-upstream
services:
registry-upstream:
loadBalancer:
servers:
- url: "${REGISTRY_UPSTREAM_URL}"
EOF
}
ensure_registry_auth_file() {
mkdir -p "${REGISTRY_AUTH_DIR}"
@@ -176,6 +214,7 @@ start_registry() {
start_traefik() {
ensure_env_file
ensure_traefik_network
render_registry_proxy_config
traefik_compose up -d
}
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="${ROOT_DIR}/.env.docker.production"
COMPOSE_FILE="${ROOT_DIR}/docker-compose.registry.local.yml"
AUTH_DIR="${ROOT_DIR}/docker/registry/auth"
AUTH_FILE="${AUTH_DIR}/htpasswd"
if [[ ! -f "${ENV_FILE}" ]]; then
echo "Missing ${ENV_FILE}" >&2
exit 1
fi
set -a
source "${ENV_FILE}"
set +a
mkdir -p "${AUTH_DIR}"
if [[ -n "${REGISTRY_USER:-}" && -n "${REGISTRY_PASSWORD:-}" ]]; then
docker run --rm --entrypoint htpasswd httpd:2-alpine -Bbn "${REGISTRY_USER}" "${REGISTRY_PASSWORD}" > "${AUTH_FILE}"
chmod 600 "${AUTH_FILE}"
elif [[ ! -f "${AUTH_FILE}" ]]; then
echo "Set REGISTRY_USER and REGISTRY_PASSWORD in ${ENV_FILE} or create ${AUTH_FILE} manually." >&2
exit 1
fi
docker compose -p rentaldrivego-registry-local --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" up -d
echo "Local registry is starting on port 5000."