mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
139 lines
6.4 KiB
YAML
139 lines
6.4 KiB
YAML
name: codeman
|
|
|
|
services:
|
|
codeman:
|
|
build:
|
|
context: ..
|
|
dockerfile: docker/server.Dockerfile
|
|
args:
|
|
CODEMAN_RUNTIME_USER: ${CODEMAN_RUNTIME_USER}
|
|
GIT_USER_EMAIL: ${GIT_USER_EMAIL:-}
|
|
GIT_USER_NAME: ${GIT_USER_NAME:-}
|
|
PGID: ${PGID:-1000}
|
|
PUID: ${PUID:-1000}
|
|
image: ${CODEMAN_IMAGE}
|
|
init: true
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${CODEMAN_PORT}:${CODEMAN_PORT}"
|
|
environment:
|
|
# Tells the self-updater to restart by exiting (the restart policy below
|
|
# relaunches it) rather than by looking for an init system that is not
|
|
# here. Also set in the image; repeated so a container started without the
|
|
# image default still self-identifies.
|
|
CODEMAN_IN_CONTAINER: "1"
|
|
# This file sets `restart: unless-stopped` below, so the updater may restart
|
|
# the server by EXITING. Declared here and only here, never in the image: a
|
|
# container started by plain `docker run` has no restart policy unless the
|
|
# operator gave it one, and there the updater asks the daemon instead and
|
|
# stages the update for a manual restart when it cannot get an answer.
|
|
CODEMAN_RESTART_BY_EXIT: "1"
|
|
CODEMAN_DOCKER_BRIDGE_HOOKS: ${CODEMAN_DOCKER_BRIDGE_HOOKS}
|
|
# Host-side equivalent of the runtime user's HOME. Docker case seed,
|
|
# credential and hook mounts are translated into the daemon namespace.
|
|
CODEMAN_DOCKER_HOST_HOME: ${CODEMAN_APPDATA_PATH}
|
|
CODEMAN_DOCKER_DISABLE_SWAP_LIMIT: ${CODEMAN_DOCKER_DISABLE_SWAP_LIMIT}
|
|
CODEMAN_CASES_PATH: ${CODEMAN_CASES_PATH}
|
|
# Passed through only so Codeman can use the same identity when it builds
|
|
# the Docker-case agent image.
|
|
CODEMAN_AGENT_IMAGE_GIT_USER_EMAIL: ${GIT_USER_EMAIL:-}
|
|
CODEMAN_AGENT_IMAGE_GIT_USER_NAME: ${GIT_USER_NAME:-}
|
|
# Extra Host-header allowlist entries for a reverse-proxied deployment
|
|
# (docker/README.md, "Reverse-proxy host allowlist"). Optional, so it
|
|
# defaults to empty rather than requiring a line in every .env.
|
|
CODEMAN_ALLOWED_HOSTS: ${CODEMAN_ALLOWED_HOSTS:-}
|
|
CODEMAN_HOST: ${CODEMAN_HOST}
|
|
CODEMAN_PASSWORD: ${CODEMAN_PASSWORD}
|
|
CODEMAN_PORT: ${CODEMAN_PORT}
|
|
CODEMAN_USERNAME: ${CODEMAN_USERNAME}
|
|
GEMINI_API_KEY: ${GEMINI_API_KEY}
|
|
PGID: ${PGID:-1000}
|
|
PUID: ${PUID:-1000}
|
|
TZ: ${TZ}
|
|
group_add:
|
|
# Retain access to the host Docker socket without running as root.
|
|
- ${DOCKER_SOCKET_GID:-999}
|
|
volumes:
|
|
# Application data and CLI credentials persist on the configured host
|
|
# path, rather than in a Docker-managed volume.
|
|
- type: bind
|
|
source: ${CODEMAN_APPDATA_PATH}
|
|
target: /home/${CODEMAN_RUNTIME_USER}
|
|
# Docker cases are sibling containers on the host daemon. Their workspace
|
|
# must be visible to Codeman at the same absolute path used by that daemon.
|
|
- type: bind
|
|
source: ${CODEMAN_CASES_PATH}
|
|
target: ${CODEMAN_CASES_PATH}
|
|
# Codeman uses the host daemon to create isolated Docker cases. This is
|
|
# Docker-outside-of-Docker, not Docker-in-Docker.
|
|
- type: bind
|
|
source: ${DOCKER_SOCKET}
|
|
target: /var/run/docker.sock
|
|
# The application source, so App Settings -> Updates can update in place.
|
|
# This is the SAME checkout used as the build context above, mounted over
|
|
# the image's baked copy: a `git checkout` performed inside the container
|
|
# then lands on the host and survives the container being recreated.
|
|
# Without it the pull would go to the container's writable layer and be
|
|
# silently discarded by the next `up`. See docs/docker-self-update.md.
|
|
# Defaults to `..` — the build context above — which Compose resolves
|
|
# against the project directory, so plain `docker compose up` works with
|
|
# no extra configuration. Set CODEMAN_REPO_PATH only to point elsewhere.
|
|
- type: bind
|
|
source: ${CODEMAN_REPO_PATH:-..}
|
|
target: /opt/codeman
|
|
# Build artefacts live in named volumes layered OVER the repo bind mount,
|
|
# so `npm install` and `npm run build` inside the container never write
|
|
# into the host checkout. That keeps container-compiled native modules
|
|
# (node-pty is built from source here) out of a checkout that may also be
|
|
# used to run Codeman natively, and keeps `git status` clean. Docker seeds
|
|
# an EMPTY named volume from the image, so the first start inherits the
|
|
# image's already-built node_modules and dist rather than paying for a
|
|
# bootstrap build.
|
|
- type: volume
|
|
source: codeman-node-modules
|
|
target: /opt/codeman/node_modules
|
|
- type: volume
|
|
source: codeman-dist
|
|
target: /opt/codeman/dist
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
# The entrypoint corrects bind-mount ownership as root before dropping to
|
|
# PUID:PGID. Everything not listed here remains dropped by cap_drop above.
|
|
# test/docker-entrypoint.test.ts pins this list against what the
|
|
# entrypoint and `init: true` actually need, so a capability cannot go
|
|
# missing silently again.
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
# `init: true` makes tini PID 1, and tini stays ROOT while the entrypoint
|
|
# drops the server to PUID. Signalling a process of a different uid needs
|
|
# CAP_KILL; without it tini's SIGTERM forward fails ("Unexpected error
|
|
# when forwarding signal: 'Operation not permitted'"), tini dies, and the
|
|
# PID namespace teardown SIGKILLs the server instead of letting
|
|
# `server.stop()` flush state on every `docker compose down`/`restart`.
|
|
- KILL
|
|
- SETGID
|
|
- SETUID
|
|
healthcheck:
|
|
test:
|
|
- CMD-SHELL
|
|
- >-
|
|
node -e "fetch('http://127.0.0.1:${CODEMAN_PORT}/api/status').then((response) => process.exit(response.status < 500 ? 0 : 1)).catch(() => process.exit(1))"
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
volumes:
|
|
# Container-owned build artefacts. They persist across container recreation,
|
|
# so an in-app update's `npm install` output is not thrown away by the next
|
|
# `up`, and they are seeded from the image on first use. Removing them (or
|
|
# `docker compose down -v`) is the supported reset: the next start rebuilds
|
|
# from the image.
|
|
codeman-node-modules:
|
|
codeman-dist:
|