Skip to content
Rulemapping

Automation Platform Documentation

Maintenance

Terminal window
docker compose ps # status including health checks
docker compose logs -f aimiddleware # follow middleware output
docker compose restart ktdocker # restart one service
docker compose down # stop everything; data is kept
docker compose up -d # start again / apply a change

Changing rw/ktbs.cl requires a restart of the application:

Terminal window
docker compose restart ktdocker

One-off commands against the instance:

Terminal window
docker compose --profile tools run --rm cms /finish-installation
docker compose --profile tools run --rm -it cms \
/reset-administrator user@example.com

The application writes its log files inside the container to /rw/var/log, visible on the host under rw/var/log/. It rotates them once per day into rw/var/log.bak/, so two generations are kept.

Terminal window
# application logs on the host
sudo ls -l rw/var/log/
# container output
docker compose logs --tail 100 ktdocker

The container output is normally almost empty, but it is where startup failures show up — a failed database connection, for instance, never reaches rw/var/log/ because the application does not get that far.

The application speaks plain HTTP on port 8080. TLS termination and public exposure are the reverse proxy’s job (nginx, HAProxy, Caddy).

Three requirements:

  • The proxy must be reachable under the host name configured as :proxy-host-name in rw/ktbs.cl. A mismatch produces broken redirects.
  • The proxy must send X-Forwarded-Proto: https. The application marks session cookies as Secure only when that header says https and :proxy-protocol-scheme is "https". Without the header the cookies go out unprotected.
  • It should also send X-Forwarded-Host with the public host name. If it does not, the application falls back to :proxy-host-name from rw/ktbs.cl, so both have to agree.

Two things carry state that cannot be recreated:

  1. the database
  2. rwshared/ — the file blobs of the disk pool

Both belong in the same backup, from the same point in time. Restoring only one of them gives you an instance whose records point at documents that are not there, or the other way round.

rw/ is largely derived and does not have to be backed up: the configuration comes from rap.config.sh, the license from the installation directory, and the links and directories are recreated by the container on every start. The exception is rw/var/, where queued tasks and import/export working directories live — include it if you rely on those features.

Terminal window
# 1. Set the new image tag
$EDITOR docker-compose.yml
# 2. Pull and recreate
docker compose pull
docker compose up -d

up -d is what applies the change: Compose replaces containers whose configuration differs from the file, so the new tag takes effect. docker compose restart would not — it restarts the existing container with the image it already has.

The license file is read at startup, so a new one takes effect with a restart of the application. Nothing else changes.

Terminal window
sudo cp <new-license>.cl rw/license.cl
sudo chown 1234:1234 rw/license.cl
sudo chmod 0400 rw/license.cl
docker compose restart ktdocker

Keep the original file in the installation directory as well — its name records which application version the license is bound to.

rwshared/ is the part that grows. Watch it:

Terminal window
du -sh rwshared/
df -h .

Neither log location grows without bound: the container logs are capped by the Compose file, and the application logs keep two generations.