fix prod ddeployment

This commit is contained in:
root
2026-06-02 12:53:45 -04:00
parent b5a974ee14
commit e9dfbeb591
9 changed files with 224 additions and 104 deletions
+29 -18
View File
@@ -182,27 +182,27 @@ REGISTRY_USER=<deploy-user-or-token-name>
REGISTRY_PASSWORD=<personal-access-token-or-deploy-token>
```
The production compose file now reads `APP_IMAGE` and `APP_VERSION` for pull-based deploys. The GitLab deploy job injects those values automatically. If you want to pull manually on the server, you can also set `APP_IMAGE` in `.env.docker.production`.
The production compose file reads `APP_IMAGE` and `APP_VERSION` for pull-based deploys. The GitLab deploy job injects those values automatically and now syncs the deployment assets to the VPS before running the server-side deploy script. Production no longer depends on `git pull` during release.
The CI pipeline publishes and deploys from the GitLab default branch (`$CI_DEFAULT_BRANCH`). If you change your release branch, update the repository default branch in GitLab instead of hard-coding branch names in `.gitlab-ci.yml`.
If you use `docker:dind` on a self-hosted GitLab runner, the runner's Docker executor must be started with `privileged = true`. Without that, `docker:dind` often logs AppArmor or `/sys/kernel/security` mount errors and can become unreliable even when the job container still starts.
#### 5. Start Traefik
#### 5. Bootstrap the server once
Traefik must be running before the app stack so it can wire up routes at startup.
Traefik must be running before the app stack so it can wire up routes at startup. This bootstrap path is for the first server setup or for deliberate source-based rebuilds. Normal production releases should go through GitLab CI.
```bash
docker compose -f traefik.yaml up -d
bash scripts/docker-prod-up-traefik.sh
```
#### 6. Build and start the app stack
If you intentionally want to build from source on the server:
```bash
npm run docker:prod:up
```
Or use the new helper scripts if you want to start one production container at a time:
Or use the helper scripts if you want to start one production container at a time:
```bash
npm run docker:prod:start:traefik
@@ -220,11 +220,22 @@ npm run docker:prod:start:api && npm run docker:prod:start:frontends
```
Docker will:
1. Build the monorepo image
1. Build the monorepo image on the server
2. Start all app services (`api`, `marketplace`, `dashboard`, `admin`, `pgmanage`)
Traefik automatically picks up the containers and provisions TLS certificates. Services are live at their `https://` URLs within ~30 seconds.
#### 6. Standard release flow
Normal production releases should use GitLab CI:
1. CI builds and pushes a single versioned image.
2. CI copies the current deployment assets (`docker-compose.production.yml`, Traefik config, deploy scripts, pgManage override) to the VPS.
3. CI runs `bash scripts/docker-prod-deploy.sh` on the VPS with `APP_IMAGE` and `APP_VERSION` pinned to the commit being released.
4. The deploy script pulls the release image, starts Postgres and Redis, runs `npm run db:deploy` as a one-shot migration job, then starts the API and frontends and waits for their health checks.
This avoids the old drift where the VPS checkout changed independently through `git pull`, or where API startup silently mixed migrations with application boot.
#### 6a. Deploy Portainer
Portainer is deployed separately from the main app stack and reuses the shared `traefik-proxy` network managed by Traefik.
@@ -245,25 +256,25 @@ The production helper scripts and the GitLab deploy job now explicitly create th
#### Updating after a code change
Pull the latest code and rebuild only the changed service:
Push to the GitLab default branch and let the pipeline deploy the pinned image. That is the supported production release path.
If CI is unavailable and you need to redeploy the image already published to the registry from the server:
```bash
git pull
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml up --build -d --no-deps <service>
# e.g. to redeploy only the API:
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml up --build -d --no-deps api
APP_IMAGE=registry.example.com/rentaldrivego/car_management_system \
APP_VERSION=<gitlab-commit-sha> \
REGISTRY_HOST=registry.example.com \
REGISTRY_USER=<registry-user> \
REGISTRY_PASSWORD=<registry-password> \
bash scripts/docker-prod-deploy.sh
```
To rebuild everything:
```bash
npm run docker:prod:up
```
Only use `npm run docker:prod:up` when you intentionally want a source build on the server.
#### Apply database migrations without downtime
```bash
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml run --rm api npm run db:deploy
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml run --rm migrate
```
#### Create the first production admin