Updated faceai container
All checks were successful
Publish FaceAI Container / publish (push) Successful in 2m23s
All checks were successful
Publish FaceAI Container / publish (push) Successful in 2m23s
This commit is contained in:
parent
85d6dff580
commit
07db048310
3 changed files with 136 additions and 18 deletions
|
|
@ -84,7 +84,7 @@ The `processor` service is built from `docker/processor.Dockerfile`, which uses
|
||||||
|
|
||||||
### Persistent Logs
|
### Persistent Logs
|
||||||
|
|
||||||
The checked-in local Compose stack now redirects the relevant Node service logs into `faceai/logs` on the host.
|
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 up --build`, inspect:
|
||||||
|
|
||||||
|
|
@ -95,6 +95,8 @@ After `docker compose up --build`, inspect:
|
||||||
|
|
||||||
This keeps the useful processor diagnostics outside the Docker-managed runtime volume so they survive container rebuilds and can be inspected directly from the workspace.
|
This keeps the useful processor diagnostics outside the Docker-managed runtime volume so they survive container rebuilds and can be inspected directly from the workspace.
|
||||||
|
|
||||||
|
Because the service entrypoints now mirror output instead of redirecting it away, the same startup and runtime messages are also visible through `docker logs regalami-faceai`, `docker logs regalami-faceai-processor`, and Portainer's container log viewer.
|
||||||
|
|
||||||
The current bundled Linux `face_matcher` binary is a PyInstaller build that requires `GLIBC_2.38` or newer and the `libxcb.so.1` runtime library. The checked-in local processor image satisfies that requirement.
|
The current bundled Linux `face_matcher` binary is a PyInstaller build that requires `GLIBC_2.38` or newer and the `libxcb.so.1` runtime library. The checked-in local processor image satisfies that requirement.
|
||||||
|
|
||||||
### Run The Browser Test
|
### Run The Browser Test
|
||||||
|
|
@ -211,14 +213,20 @@ services:
|
||||||
image: forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
image: forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
||||||
container_name: regalami-faceai
|
container_name: regalami-faceai
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: sh -c "mkdir -p /data/logs && npm run start >> /data/logs/backend.log 2>&1"
|
command:
|
||||||
|
- node
|
||||||
|
- docker/run-with-log-file.mjs
|
||||||
|
- /data/logs/backend.log
|
||||||
|
- npm
|
||||||
|
- run
|
||||||
|
- start
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
PORT: 3001
|
PORT: 3001
|
||||||
FACEAI_FRONTEND_URL: https://ai.regalamiunsorriso.it
|
FACEAI_FRONTEND_URL: https://ai.regalamiunsorriso.it
|
||||||
FACEAI_PUBLIC_BASE_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_RETURN_URL: https://www.regalamiunsorriso.it/faceai_return.php
|
||||||
FACEAI_SHARED_SECRET: change-this-to-a-long-random-secret
|
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||||
FACEAI_SESSION_COOKIE: rus_faceai_session
|
FACEAI_SESSION_COOKIE: rus_faceai_session
|
||||||
FACEAI_REDIS_URL: redis://redis:6379
|
FACEAI_REDIS_URL: redis://redis:6379
|
||||||
FACEAI_QUEUE_NAME: faceai-searches
|
FACEAI_QUEUE_NAME: faceai-searches
|
||||||
|
|
@ -228,19 +236,32 @@ services:
|
||||||
FACEAI_PKL_ROOT: /data/pkl
|
FACEAI_PKL_ROOT: /data/pkl
|
||||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 0
|
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 0
|
||||||
volumes:
|
volumes:
|
||||||
- /var/docker/faceai/runtime:/data/runtime
|
- /mnt/storage/data/faceai/runtime:/data/runtime
|
||||||
- /var/docker/faceai/logs:/data/logs
|
- /mnt/storage/data/faceai/logs:/data/logs
|
||||||
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3001:3001"
|
- "127.0.0.1:3001:3001"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/health | grep -q '\"ok\":true'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 6
|
||||||
|
start_period: 20s
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
processor:
|
processor:
|
||||||
image: forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
image: forgejo.maddoscientisto.net/maddo/faceai-client:latest
|
||||||
container_name: regalami-faceai-processor
|
container_name: regalami-faceai-processor
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: sh -c "mkdir -p /data/logs && npm run start:processor >> /data/logs/processor.log 2>&1"
|
command:
|
||||||
|
- node
|
||||||
|
- docker/run-with-log-file.mjs
|
||||||
|
- /data/logs/processor.log
|
||||||
|
- npm
|
||||||
|
- run
|
||||||
|
- start:processor
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
FACEAI_REDIS_URL: redis://redis:6379
|
FACEAI_REDIS_URL: redis://redis:6379
|
||||||
|
|
@ -252,18 +273,24 @@ services:
|
||||||
FACEAI_WORKER_CONCURRENCY: 2
|
FACEAI_WORKER_CONCURRENCY: 2
|
||||||
FACEAI_WORKER_TIMEOUT_MS: 300000
|
FACEAI_WORKER_TIMEOUT_MS: 300000
|
||||||
volumes:
|
volumes:
|
||||||
- /var/docker/faceai/runtime:/data/runtime
|
- /mnt/storage/data/faceai/runtime:/data/runtime
|
||||||
- /var/docker/faceai/logs:/data/logs
|
- /mnt/storage/data/faceai/logs:/data/logs
|
||||||
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
- /mnt/nas12/nas2/RUS:/data/pkl:ro
|
||||||
- /var/docker/faceai/bin/Face_Recognition_Unix:/opt/face-recognition:ro
|
- /mnt/storage/data/faceai/bin/Face_Recognition_Unix:/opt/face-recognition:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
container_name: regalami-faceai-redis
|
container_name: regalami-faceai-redis
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: redis-server --appendonly no
|
command: redis-server --appendonly no
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 12
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
@ -392,7 +419,9 @@ In the provided Docker Compose stack, that wiring is already done with:
|
||||||
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
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 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.
|
||||||
|
|
||||||
The local PHP simulator also needs the legacy bridge feature flag enabled:
|
The local PHP simulator also needs the legacy bridge feature flag enabled:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,17 @@ services:
|
||||||
faceai:
|
faceai:
|
||||||
image: node:20-alpine
|
image: node:20-alpine
|
||||||
container_name: regalami-faceai
|
container_name: regalami-faceai
|
||||||
|
restart: unless-stopped
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
command: sh -c "mkdir -p /data/logs && npm run start --workspace @regalami/faceai-backend >> /data/logs/backend.log 2>&1"
|
command:
|
||||||
|
- node
|
||||||
|
- docker/run-with-log-file.mjs
|
||||||
|
- /data/logs/backend.log
|
||||||
|
- npm
|
||||||
|
- run
|
||||||
|
- start
|
||||||
|
- --workspace
|
||||||
|
- "@regalami/faceai-backend"
|
||||||
environment:
|
environment:
|
||||||
PORT: 3001
|
PORT: 3001
|
||||||
FACEAI_FRONTEND_URL: http://localhost:3001
|
FACEAI_FRONTEND_URL: http://localhost:3001
|
||||||
|
|
@ -12,7 +21,7 @@ services:
|
||||||
FACEAI_PKL_ROOT: /data/pkl
|
FACEAI_PKL_ROOT: /data/pkl
|
||||||
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 1
|
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 1
|
||||||
FACEAI_LOCAL_LEGACY_STATIC_ROOT: /legacy-www
|
FACEAI_LOCAL_LEGACY_STATIC_ROOT: /legacy-www
|
||||||
FACEAI_SHARED_SECRET: change-me
|
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||||
FACEAI_SESSION_COOKIE: rus_faceai_session
|
FACEAI_SESSION_COOKIE: rus_faceai_session
|
||||||
FACEAI_REDIS_URL: redis://redis:6379
|
FACEAI_REDIS_URL: redis://redis:6379
|
||||||
FACEAI_RUNTIME_ROOT: /data/runtime
|
FACEAI_RUNTIME_ROOT: /data/runtime
|
||||||
|
|
@ -26,8 +35,15 @@ services:
|
||||||
- faceai-runtime:/data/runtime
|
- faceai-runtime:/data/runtime
|
||||||
ports:
|
ports:
|
||||||
- "3001:3001"
|
- "3001:3001"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/health | grep -q '\"ok\":true'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 6
|
||||||
|
start_period: 20s
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
processor:
|
processor:
|
||||||
build:
|
build:
|
||||||
|
|
@ -35,8 +51,17 @@ services:
|
||||||
dockerfile: docker/processor.Dockerfile
|
dockerfile: docker/processor.Dockerfile
|
||||||
image: regalami-faceai-processor-local
|
image: regalami-faceai-processor-local
|
||||||
container_name: regalami-faceai-processor
|
container_name: regalami-faceai-processor
|
||||||
|
restart: unless-stopped
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
command: sh -c "mkdir -p /data/logs && npm run start --workspace @regalami/faceai-processor >> /data/logs/processor.log 2>&1"
|
command:
|
||||||
|
- node
|
||||||
|
- docker/run-with-log-file.mjs
|
||||||
|
- /data/logs/processor.log
|
||||||
|
- npm
|
||||||
|
- run
|
||||||
|
- start
|
||||||
|
- --workspace
|
||||||
|
- "@regalami/faceai-processor"
|
||||||
environment:
|
environment:
|
||||||
FACEAI_REDIS_URL: redis://redis:6379
|
FACEAI_REDIS_URL: redis://redis:6379
|
||||||
FACEAI_QUEUE_NAME: faceai-searches
|
FACEAI_QUEUE_NAME: faceai-searches
|
||||||
|
|
@ -52,27 +77,38 @@ services:
|
||||||
- ../test_pkl:/data/pkl:ro
|
- ../test_pkl:/data/pkl:ro
|
||||||
- faceai-runtime:/data/runtime
|
- faceai-runtime:/data/runtime
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
container_name: regalami-faceai-redis
|
container_name: regalami-faceai-redis
|
||||||
|
restart: unless-stopped
|
||||||
command: redis-server --appendonly no
|
command: redis-server --appendonly no
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 12
|
||||||
|
|
||||||
legacy-php:
|
legacy-php:
|
||||||
image: php:8.3-apache
|
image: php:8.3-apache
|
||||||
container_name: regalami-legacy-php
|
container_name: regalami-legacy-php
|
||||||
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
FACEAI_FEATURE_ENABLED: 1
|
FACEAI_FEATURE_ENABLED: 1
|
||||||
FACEAI_BACKEND_INTERNAL_URL: http://faceai:3001
|
FACEAI_BACKEND_INTERNAL_URL: http://faceai:3001
|
||||||
FACEAI_FRONTEND_URL: http://localhost:3001
|
FACEAI_FRONTEND_URL: http://localhost:3001
|
||||||
FACEAI_SHARED_SECRET: change-me
|
FACEAI_SHARED_SECRET: disagio-spaghetti-science-lol-boh
|
||||||
FACEAI_ALLOW_DEV_HANDOFF: 1
|
FACEAI_ALLOW_DEV_HANDOFF: 1
|
||||||
FACEAI_IDENTITY_COOKIE: rus_faceai_identity
|
FACEAI_IDENTITY_COOKIE: rus_faceai_identity
|
||||||
volumes:
|
volumes:
|
||||||
- ../www:/var/www/html
|
- ../www:/var/www/html
|
||||||
ports:
|
ports:
|
||||||
- "8080:80"
|
- "8080:80"
|
||||||
|
depends_on:
|
||||||
|
faceai:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
faceai-runtime:
|
faceai-runtime:
|
||||||
|
|
|
||||||
53
faceai/docker/run-with-log-file.mjs
Normal file
53
faceai/docker/run-with-log-file.mjs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import fsp from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
import process from 'node:process';
|
||||||
|
import { spawn } from 'node:child_process';
|
||||||
|
|
||||||
|
const [, , logPath, ...commandArgs] = process.argv;
|
||||||
|
|
||||||
|
if (!logPath || commandArgs.length === 0) {
|
||||||
|
process.stderr.write('Usage: node docker/run-with-log-file.mjs <log-path> <command> [args...]\n');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await fsp.mkdir(path.dirname(logPath), { recursive: true });
|
||||||
|
|
||||||
|
const logStream = fs.createWriteStream(logPath, { flags: 'a' });
|
||||||
|
const child = spawn(commandArgs[0], commandArgs.slice(1), {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
env: process.env,
|
||||||
|
stdio: ['inherit', 'pipe', 'pipe']
|
||||||
|
});
|
||||||
|
|
||||||
|
function writeChunk(target, chunk) {
|
||||||
|
target.write(chunk);
|
||||||
|
logStream.write(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
child.stdout.on('data', (chunk) => {
|
||||||
|
writeChunk(process.stdout, chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stderr.on('data', (chunk) => {
|
||||||
|
writeChunk(process.stderr, chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', (error) => {
|
||||||
|
const message = `${error.stack || error.message}\n`;
|
||||||
|
writeChunk(process.stderr, message);
|
||||||
|
logStream.end(() => {
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('close', (code, signal) => {
|
||||||
|
logStream.end(() => {
|
||||||
|
if (signal) {
|
||||||
|
process.kill(process.pid, signal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exit(code ?? 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue