The charm had no ``hooks/init``, so Carbone started in its default stateless mode: no Studio, no template management, and ``CARBONE_BIND`` defaulting to ``127.0.0.1`` (unreachable behind the web-proxy). Add ``hooks/init`` to: - bind on ``0.0.0.0`` so the ``web-proxy`` can reach the service ; - serve the Studio and ``/carbone-studio.js`` (``CARBONE_STUDIO``) ; - enable stateful template management (``CARBONE_TEMPLATE_MANAGEMENT``): stable 64-bit template IDs, versioning and the ``/template`` endpoints ; - align the datastore/configstore ownership on the unprivileged ``carbone`` image user, otherwise the container crash-loops with ``EACCES`` on ``/app/config/config.json``. Persist ``/app/config`` as a ``config-resources`` and set a ``docker-compose.stop_grace_period`` of 200s: Carbone flushes its template metadata on graceful shutdown, and Docker's 10s default would SIGKILL it and lose templates on redeploy. Flush metadata every 5 minutes to shrink the hard-crash window. Bump the image to ``full-5.15.1`` and add a local ``basic-deploy`` test. Verified locally: ``/status`` 200, ``/carbone-studio.js`` 200, ``GET /templates`` 200, template upload with versioning plus render from the stable template ID, and metadata survival across a container recreation.
47 lines
2.1 KiB
Bash
Executable File
47 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
## Init is run on host
|
|
## For now it is run every time the script is launched, but
|
|
## it should be launched only once after build.
|
|
|
|
## Accessible variables are:
|
|
## - SERVICE_NAME Name of current service
|
|
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
|
|
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
|
|
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
|
|
|
|
set -e
|
|
|
|
## The image runs as the unprivileged "carbone" user, while the datastore
|
|
## and configstore bind mounts are created by root. Both /app/template
|
|
## (templates + metadata.db) and /app/config (config.json, keys, license)
|
|
## must be writable by that user, otherwise the container crash-loops with
|
|
## "EACCES: permission denied, open '/app/config/config.json'".
|
|
uid_gid=($(docker_get_uid_gid "$SERVICE_NAME" "carbone" "carbone")) || exit 1
|
|
uid="${uid_gid[0]}"
|
|
gid="${uid_gid[1]}"
|
|
|
|
mkdir -p "$SERVICE_DATASTORE/app/template" "$SERVICE_CONFIGSTORE/app/config"
|
|
chown "$uid:$gid" "$SERVICE_DATASTORE/app/template" "$SERVICE_CONFIGSTORE/app/config"
|
|
|
|
## Carbone starts in stateless mode (document generation only) and binds
|
|
## to 127.0.0.1 by default (see `carbone webserver --help`, v5.15.1).
|
|
## Inside Docker it must:
|
|
## - listen on all interfaces so the web-proxy can reach it (CARBONE_BIND) ;
|
|
## - serve the Studio web interface and /carbone-studio.js (CARBONE_STUDIO) ;
|
|
## - enable stateful template management: stable 64-bit template IDs,
|
|
## versioning and the GET/POST/PATCH /template endpoints
|
|
## (CARBONE_TEMPLATE_MANAGEMENT).
|
|
##
|
|
## CARBONE_TEMPLATE_METADATA_FLUSH_CRON defaults to once a day; flushing
|
|
## every 5 minutes shrinks the window where a hard crash (SIGKILL, OOM)
|
|
## would lose template metadata. The graceful-shutdown flush remains the
|
|
## safety net for redeploys (see docker-compose.stop_grace_period).
|
|
init-config-add "
|
|
$SERVICE_NAME:
|
|
environment:
|
|
CARBONE_BIND: \"0.0.0.0\"
|
|
CARBONE_STUDIO: \"true\"
|
|
CARBONE_TEMPLATE_MANAGEMENT: \"true\"
|
|
CARBONE_TEMPLATE_METADATA_FLUSH_CRON: \"*/5 * * * *\"
|
|
" |