Docker
docker run -d --name ghchronicle \ -v /etc/ghchronicle/config.yaml:/config.yaml:ro \ -e GITHUB_TOKEN -e INFLUX_TOKEN \ -p 9605:9605 \ ghcr.io/jmrplens/ghchronicle -config /config.yamlLa imagen
Sección titulada «La imagen»Construida FROM gcr.io/distroless/static-debian13:nonroot sobre un binario
estático con CGO_ENABLED=0. No lleva shell ni gestor de paquetes, así que la
ejecución de código dentro del contenedor no tiene con qué pivotar, y la
etiqueta nonroot fija el uid 65532, lo que lo mantiene fuera de root
incluso cuando el orquestador no pone ningún securityContext propio.
Dos consecuencias que conviene saber antes de depurarlo:
docker exec ... shno funciona. No haysh. Lee los logs en su lugar.- Todo lo que el contenedor escriba debe pertenecer al uid 65532 o ser escribible por él.
Qué tiene que ser escribible
Sección titulada «Qué tiene que ser escribible»El fichero de configuración se monta de solo lectura. Cuatro cosas no:
| Ruta | Necesaria para |
|---|---|
state_ | Siempre. Sin una ruta persistente el recorrido de estrellas se repite en cada reinicio |
sinks. | Siempre. El registro de escrituras, que por omisión vive junto al fichero de estado |
sinks. | Solo con el destino de fichero |
log. | Solo con un fichero de log configurado |
Los dos primeros viven por omisión en el mismo directorio, así que un solo volumen montado cubre ambos. Montar solo el fichero de estado pierde el registro en cada reinicio, y entonces cada reinicio cuesta una pasada entera de reescritura, que es justo lo que el registro existe para evitar: solo se escribe lo que ha cambiado.
docker volume create ghchronicle-statedocker run -d --name ghchronicle \ -v /etc/ghchronicle/config.yaml:/config.yaml:ro \ -v ghchronicle-state:/var/lib/ghchronicle \ -e GITHUB_TOKEN \ ghcr.io/jmrplens/ghchronicle -config /config.yamlEl puerto
Sección titulada «El puerto»EXPOSE 9605 es el exportador de Prometheus, y es el único listener que el
proceso abre. Publícalo solo si activaste el destino prometheus; todos los
demás destinos son salientes.
Con compose
Sección titulada «Con compose»services: ghchronicle: image: ghcr.io/jmrplens/ghchronicle command: ["-config", "/config.yaml"] restart: unless-stopped environment: GITHUB_TOKEN: ${GITHUB_TOKEN} INFLUX_TOKEN: ${INFLUX_TOKEN} volumes: - ./config.yaml:/config.yaml:ro - state:/var/lib/ghchroniclevolumes: state:services: influxdb: image: influxdb:3-core volumes: - influx:/var/lib/influxdb3 ports: - "8181:8181"
ghchronicle: image: ghcr.io/jmrplens/ghchronicle command: ["-config", "/config.yaml"] restart: unless-stopped depends_on: - influxdb environment: GITHUB_TOKEN: ${GITHUB_TOKEN} INFLUX_TOKEN: ${INFLUX_TOKEN} volumes: - ./config.yaml:/config.yaml:ro - state:/var/lib/ghchronicle
volumes: influx: state:El colector alcanza la base de datos por nombre de servicio, así que
sinks.influxdb.url es http://influxdb:8181.
Una pasada y salir
Sección titulada «Una pasada y salir»El contenedor acepta las mismas opciones que el binario, así que un planificador puede ejecutarlo sin un servicio permanente.
docker run --rm \ -v /etc/ghchronicle/config.yaml:/config.yaml:ro \ -v ghchronicle-state:/var/lib/ghchronicle \ -e GITHUB_TOKEN \ ghcr.io/jmrplens/ghchronicle -config /config.yaml -onceMonta el volumen de estado también en este modo. Es lo que hace barata la segunda ejecución.