feat: Add environment configuration files and update Docker Compose setup for development and production
This commit is contained in:
parent
23f811e465
commit
539a848e95
8 changed files with 292 additions and 193 deletions
35
faceai/.env.development
Normal file
35
faceai/.env.development
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
NODE_ENV=development
|
||||
FACEAI_CLIENT_DEV_IMAGE=node:20-alpine
|
||||
FACEAI_PROCESSOR_DEV_IMAGE=regalami-faceai-processor-local
|
||||
FACEAI_PORT=3001
|
||||
FACEAI_PUBLISHED_PORT=3001
|
||||
FACEAI_LEGACY_PHP_PORT=8080
|
||||
FACEAI_FRONTEND_URL=http://localhost:3001
|
||||
FACEAI_PUBLIC_BASE_URL=http://localhost:3001
|
||||
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL=http://localhost:8080/index.jsp
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC=1
|
||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT=/legacy-www
|
||||
FACEAI_SHARED_SECRET=disagio-spaghetti-science-lol-boh
|
||||
FACEAI_SESSION_COOKIE=rus_faceai_session
|
||||
FACEAI_REDIS_URL=redis://redis:6379
|
||||
FACEAI_QUEUE_NAME=faceai-searches
|
||||
FACEAI_RUNTIME_ROOT=/data/runtime
|
||||
FACEAI_UPLOAD_ROOT=/data/runtime/uploads
|
||||
FACEAI_LOG_ROOT=/data/logs
|
||||
FACEAI_PKL_ROOT=/data/pkl
|
||||
FACEAI_MATCHER_BINARY=/app/bin/face_matcher
|
||||
FACEAI_WORKER_CONCURRENCY=2
|
||||
FACEAI_WORKER_TIMEOUT_MS=300000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS=20000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS=5000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS=20
|
||||
FACEAI_FEATURE_ENABLED=1
|
||||
FACEAI_BACKEND_INTERNAL_URL=http://faceai:3001
|
||||
FACEAI_ALLOW_DEV_HANDOFF=1
|
||||
FACEAI_IDENTITY_COOKIE=rus_faceai_identity
|
||||
LIVE_SITE_BASE_URL=https://www.regalamiunsorriso.it
|
||||
LIVE_SITE_LOGIN_URL=https://www.regalamiunsorriso.it/login_clienti-it.html
|
||||
LIVE_SITE_RACE_URL=https://www.regalamiunsorriso.it/42%20HALF%20MARATHON%20FIRENZE_gara-1018545---96-1.html
|
||||
LIVE_SITE_USERNAME=piero
|
||||
LIVE_SITE_PASSWORD=AA25061958Pg!
|
||||
|
|
@ -1,22 +1,46 @@
|
|||
PORT=3001
|
||||
FACEAI_FRONTEND_URL=http://localhost:5173
|
||||
FACEAI_PUBLIC_BASE_URL=http://localhost:3001
|
||||
FACEAI_LEGACY_RETURN_URL=http://localhost:3001/dev/legacy/return
|
||||
FACEAI_LEGACY_HOME_URL=http://localhost:8080/index.jsp
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC=1
|
||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT=k:\various\regalamiunsorriso\www
|
||||
# Compose usage:
|
||||
# docker compose -f docker-compose.yml --env-file .env.production up -d
|
||||
# docker compose --env-file .env.development up --build
|
||||
|
||||
NODE_ENV=production
|
||||
FACEAI_CLIENT_IMAGE=forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
||||
FACEAI_PROCESSOR_IMAGE=forgejo.maddoscientisto.net/maddo/faceai-processor:latest
|
||||
FACEAI_REDIS_IMAGE=redis:7-alpine
|
||||
FACEAI_CLIENT_CONTAINER_NAME=regalami-faceai
|
||||
FACEAI_PROCESSOR_CONTAINER_NAME=regalami-faceai-processor
|
||||
FACEAI_REDIS_CONTAINER_NAME=regalami-faceai-redis
|
||||
FACEAI_CLIENT_DEV_IMAGE=node:20-alpine
|
||||
FACEAI_PROCESSOR_DEV_IMAGE=regalami-faceai-processor-local
|
||||
FACEAI_PORT=3001
|
||||
FACEAI_PUBLISHED_PORT=3001
|
||||
FACEAI_LEGACY_PHP_PORT=8080
|
||||
FACEAI_FRONTEND_URL=https://ai.regalamiunsorriso.it
|
||||
FACEAI_PUBLIC_BASE_URL=https://ai.regalamiunsorriso.it
|
||||
FACEAI_LEGACY_RETURN_URL=https://www.regalamiunsorriso.it/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL=https://www.regalamiunsorriso.it
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC=0
|
||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT=/legacy-www
|
||||
FACEAI_SHARED_SECRET=change-me
|
||||
FACEAI_SESSION_COOKIE=rus_faceai_session
|
||||
FACEAI_IDENTITY_COOKIE=rus_faceai_identity
|
||||
FACEAI_REDIS_URL=redis://redis:6379
|
||||
FACEAI_QUEUE_NAME=faceai-searches
|
||||
FACEAI_RUNTIME_ROOT=/data/runtime
|
||||
FACEAI_UPLOAD_ROOT=/data/runtime/uploads
|
||||
FACEAI_LOG_ROOT=/data/logs
|
||||
FACEAI_PKL_ROOT=/data/pkl
|
||||
FACEAI_RUNTIME_BIND=/mnt/storage/data/faceai/runtime
|
||||
FACEAI_LOG_BIND=/mnt/storage/data/faceai/logs
|
||||
FACEAI_PKL_BIND=/mnt/nas12/nas2/RUS
|
||||
FACEAI_MATCHER_BINARY=/app/bin/face_matcher
|
||||
FACEAI_WORKER_CONCURRENCY=8
|
||||
FACEAI_WORKER_TIMEOUT_MS=300000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS=20000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS=5000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS=20
|
||||
FACEAI_FEATURE_ENABLED=1
|
||||
FACEAI_BACKEND_INTERNAL_URL=http://faceai:3001
|
||||
FACEAI_ALLOW_DEV_HANDOFF=1
|
||||
LIVE_SITE_BASE_URL=https://www.regalamiunsorriso.it
|
||||
LIVE_SITE_LOGIN_URL=https://www.regalamiunsorriso.it/login_clienti-it.html
|
||||
LIVE_SITE_RACE_URL=https://www.regalamiunsorriso.it/42%20HALF%20MARATHON%20FIRENZE_gara-1018545---96-1.html
|
||||
|
|
|
|||
28
faceai/.env.production
Normal file
28
faceai/.env.production
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
NODE_ENV=production
|
||||
FACEAI_CLIENT_IMAGE=forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
||||
FACEAI_PROCESSOR_IMAGE=forgejo.maddoscientisto.net/maddo/faceai-processor:latest
|
||||
FACEAI_REDIS_IMAGE=redis:7-alpine
|
||||
FACEAI_CLIENT_CONTAINER_NAME=regalami-faceai
|
||||
FACEAI_PROCESSOR_CONTAINER_NAME=regalami-faceai-processor
|
||||
FACEAI_REDIS_CONTAINER_NAME=regalami-faceai-redis
|
||||
FACEAI_PORT=3001
|
||||
FACEAI_PUBLISHED_PORT=3001
|
||||
FACEAI_FRONTEND_URL=https://ai.regalamiunsorriso.it
|
||||
FACEAI_PUBLIC_BASE_URL=https://ai.regalamiunsorriso.it
|
||||
FACEAI_LEGACY_RETURN_URL=https://www.regalamiunsorriso.it/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL=https://www.regalamiunsorriso.it
|
||||
FACEAI_SHARED_SECRET=disagio-spaghetti-science-lol-boh
|
||||
FACEAI_SESSION_COOKIE=rus_faceai_session
|
||||
FACEAI_REDIS_URL=redis://redis:6379
|
||||
FACEAI_QUEUE_NAME=faceai-searches
|
||||
FACEAI_RUNTIME_ROOT=/data/runtime
|
||||
FACEAI_UPLOAD_ROOT=/data/runtime/uploads
|
||||
FACEAI_LOG_ROOT=/data/logs
|
||||
FACEAI_PKL_ROOT=/data/pkl
|
||||
FACEAI_RUNTIME_BIND=/mnt/storage/data/faceai/runtime
|
||||
FACEAI_LOG_BIND=/mnt/storage/data/faceai/logs
|
||||
FACEAI_PKL_BIND=/mnt/nas12/nas2/RUS
|
||||
FACEAI_MATCHER_BINARY=/app/bin/face_matcher
|
||||
FACEAI_WORKER_CONCURRENCY=8
|
||||
FACEAI_WORKER_TIMEOUT_MS=300000
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC=0
|
||||
161
faceai/README.md
161
faceai/README.md
|
|
@ -63,10 +63,17 @@ From this folder:
|
|||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
docker compose up --build
|
||||
docker compose --env-file .env.development up --build
|
||||
```
|
||||
|
||||
The checked-in `docker-compose.yml` starts:
|
||||
The checked-in Compose setup now uses:
|
||||
|
||||
- `docker-compose.yml` as the production-ready base stack
|
||||
- `docker-compose.override.yml` as the local development overlay
|
||||
- `.env.production` for production-oriented values
|
||||
- `.env.development` for the local simulator workflow
|
||||
|
||||
The local development stack started by the command above combines the base file and the override and starts:
|
||||
|
||||
- FaceAI public site on `http://localhost:3001`
|
||||
- processor runner on the internal Compose network
|
||||
|
|
@ -85,7 +92,7 @@ The `processor` service is built from `docker/processor.Dockerfile` using the re
|
|||
|
||||
The checked-in local Compose stack now mirrors the relevant Node service logs to both Docker stdout/stderr and `faceai/logs` on the host.
|
||||
|
||||
After `docker compose up --build`, inspect:
|
||||
After `docker compose --env-file .env.development up --build`, inspect:
|
||||
|
||||
- `faceai/logs/backend.log` for backend startup and API-side failures
|
||||
- `faceai/logs/processor.log` for worker startup, queue processing, and uncaught processor errors
|
||||
|
|
@ -131,7 +138,7 @@ npm run build
|
|||
If you want to stop and remove the local containers afterward, run:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose --env-file .env.development down
|
||||
```
|
||||
|
||||
### Automated End-To-End Test
|
||||
|
|
@ -149,7 +156,7 @@ npm run test:e2e
|
|||
The suite will:
|
||||
|
||||
- build the frontend bundle
|
||||
- start `docker compose up --build -d`
|
||||
- start `docker compose --env-file .env.development up --build -d`
|
||||
- open `http://localhost:8080/faceai_simulator.php?raceId=202&lang=it`
|
||||
- click the `Face ID` launch button injected by `www/_js/rus-ecom-240621.js`
|
||||
- upload `test_pkl/test_images/DSC_1960.JPG`
|
||||
|
|
@ -237,7 +244,7 @@ One workable loop is:
|
|||
|
||||
```bash
|
||||
npm install
|
||||
docker compose up redis -d
|
||||
docker compose --env-file .env.development up redis -d
|
||||
npm run dev
|
||||
```
|
||||
|
||||
|
|
@ -245,7 +252,9 @@ Then start the processor in a second shell, either with its own local environmen
|
|||
|
||||
## Docker Compose Deployment For The Public Site And Matcher Runner
|
||||
|
||||
The checked-in `docker-compose.yml` is for local integration testing because it also includes the PHP simulator and local bind mounts. For hosted deployment, keep the same three-service application topology but remove `legacy-php` and replace the local mounts with the real production paths on the host.
|
||||
The checked-in `docker-compose.yml` is now the production-ready base stack for hosted deployment. The checked-in `docker-compose.override.yml` is the development overlay that restores the local PHP simulator, workspace bind mounts, and development-oriented commands.
|
||||
|
||||
Because Docker Compose auto-loads `docker-compose.override.yml` when it is present in the same directory, production-style runs from this workspace must explicitly select only the base file.
|
||||
|
||||
The public FaceAI site and the matcher runner can both use the same application image. The difference is only the process command:
|
||||
|
||||
|
|
@ -254,102 +263,25 @@ The public FaceAI site and the matcher runner can both use the same application
|
|||
|
||||
If that shared image also embeds or mounts the current Linux `face_matcher` build, make sure the base OS provides `GLIBC_2.38` or newer and includes `libxcb1`. A Debian Trixie-based image with that package installed satisfies the requirement; a Bookworm-based image does not.
|
||||
|
||||
### Production Compose Example
|
||||
### Production Compose Commands
|
||||
|
||||
This example assumes:
|
||||
This setup assumes:
|
||||
|
||||
- FaceAI runtime files, logs, and matcher binaries live under `/var/docker/faceai` on the host
|
||||
- the NAS export is already mounted on the host at `/mnt/nas12` via `/etc/fstab`, for example `192.168.10.247:/public /mnt/nas12 nfs rw,noatime 0 0`
|
||||
- the race dataset root is available on the host at `/mnt/nas12/nas2/RUS`
|
||||
|
||||
Replace the registry path and secrets with the real deployment values.
|
||||
Set the real production values in `.env.production`, then run:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
faceai:
|
||||
image: forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
||||
container_name: regalami-faceai
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- /data/logs/backend.log
|
||||
- npm
|
||||
- run
|
||||
- start
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3001
|
||||
FACEAI_FRONTEND_URL: https://ai.regalamiunsorriso.it
|
||||
FACEAI_PUBLIC_BASE_URL: https://ai.regalamiunsorriso.it
|
||||
FACEAI_LEGACY_RETURN_URL: https://www.regalamiunsorriso.it/faceai_return.php
|
||||
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||
FACEAI_SESSION_COOKIE: rus_faceai_session
|
||||
FACEAI_REDIS_URL: redis://redis:6379
|
||||
FACEAI_QUEUE_NAME: faceai-searches
|
||||
FACEAI_RUNTIME_ROOT: /data/runtime
|
||||
FACEAI_UPLOAD_ROOT: /data/runtime/uploads
|
||||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS: 20000
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 0
|
||||
volumes:
|
||||
- /mnt/storage/data/faceai/runtime:/data/runtime
|
||||
- /mnt/storage/data/faceai/logs:/data/logs
|
||||
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
||||
ports:
|
||||
- "3001:3001"
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health').then(async (response) => { const payload = await response.json().catch(() => ({})); if (!response.ok || payload.ok !== true) { console.error(JSON.stringify(payload)); process.exit(1); } }).catch((error) => { console.error(error.stack || error.message); process.exit(1); })"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 6
|
||||
start_period: 20s
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
```bash
|
||||
docker compose -f docker-compose.yml --env-file .env.production up -d
|
||||
```
|
||||
|
||||
processor:
|
||||
image: forgejo.maddoscientisto.net/maddo/faceai-processor:latest
|
||||
container_name: regalami-faceai-processor
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- /data/logs/processor.log
|
||||
- npm
|
||||
- run
|
||||
- start:processor
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
FACEAI_REDIS_URL: redis://redis:6379
|
||||
FACEAI_QUEUE_NAME: faceai-searches
|
||||
FACEAI_RUNTIME_ROOT: /data/runtime
|
||||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_MATCHER_BINARY: /app/bin/face_matcher
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS: 5000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS: 20
|
||||
FACEAI_WORKER_CONCURRENCY: 2
|
||||
FACEAI_WORKER_TIMEOUT_MS: 300000
|
||||
volumes:
|
||||
- /mnt/storage/data/faceai/runtime:/data/runtime
|
||||
- /mnt/storage/data/faceai/logs:/data/logs
|
||||
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
To pull newer images before a rollout:
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: regalami-faceai-redis
|
||||
restart: unless-stopped
|
||||
command: redis-server --appendonly no
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 12
|
||||
```bash
|
||||
docker compose -f docker-compose.yml --env-file .env.production pull
|
||||
docker compose -f docker-compose.yml --env-file .env.production up -d
|
||||
```
|
||||
|
||||
This pattern assumes a reverse proxy on the host publishes `https://ai.regalamiunsorriso.it` and forwards to `127.0.0.1:3001`. The processor is internal-only and does not expose any public port.
|
||||
|
|
@ -451,16 +383,37 @@ This scaffold can now be deployed with the public site, processor, and Redis, bu
|
|||
|
||||
So the Compose deployment is appropriate for hosted integration and controlled production-like rollout, but not yet for the final hardened architecture described in the integration plan.
|
||||
|
||||
## Environment
|
||||
## Environment Files
|
||||
|
||||
Defaults are already set for local development, but these can be overridden:
|
||||
The repository now keeps separate env files for the two compose workflows:
|
||||
|
||||
- `.env.production`: production-oriented values used with the base compose file only
|
||||
- `.env.development`: local simulator values used with the base file plus the override
|
||||
|
||||
To start the local development stack:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.development up --build
|
||||
```
|
||||
|
||||
To start the production-style stack from this workspace without loading the development override:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml --env-file .env.production up -d
|
||||
```
|
||||
|
||||
If you need a template that lists all supported variables, use `.env.example`.
|
||||
|
||||
The most important development defaults are:
|
||||
|
||||
```text
|
||||
PORT=3001
|
||||
FACEAI_FRONTEND_URL=http://localhost:5173
|
||||
NODE_ENV=development
|
||||
FACEAI_PORT=3001
|
||||
FACEAI_FRONTEND_URL=http://localhost:3001
|
||||
FACEAI_PUBLIC_BASE_URL=http://localhost:3001
|
||||
FACEAI_LEGACY_RETURN_URL=http://localhost:3001/dev/legacy/return
|
||||
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL=http://localhost:8080/index.jsp
|
||||
FACEAI_FEATURE_ENABLED=1
|
||||
FACEAI_SHARED_SECRET=change-me
|
||||
FACEAI_SESSION_COOKIE=rus_faceai_session
|
||||
FACEAI_REDIS_URL=redis://redis:6379
|
||||
|
|
@ -469,19 +422,19 @@ FACEAI_RUNTIME_ROOT=/data/runtime
|
|||
FACEAI_UPLOAD_ROOT=/data/runtime/uploads
|
||||
FACEAI_LOG_ROOT=/data/logs
|
||||
FACEAI_PKL_ROOT=/data/pkl
|
||||
FACEAI_MATCHER_BINARY=/opt/face-recognition/face_matcher
|
||||
FACEAI_MATCHER_BINARY=/app/bin/face_matcher
|
||||
```
|
||||
|
||||
If you want FaceAI to return through the new PHP bridge prepared under `www`, point `FACEAI_LEGACY_RETURN_URL` to that endpoint instead, for example `http://localhost/faceai_return.php` or the equivalent URL in your local PHP setup.
|
||||
|
||||
In the provided Docker Compose stack, that wiring is already done with:
|
||||
In the development override, that wiring is already done with:
|
||||
|
||||
```text
|
||||
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL=http://localhost:8080/index.jsp
|
||||
```
|
||||
|
||||
The log wiring is also already done in the checked-in Compose file with a host bind mount for `./logs:/data/logs`, so both the backend and the processor write persistent diagnostics into the workspace while also remaining visible through Docker and Portainer container logs.
|
||||
The development override also keeps the log wiring with `./logs:/data/logs`, so both the backend and the processor write persistent diagnostics into the workspace while also remaining visible through Docker and Portainer container logs.
|
||||
|
||||
The Compose contract now also includes an HTTP healthcheck on the public FaceAI service and a Redis readiness check. That makes `docker compose ps` meaningful during rollout: `faceai` only becomes healthy after `GET /health` returns `{"ok":true}`, and both the public site and the processor wait for Redis readiness before their own startup sequence begins.
|
||||
|
||||
|
|
@ -491,12 +444,12 @@ The local PHP simulator also needs the legacy bridge feature flag enabled:
|
|||
FACEAI_FEATURE_ENABLED=1
|
||||
```
|
||||
|
||||
The checked-in `docker-compose.yml` now sets that on the `legacy-php` service so the simulator can launch the FaceAI handoff flow locally.
|
||||
The checked-in `docker-compose.override.yml` sets that on the `legacy-php` service so the simulator can launch the FaceAI handoff flow locally.
|
||||
|
||||
## Notes
|
||||
|
||||
- Search orchestration now uses Redis and a dedicated processor worker.
|
||||
- The checked-in Compose file is meant for local integration testing, not as-is production use.
|
||||
- The checked-in base Compose file is production-oriented, while the checked-in override is development-only.
|
||||
- The local legacy simulator is intentionally backend-driven so the handoff can be tested without compiling the existing Java application.
|
||||
- `www/faceai_simulator.php` exists only for local testing. It does not replace the actual JSP race page.
|
||||
- The final legacy integration still needs a real signed identity source and a real return-filter implementation on the old site.
|
||||
|
|
|
|||
91
faceai/docker-compose.override.yml
Normal file
91
faceai/docker-compose.override.yml
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
services:
|
||||
faceai:
|
||||
image: ${FACEAI_CLIENT_DEV_IMAGE:-node:20-alpine}
|
||||
working_dir: /app
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- ${FACEAI_BACKEND_LOG_FILE:-/data/logs/backend.log}
|
||||
- npm
|
||||
- run
|
||||
- start
|
||||
- --workspace
|
||||
- "@regalami/faceai-backend"
|
||||
environment:
|
||||
NODE_ENV: ${NODE_ENV:-development}
|
||||
PORT: ${FACEAI_PORT:-3001}
|
||||
FACEAI_FRONTEND_URL: ${FACEAI_FRONTEND_URL:-http://localhost:3001}
|
||||
FACEAI_PUBLIC_BASE_URL: ${FACEAI_PUBLIC_BASE_URL:-http://localhost:3001}
|
||||
FACEAI_LEGACY_RETURN_URL: ${FACEAI_LEGACY_RETURN_URL:-http://localhost:8080/faceai_return.php}
|
||||
FACEAI_LEGACY_HOME_URL: ${FACEAI_LEGACY_HOME_URL:-http://localhost:8080/index.jsp}
|
||||
FACEAI_SHARED_SECRET: ${FACEAI_SHARED_SECRET:-change-me}
|
||||
FACEAI_SESSION_COOKIE: ${FACEAI_SESSION_COOKIE:-rus_faceai_session}
|
||||
FACEAI_REDIS_URL: ${FACEAI_REDIS_URL:-redis://redis:6379}
|
||||
FACEAI_QUEUE_NAME: ${FACEAI_QUEUE_NAME:-faceai-searches}
|
||||
FACEAI_RUNTIME_ROOT: ${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
FACEAI_UPLOAD_ROOT: ${FACEAI_UPLOAD_ROOT:-/data/runtime/uploads}
|
||||
FACEAI_LOG_ROOT: ${FACEAI_LOG_ROOT:-/data/logs}
|
||||
FACEAI_PKL_ROOT: ${FACEAI_PKL_ROOT:-/data/pkl}
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: ${FACEAI_ENABLE_LOCAL_LEGACY_STATIC:-1}
|
||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT: ${FACEAI_LOCAL_LEGACY_STATIC_ROOT:-/legacy-www}
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS: ${FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS:-20000}
|
||||
volumes:
|
||||
- .:/app
|
||||
- ./logs:${FACEAI_LOG_ROOT:-/data/logs}
|
||||
- ../www:${FACEAI_LOCAL_LEGACY_STATIC_ROOT:-/legacy-www}:ro
|
||||
- ../test_pkl:${FACEAI_PKL_ROOT:-/data/pkl}:ro
|
||||
- faceai-runtime:${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
|
||||
processor:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: faceai/docker/processor.Dockerfile
|
||||
image: ${FACEAI_PROCESSOR_DEV_IMAGE:-regalami-faceai-processor-local}
|
||||
working_dir: /app
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- ${FACEAI_PROCESSOR_LOG_FILE:-/data/logs/processor.log}
|
||||
- npm
|
||||
- run
|
||||
- start
|
||||
- --workspace
|
||||
- "@regalami/faceai-processor"
|
||||
environment:
|
||||
NODE_ENV: ${NODE_ENV:-development}
|
||||
FACEAI_REDIS_URL: ${FACEAI_REDIS_URL:-redis://redis:6379}
|
||||
FACEAI_QUEUE_NAME: ${FACEAI_QUEUE_NAME:-faceai-searches}
|
||||
FACEAI_RUNTIME_ROOT: ${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
FACEAI_LOG_ROOT: ${FACEAI_LOG_ROOT:-/data/logs}
|
||||
FACEAI_PKL_ROOT: ${FACEAI_PKL_ROOT:-/data/pkl}
|
||||
FACEAI_MATCHER_BINARY: ${FACEAI_MATCHER_BINARY:-/app/bin/face_matcher}
|
||||
FACEAI_WORKER_CONCURRENCY: ${FACEAI_WORKER_CONCURRENCY:-2}
|
||||
FACEAI_WORKER_TIMEOUT_MS: ${FACEAI_WORKER_TIMEOUT_MS:-300000}
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS: ${FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS:-5000}
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS: ${FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS:-20}
|
||||
volumes:
|
||||
- ./logs:${FACEAI_LOG_ROOT:-/data/logs}
|
||||
- ../test_pkl:${FACEAI_PKL_ROOT:-/data/pkl}:ro
|
||||
- faceai-runtime:${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
|
||||
legacy-php:
|
||||
image: ${FACEAI_LEGACY_PHP_IMAGE:-php:8.3-apache}
|
||||
container_name: ${FACEAI_LEGACY_PHP_CONTAINER_NAME:-regalami-legacy-php}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
FACEAI_FEATURE_ENABLED: ${FACEAI_FEATURE_ENABLED:-1}
|
||||
FACEAI_BACKEND_INTERNAL_URL: ${FACEAI_BACKEND_INTERNAL_URL:-http://faceai:3001}
|
||||
FACEAI_FRONTEND_URL: ${FACEAI_FRONTEND_URL:-http://localhost:3001}
|
||||
FACEAI_SHARED_SECRET: ${FACEAI_SHARED_SECRET:-change-me}
|
||||
FACEAI_ALLOW_DEV_HANDOFF: ${FACEAI_ALLOW_DEV_HANDOFF:-1}
|
||||
FACEAI_IDENTITY_COOKIE: ${FACEAI_IDENTITY_COOKIE:-rus_faceai_identity}
|
||||
volumes:
|
||||
- ../www:/var/www/html
|
||||
ports:
|
||||
- "${FACEAI_LEGACY_PHP_PORT:-8080}:80"
|
||||
depends_on:
|
||||
faceai:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
faceai-runtime:
|
||||
|
|
@ -1,44 +1,39 @@
|
|||
services:
|
||||
faceai:
|
||||
image: node:20-alpine
|
||||
container_name: regalami-faceai
|
||||
image: ${FACEAI_CLIENT_IMAGE:-forgejo.maddoscientisto.net/maddo/faceai-client:latest}
|
||||
container_name: ${FACEAI_CLIENT_CONTAINER_NAME:-regalami-faceai}
|
||||
restart: unless-stopped
|
||||
working_dir: /app
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- /data/logs/backend.log
|
||||
- ${FACEAI_BACKEND_LOG_FILE:-/data/logs/backend.log}
|
||||
- npm
|
||||
- run
|
||||
- start
|
||||
- --workspace
|
||||
- "@regalami/faceai-backend"
|
||||
environment:
|
||||
PORT: 3001
|
||||
FACEAI_FRONTEND_URL: http://localhost:3001
|
||||
FACEAI_PUBLIC_BASE_URL: http://localhost:3001
|
||||
FACEAI_LEGACY_RETURN_URL: http://localhost:8080/faceai_return.php
|
||||
FACEAI_LEGACY_HOME_URL: http://localhost:8080/index.jsp
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 1
|
||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT: /legacy-www
|
||||
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||
FACEAI_SESSION_COOKIE: rus_faceai_session
|
||||
FACEAI_REDIS_URL: redis://redis:6379
|
||||
FACEAI_RUNTIME_ROOT: /data/runtime
|
||||
FACEAI_UPLOAD_ROOT: /data/runtime/uploads
|
||||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS: 20000
|
||||
NODE_ENV: ${NODE_ENV:-production}
|
||||
PORT: ${FACEAI_PORT:-3001}
|
||||
FACEAI_FRONTEND_URL: ${FACEAI_FRONTEND_URL:-https://ai.regalamiunsorriso.it}
|
||||
FACEAI_PUBLIC_BASE_URL: ${FACEAI_PUBLIC_BASE_URL:-https://ai.regalamiunsorriso.it}
|
||||
FACEAI_LEGACY_RETURN_URL: ${FACEAI_LEGACY_RETURN_URL:-https://www.regalamiunsorriso.it/faceai_return.php}
|
||||
FACEAI_LEGACY_HOME_URL: ${FACEAI_LEGACY_HOME_URL:-https://www.regalamiunsorriso.it}
|
||||
FACEAI_SHARED_SECRET: ${FACEAI_SHARED_SECRET:-change-me}
|
||||
FACEAI_SESSION_COOKIE: ${FACEAI_SESSION_COOKIE:-rus_faceai_session}
|
||||
FACEAI_REDIS_URL: ${FACEAI_REDIS_URL:-redis://redis:6379}
|
||||
FACEAI_QUEUE_NAME: ${FACEAI_QUEUE_NAME:-faceai-searches}
|
||||
FACEAI_RUNTIME_ROOT: ${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
FACEAI_UPLOAD_ROOT: ${FACEAI_UPLOAD_ROOT:-/data/runtime/uploads}
|
||||
FACEAI_LOG_ROOT: ${FACEAI_LOG_ROOT:-/data/logs}
|
||||
FACEAI_PKL_ROOT: ${FACEAI_PKL_ROOT:-/data/pkl}
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: ${FACEAI_ENABLE_LOCAL_LEGACY_STATIC:-0}
|
||||
volumes:
|
||||
- .:/app
|
||||
- ./logs:/data/logs
|
||||
- ../www:/legacy-www:ro
|
||||
- ../test_pkl:/data/pkl:ro
|
||||
- faceai-runtime:/data/runtime
|
||||
- ${FACEAI_RUNTIME_BIND:-/mnt/storage/data/faceai/runtime}:${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
- ${FACEAI_LOG_BIND:-/mnt/storage/data/faceai/logs}:${FACEAI_LOG_ROOT:-/data/logs}
|
||||
- ${FACEAI_PKL_BIND:-/mnt/nas12/nas2/RUS}:${FACEAI_PKL_ROOT:-/data/pkl}:ro
|
||||
ports:
|
||||
- "3001:3001"
|
||||
- "${FACEAI_PUBLISHED_PORT:-3001}:${FACEAI_PORT:-3001}"
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health').then(async (response) => { const payload = await response.json().catch(() => ({})); if (!response.ok || payload.ok !== true) { console.error(JSON.stringify(payload)); process.exit(1); } }).catch((error) => { console.error(error.stack || error.message); process.exit(1); })"]
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:' + (process.env.PORT || '3001') + '/health').then(async (response) => { const payload = await response.json().catch(() => ({})); if (!response.ok || payload.ok !== true) { console.error(JSON.stringify(payload)); process.exit(1); } }).catch((error) => { console.error(error.stack || error.message); process.exit(1); })"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 6
|
||||
|
|
@ -48,69 +43,41 @@ services:
|
|||
condition: service_healthy
|
||||
|
||||
processor:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: faceai/docker/processor.Dockerfile
|
||||
image: regalami-faceai-processor-local
|
||||
container_name: regalami-faceai-processor
|
||||
image: ${FACEAI_PROCESSOR_IMAGE:-forgejo.maddoscientisto.net/maddo/faceai-processor:latest}
|
||||
container_name: ${FACEAI_PROCESSOR_CONTAINER_NAME:-regalami-faceai-processor}
|
||||
restart: unless-stopped
|
||||
working_dir: /app
|
||||
command:
|
||||
- node
|
||||
- docker/run-with-log-file.mjs
|
||||
- /data/logs/processor.log
|
||||
- ${FACEAI_PROCESSOR_LOG_FILE:-/data/logs/processor.log}
|
||||
- npm
|
||||
- run
|
||||
- start
|
||||
- --workspace
|
||||
- "@regalami/faceai-processor"
|
||||
- start:processor
|
||||
environment:
|
||||
FACEAI_REDIS_URL: redis://redis:6379
|
||||
FACEAI_QUEUE_NAME: faceai-searches
|
||||
FACEAI_RUNTIME_ROOT: /data/runtime
|
||||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_WORKER_CONCURRENCY: 2
|
||||
FACEAI_MATCHER_BINARY: /app/bin/face_matcher
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS: 5000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS: 20
|
||||
NODE_ENV: ${NODE_ENV:-production}
|
||||
FACEAI_REDIS_URL: ${FACEAI_REDIS_URL:-redis://redis:6379}
|
||||
FACEAI_QUEUE_NAME: ${FACEAI_QUEUE_NAME:-faceai-searches}
|
||||
FACEAI_RUNTIME_ROOT: ${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
FACEAI_LOG_ROOT: ${FACEAI_LOG_ROOT:-/data/logs}
|
||||
FACEAI_PKL_ROOT: ${FACEAI_PKL_ROOT:-/data/pkl}
|
||||
FACEAI_MATCHER_BINARY: ${FACEAI_MATCHER_BINARY:-/app/bin/face_matcher}
|
||||
FACEAI_WORKER_CONCURRENCY: ${FACEAI_WORKER_CONCURRENCY:-8}
|
||||
FACEAI_WORKER_TIMEOUT_MS: ${FACEAI_WORKER_TIMEOUT_MS:-300000}
|
||||
volumes:
|
||||
- ./logs:/data/logs
|
||||
- ../test_pkl:/data/pkl:ro
|
||||
- faceai-runtime:/data/runtime
|
||||
- ${FACEAI_RUNTIME_BIND:-/mnt/storage/data/faceai/runtime}:${FACEAI_RUNTIME_ROOT:-/data/runtime}
|
||||
- ${FACEAI_LOG_BIND:-/mnt/storage/data/faceai/logs}:${FACEAI_LOG_ROOT:-/data/logs}
|
||||
- ${FACEAI_PKL_BIND:-/mnt/nas12/nas2/RUS}:${FACEAI_PKL_ROOT:-/data/pkl}:ro
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: regalami-faceai-redis
|
||||
image: ${FACEAI_REDIS_IMAGE:-redis:7-alpine}
|
||||
container_name: ${FACEAI_REDIS_CONTAINER_NAME:-regalami-faceai-redis}
|
||||
restart: unless-stopped
|
||||
command: redis-server --appendonly no
|
||||
command: ${FACEAI_REDIS_COMMAND:-redis-server --appendonly no}
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 12
|
||||
|
||||
legacy-php:
|
||||
image: php:8.3-apache
|
||||
container_name: regalami-legacy-php
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
FACEAI_FEATURE_ENABLED: 1
|
||||
FACEAI_BACKEND_INTERNAL_URL: http://faceai:3001
|
||||
FACEAI_FRONTEND_URL: http://localhost:3001
|
||||
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||
FACEAI_ALLOW_DEV_HANDOFF: 1
|
||||
FACEAI_IDENTITY_COOKIE: rus_faceai_identity
|
||||
volumes:
|
||||
- ../www:/var/www/html
|
||||
ports:
|
||||
- "8080:80"
|
||||
depends_on:
|
||||
faceai:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
faceai-runtime:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
"dev:backend": "npm run dev --workspace @regalami/faceai-backend",
|
||||
"dev:frontend": "npm run dev --workspace @regalami/faceai-frontend",
|
||||
"dev:processor": "npm run dev --workspace @regalami/faceai-processor",
|
||||
"compose:prod:up": "docker compose -f docker-compose.yml --env-file .env.production up -d",
|
||||
"compose:prod:down": "docker compose -f docker-compose.yml --env-file .env.production down",
|
||||
"compose:dev:up": "docker compose --env-file .env.development up --build",
|
||||
"compose:dev:down": "docker compose --env-file .env.development down",
|
||||
"build": "npm run build --workspace @regalami/faceai-frontend && npm run build --workspace @regalami/faceai-backend",
|
||||
"start": "npm run start --workspace @regalami/faceai-backend",
|
||||
"start:processor": "npm run start --workspace @regalami/faceai-processor",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ services:
|
|||
FACEAI_UPLOAD_ROOT: /data/runtime/uploads
|
||||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS: 20000
|
||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 0
|
||||
volumes:
|
||||
- /mnt/storage/data/faceai/runtime:/data/runtime
|
||||
|
|
@ -34,7 +33,7 @@ services:
|
|||
ports:
|
||||
- "3001:3001"
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health').then(async (response) => { const payload = await response.json().catch(() => ({})); if (!response.ok || payload.ok !== true) { console.error(JSON.stringify(payload)); process.exit(1); } }).catch((error) => { console.error(error.stack || error.message); process.exit(1); })"]
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/health | grep -q '\"ok\":true'"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 6
|
||||
|
|
@ -62,8 +61,6 @@ services:
|
|||
FACEAI_LOG_ROOT: /data/logs
|
||||
FACEAI_PKL_ROOT: /data/pkl
|
||||
FACEAI_MATCHER_BINARY: /app/bin/face_matcher
|
||||
FACEAI_PROCESSOR_HEARTBEAT_INTERVAL_MS: 5000
|
||||
FACEAI_PROCESSOR_HEARTBEAT_TTL_SECONDS: 20
|
||||
FACEAI_WORKER_CONCURRENCY: 8
|
||||
FACEAI_WORKER_TIMEOUT_MS: 300000
|
||||
volumes:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue