# 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

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

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

```bash
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`.

```env
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:

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

Then restart Docker:

```bash
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:

```env
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:

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

Or fetch the archive and deploy in one command:

```bash
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:

```bash
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:

```bash
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:

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

## Deploy A Prebuilt Release

```bash
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:

```bash
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 carplace 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`
