Files
carmanagement/production
root 7c1bd2d0c0
Build & Deploy / Build & Push Docker Image (push) Successful in 2m52s
Test / Type Check (all packages) (push) Successful in 50s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 49s
Test / Homepage Unit Tests (push) Successful in 42s
Test / Storefront Unit Tests (push) Successful in 39s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 41s
Test / API Integration Tests (push) Successful in 1m1s
Support insecure VPN registry pulls
2026-07-02 12:06:01 -04:00
..
2026-07-01 01:37:37 -04:00
2026-07-01 01:37:37 -04:00
2026-07-01 01:37:37 -04:00
2026-07-02 12:06:01 -04:00
2026-07-01 01:37:37 -04:00

RentalDriveGo Production Bundle

This folder contains the files needed to run a production deployment from prebuilt Docker images.

It is intended for a VPS/deploy directory such as /opt/rentaldrivego or ~/prodfolder. Do not run docker compose up --build from this folder; building from source requires the full repository.

Files

  • docker-compose.production.yml - production app stack.
  • traefik.yaml - Traefik reverse proxy stack.
  • .env.docker.production.example - sanitized environment template.
  • scripts/ - production deploy, startup, backup, and restore helpers.
  • docker/pgmanage/override.py - PgManage runtime override.
  • dynamic/ - generated Traefik dynamic config location.

First-Time Setup

cd /opt/rentaldrivego
chmod +x scripts/*.sh

This bundle includes .env.docker.production for the current rentaldrivego.ma deployment. Review it before starting services:

nano .env.docker.production

At minimum, verify or rotate:

  • POSTGRES_PASSWORD
  • REDIS_PASSWORD
  • JWT_SECRET
  • IMAGE_TAG
  • APP_IMAGE
  • MAIL_PASSWORD
  • PGMANAGE_DEFAULT_PASSWORD

If Docker needs to log in before pulling the app image, also set:

  • REGISTRY_USER
  • REGISTRY_TOKEN

For the current VPN-reachable image registry, use direct pulls from the VPS. The registry is 10.0.0.4, and the VPS WireGuard address is 10.0.0.1.

APP_IMAGE=10.0.0.4/melabidi/carmanagement
REGISTRY_HOST=10.0.0.4
REGISTRY_USER=melabidi
REGISTRY_TOKEN=<registry-token>
REGISTRY_INSECURE=true
IMAGE_ARCHIVE_DIR=
IMAGE_ARCHIVE_REQUIRED=false

Because Docker image names cannot include http://, the VPS Docker daemon must mark the registry as insecure before direct HTTP pulls. Add this entry to /etc/docker/daemon.json, merging it with any existing settings:

{
  "insecure-registries": ["10.0.0.4"]
}

Then restart Docker:

sudo systemctl restart docker

VPN Container Image Handoff

This fallback is only needed if the VPS cannot reach 10.0.0.4 directly. If the registry is only reachable inside a VPN container, use the shared archive folder:

IMAGE_ARCHIVE_DIR=/opt/docker-image-transfer
IMAGE_ARCHIVE_REQUIRED=true
APP_IMAGE=10.0.0.4/melabidi/carmanagement
IMAGE_TAG=latest
REGISTRY_USER=melabidi

From the VPS, use the VPN container network to copy the image into the transfer folder:

VPN_CONTAINER="6c5dca44e1c2" ./fetch-image-through-vpn.sh

Or fetch the archive and deploy in one command:

VPN_CONTAINER="6c5dca44e1c2" ./deploy-production.sh --fetch-through-vpn

When IMAGE_ARCHIVE_REQUIRED=true, ./deploy-production.sh will also fetch a missing archive automatically if VPN_CONTAINER is set:

VPN_CONTAINER="6c5dca44e1c2" ./deploy-production.sh

If VPN_CONTAINER is not set, the deploy script tries to auto-detect one running container with a common VPN name or image such as vpn, gluetun, wireguard, openvpn, tailscale, or wg-easy.

Equivalent manual command:

sudo mkdir -p /opt/docker-image-transfer
sudo chmod 700 /opt/docker-image-transfer

IMAGE_TAG="latest"
REGISTRY_USER="melabidi"
VPN_CONTAINER="6c5dca44e1c2"

read -rsp "Registry token: " REGISTRY_TOKEN
echo

docker run --rm \
  --network "container:${VPN_CONTAINER}" \
  -v /opt/docker-image-transfer:/transfer \
  quay.io/skopeo/stable:latest \
  copy \
  --override-os linux \
  --override-arch amd64 \
  --src-tls-verify=false \
  --src-creds "${REGISTRY_USER}:${REGISTRY_TOKEN}" \
  "docker://10.0.0.4/melabidi/carmanagement:${IMAGE_TAG}" \
  "docker-archive:/transfer/carmanagement-${IMAGE_TAG}.tar:10.0.0.4/melabidi/carmanagement:${IMAGE_TAG}"

Set the same IMAGE_TAG in .env.docker.production, then run the deployment. The deploy script will run docker load -i /opt/docker-image-transfer/carmanagement-${IMAGE_TAG}.tar before starting services. Because IMAGE_ARCHIVE_REQUIRED=true, the VPS will not try to pull from 10.0.0.4 directly.

If the VPS can reach the registry directly and you want to bypass archive loading, run:

./deploy-production.sh --image-tag latest --pull-registry

Deploy A Prebuilt Release

cd /opt/rentaldrivego
chmod +x deploy-production.sh scripts/*.sh
./deploy-production.sh

The deploy script loads the shared-folder image archive, starts Traefik and shared services, runs migrations, then starts the app services.

Manual Compose Flow

Use this only when you want to run compose directly:

cd /opt/rentaldrivego
docker load -i /opt/docker-image-transfer/carmanagement-latest.tar
APP_ENV_FILE=.env.docker.production docker compose --env-file .env.docker.production -f docker-compose.production.yml up -d postgres redis
APP_ENV_FILE=.env.docker.production docker compose --env-file .env.docker.production -f docker-compose.production.yml run --rm migrate
APP_ENV_FILE=.env.docker.production docker compose --env-file .env.docker.production -f docker-compose.production.yml up -d api homepage storefront dashboard admin

Source Builds

If you need to build on the VPS, copy the full repository instead of only this folder. Dockerfile.production requires:

  • package.json
  • package-lock.json
  • turbo.json
  • tsconfig.base.json
  • apps/
  • packages/
  • config/
  • docker/entrypoint.production.sh