From 08778d7aacaeaed5dc4fa698b20fca6cda96f087 Mon Sep 17 00:00:00 2001 From: Gizem Ekinci Date: Fri, 2 Oct 2026 16:44:38 +0200 Subject: [PATCH 1/7] Move docker compose assets into docker directory --- .github/workflows/ci_job.yml | 4 ++ dev.sh | 8 ++-- .../docker-compose.dev.yml | 44 +++++++++---------- .../docker-compose.yml | 20 ++++----- gen_compose.py => docker/gen_compose.py | 9 ++-- prod.sh | 8 ++-- tests/unit_tests/test_gen_compose.py | 4 +- tests/unit_tests/test_prod_sh.py | 37 ++++++++++++---- 8 files changed, 79 insertions(+), 55 deletions(-) rename docker-compose.dev.yml => docker/docker-compose.dev.yml (93%) rename docker-compose.yml => docker/docker-compose.yml (91%) rename gen_compose.py => docker/gen_compose.py (97%) diff --git a/.github/workflows/ci_job.yml b/.github/workflows/ci_job.yml index 7ccd902d..a6c34bdb 100644 --- a/.github/workflows/ci_job.yml +++ b/.github/workflows/ci_job.yml @@ -33,6 +33,8 @@ jobs: dev-tests: name: Full test suite on dev stack (Python 3.13) runs-on: ubuntu-latest + env: + COMPOSE_FILE: docker/docker-compose.dev.yml steps: - name: Checkout @@ -85,6 +87,8 @@ jobs: prod-smoke: name: Production smoke test runs-on: ubuntu-latest + env: + COMPOSE_FILE: docker/docker-compose.yml steps: - name: Checkout diff --git a/dev.sh b/dev.sh index 886ef18f..09aecfa8 100755 --- a/dev.sh +++ b/dev.sh @@ -23,7 +23,7 @@ Custom options: --debug, --DEBUG Enable debug mode (CLIMATECLAW_DEBUG=1) --debug=VALUE Set debug explicitly, e.g. --debug=0 or --debug=1 --no-debug Disable debug mode - --scale Generate and use docker-compose.dev.scaled.yml + --scale Generate and use docker/docker-compose.dev.scaled.yml --build Build images before starting Examples: @@ -43,7 +43,7 @@ EOF export CLIMATECLAW_DEV=1 CLIMATECLAW_DEBUG="${CLIMATECLAW_DEBUG:-0}" -COMPOSE_FILE="docker-compose.dev.yml" +COMPOSE_FILE="docker/docker-compose.dev.yml" BUILD_COMPOSE_FILE="${COMPOSE_FILE}" DO_BUILD=0 COMPOSE_ARGS=() @@ -69,8 +69,8 @@ for arg in "$@"; do ;; # Launch with scaling and proxy --scale) - ./gen_compose.py ${COMPOSE_FILE} - COMPOSE_FILE="docker-compose.dev.scaled.yml" + ./docker/gen_compose.py "${COMPOSE_FILE}" + COMPOSE_FILE="docker/docker-compose.dev.scaled.yml" ;; # Build images once from the unscaled compose file. --build) diff --git a/docker-compose.dev.yml b/docker/docker-compose.dev.yml similarity index 93% rename from docker-compose.dev.yml rename to docker/docker-compose.dev.yml index 062dd5ef..e583015e 100644 --- a/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -1,7 +1,7 @@ services: climateclaw-base: build: - context: . + context: .. dockerfile: docker/Dockerfile.base image: ghcr.io/freva-org/climateclaw-base:latest profiles: @@ -10,9 +10,9 @@ services: climateclaw: image: climateclaw-${CLIMATECLAW_INSTANCE_NAME:?Instance name must be set in the .env file to differentiate between instances} build: - context: . + context: .. dockerfile: docker/climateclaw/Dockerfile - env_file: .env + env_file: ../.env environment: CLIMATECLAW_DEV: ${CLIMATECLAW_DEV} CLIMATECLAW_DEBUG: ${CLIMATECLAW_DEBUG:-0} @@ -22,8 +22,8 @@ services: - "8600:${CLIMATECLAW_BACKEND_PORT:-8502}" # localhost:8600/docs give FastAPI docs - "${CLIMATECLAW_DEBUG_PORT:-5678}:${CLIMATECLAW_DEBUG_PORT:-5678}" # Port for debugpy volumes: - - ./cache/:/app/cache - - ./logs/:/app/logs + - ../cache/:/app/cache + - ../logs/:/app/logs networks: - climateclaw healthcheck: @@ -41,9 +41,9 @@ services: rag-server: image: rag-server-${CLIMATECLAW_INSTANCE_NAME} build: - context: . + context: .. dockerfile: docker/rag-server/Dockerfile - env_file: .env + env_file: ../.env hostname: rag-server-${CLIMATECLAW_INSTANCE_NAME} environment: CLIMATECLAW_DEV: ${CLIMATECLAW_DEV} @@ -51,17 +51,17 @@ services: CLIMATECLAW_MCP_HOST: 0.0.0.0 CLIMATECLAW_MCP_PORT: ${CLIMATECLAW_RAG_PORT:-8050} volumes: - - ./resources:/app/resources:ro - - ./logs/:/app/logs + - ../resources:/app/resources:ro + - ../logs/:/app/logs networks: - climateclaw code-server: image: code-server-${CLIMATECLAW_INSTANCE_NAME} build: - context: . + context: .. dockerfile: docker/code-server/Dockerfile - env_file: .env + env_file: ../.env hostname: code-server-${CLIMATECLAW_INSTANCE_NAME} environment: CLIMATECLAW_DEV: ${CLIMATECLAW_DEV} @@ -72,8 +72,8 @@ services: - 8051:8051 cpus: 4 volumes: - - ./cache/:/app/cache - - ./logs/:/app/logs + - ../cache/:/app/cache + - ../logs/:/app/logs networks: - climateclaw healthcheck: @@ -86,9 +86,9 @@ services: web-search-server: image: web-search-server-${CLIMATECLAW_INSTANCE_NAME} build: - context: . + context: .. dockerfile: docker/web-search-server/Dockerfile - env_file: .env + env_file: ../.env hostname: web-search-server-${CLIMATECLAW_INSTANCE_NAME} environment: CLIMATECLAW_DEV: ${CLIMATECLAW_DEV} @@ -100,7 +100,7 @@ services: networks: - climateclaw volumes: - - ./logs/:/app/logs + - ../logs/:/app/logs healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:8052/healthz')\""] interval: 30s @@ -112,8 +112,8 @@ services: image: ghcr.io/berriai/litellm:main-latest hostname: litellm-${CLIMATECLAW_INSTANCE_NAME} volumes: - - ./litellm_config.yaml:/app/config.yaml # Mount the local litellm_config.yaml file to the container - - ./logs/:/app/logs + - ../litellm_config.yaml:/app/config.yaml # Mount the local litellm_config.yaml file to the container + - ../logs/:/app/logs entrypoint: ["/bin/sh", "-c"] command: - > @@ -124,7 +124,7 @@ services: --run_gunicorn --detailed_debug 2>&1 | tee -a /app/logs/litellm.log - env_file: .env + env_file: ../.env ports: - "4000:4000" # Expose LiteLLM port to the host machine for direct access if needed, e.g. local dev networks: @@ -154,7 +154,7 @@ services: ports: - "27017:27017" volumes: - - ./mongo-data:/data/db + - ../mongo-data:/data/db healthcheck: test: ["CMD", "healthchecks", "-s", "mongo"] interval: 35s @@ -201,8 +201,8 @@ services: - DEV_MODE=1 - CHAT_BOT=1 volumes: - - ./docker/freva.conf:/data/evaluation_system.conf - - ./cache/:/opt/freva_web/static/preview/climateclaw + - ./freva.conf:/data/evaluation_system.conf + - ../cache/:/opt/freva_web/static/preview/climateclaw freva-cache: networks: diff --git a/docker-compose.yml b/docker/docker-compose.yml similarity index 91% rename from docker-compose.yml rename to docker/docker-compose.yml index 74d8f35b..7ff9aa21 100644 --- a/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,9 +2,9 @@ services: climateclaw-base: # Build manually with: - # docker compose -f docker-compose.dev.yml --profile build-only build climateclaw-base + # docker compose -f docker/docker-compose.dev.yml --profile build-only build climateclaw-base build: - context: . + context: .. dockerfile: docker/Dockerfile.base image: ghcr.io/freva-org/climateclaw-base:latest profiles: @@ -13,9 +13,9 @@ services: climateclaw: image: climateclaw-${CLIMATECLAW_INSTANCE_NAME:?Instance name must be set in the .env file to differentiate between instances} build: - context: . + context: .. dockerfile: docker/climateclaw/Dockerfile - env_file: .env + env_file: ../.env hostname: climateclaw-${CLIMATECLAW_INSTANCE_NAME} ports: - "${CLIMATECLAW_TARGET_PORT:-8502}:${CLIMATECLAW_BACKEND_PORT:-8502}" # If either is unset, the default value will be used. @@ -40,9 +40,9 @@ services: code-server: image: code-server-${CLIMATECLAW_INSTANCE_NAME} build: - context: . + context: .. dockerfile: docker/code-server/Dockerfile - env_file: .env + env_file: ../.env hostname: code-server-${CLIMATECLAW_INSTANCE_NAME} environment: CLIMATECLAW_MCP_HOST: 0.0.0.0 @@ -64,9 +64,9 @@ services: web-search-server: image: web-search-server-${CLIMATECLAW_INSTANCE_NAME} build: - context: . + context: .. dockerfile: docker/web-search-server/Dockerfile - env_file: .env + env_file: ../.env hostname: web-search-server-${CLIMATECLAW_INSTANCE_NAME} environment: CLIMATECLAW_MCP_HOST: 0.0.0.0 @@ -86,7 +86,7 @@ services: image: ghcr.io/berriai/litellm:v1.102.0 hostname: litellm-${CLIMATECLAW_INSTANCE_NAME} volumes: - - ./litellm_config.yaml:/app/config.yaml # Mount the local litellm_config.yaml file to the container + - ../litellm_config.yaml:/app/config.yaml # Mount the local litellm_config.yaml file to the container - /container/da/climateclaw-links/${CLIMATECLAW_INSTANCE_NAME}/logs:/app/logs entrypoint: ["/bin/sh", "-c"] command: @@ -98,7 +98,7 @@ services: --run_gunicorn --detailed_debug 2>&1 | tee -a /app/logs/litellm.log - env_file: .env + env_file: ../.env environment: CLIMATECLAW_VLLM_LITELLM_MODEL: "hosted_vllm/${CLIMATECLAW_VLLM_MODEL_ID:-nvidia/Gemma-4-31B-IT-NVFP4}" networks: diff --git a/gen_compose.py b/docker/gen_compose.py similarity index 97% rename from gen_compose.py rename to docker/gen_compose.py index 5be2f52e..a0938699 100755 --- a/gen_compose.py +++ b/docker/gen_compose.py @@ -289,7 +289,7 @@ def generate_haproxy( def main(): if len(sys.argv) < 2: - print("Usage: gen_compose.py docker-compose.dev.yml [project]") + print("Usage: docker/gen_compose.py docker/docker-compose.dev.yml [project]") sys.exit(1) compose_path = sys.argv[1] @@ -373,7 +373,7 @@ def main(): network_name = list(base["networks"].keys())[0] log_dir = ( - "./logs/" + "../logs/" if "dev" in compose_path else "/container/da/climateclaw-links/${CLIMATECLAW_INSTANCE_NAME}/logs" ) @@ -421,9 +421,10 @@ def main(): timeout=mcp_request_timeout, ) - Path("haproxy.cfg").write_text(haproxy_cfg) + haproxy_path = input_path.with_name("haproxy.cfg") + haproxy_path.write_text(haproxy_cfg) - print(f"Generated {output_path.name} and haproxy.cfg") + print(f"Generated {output_path} and {haproxy_path}") if __name__ == "__main__": diff --git a/prod.sh b/prod.sh index 7792cc31..05a647b7 100755 --- a/prod.sh +++ b/prod.sh @@ -7,7 +7,7 @@ Usage: $(basename "$0") [OPTIONS] [COMPOSE_ARGS...] Deploy the climateclaw stack via podman-compose. -Generates a scaled compose file from docker-compose.yml, tears down any +Generates a scaled compose file from docker/docker-compose.yml, tears down any previous deployment, optionally rebuilds images, and starts the services. Options: @@ -32,8 +32,8 @@ EOF exit 0 } -COMPOSE_FILE="docker-compose.yml" -SCALED_FILE="docker-compose.scaled.yml" +COMPOSE_FILE="docker/docker-compose.yml" +SCALED_FILE="docker/docker-compose.scaled.yml" ENV_FILE=".env" PROJECT="${CLIMATECLAW_PROJECT_NAME:-}" do_build=false @@ -122,7 +122,7 @@ fi # --- Generate scaled compose file --- echo "[prod.sh] Generating scaled compose file from ${COMPOSE_FILE}" echo "[prod.sh] Using project: ${CLIMATECLAW_PROJECT_NAME}" -./gen_compose.py "${COMPOSE_FILE}" "${PROJECT}" +./docker/gen_compose.py "${COMPOSE_FILE}" "${PROJECT}" # --- Tear down previous deployment --- ${COMPOSE} -f "${SCALED_FILE}" down diff --git a/tests/unit_tests/test_gen_compose.py b/tests/unit_tests/test_gen_compose.py index 26b6b6c8..3a83eb75 100644 --- a/tests/unit_tests/test_gen_compose.py +++ b/tests/unit_tests/test_gen_compose.py @@ -5,8 +5,8 @@ import pytest import yaml -# gen_compose.py is a repo-root script, while pytest only adds src/ to sys.path. -GEN_COMPOSE_PATH = Path(__file__).resolve().parents[2] / "gen_compose.py" +# gen_compose.py lives under docker/, while pytest only adds src/ to sys.path. +GEN_COMPOSE_PATH = Path(__file__).resolve().parents[2] / "docker" / "gen_compose.py" spec = importlib.util.spec_from_file_location("gen_compose", GEN_COMPOSE_PATH) assert spec is not None assert spec.loader is not None diff --git a/tests/unit_tests/test_prod_sh.py b/tests/unit_tests/test_prod_sh.py index 7722d625..906014cb 100644 --- a/tests/unit_tests/test_prod_sh.py +++ b/tests/unit_tests/test_prod_sh.py @@ -12,8 +12,10 @@ def _prod_fixture(tmp_path, monkeypatch): repo_root = os.getcwd() shutil.copy(repo_root + "/prod.sh", tmp_path / "prod.sh") (tmp_path / "prod.sh").chmod(0o755) - (tmp_path / "docker-compose.yml").write_text("services: {}\n") - (tmp_path / "docker-compose.scaled.yml").write_text("services: {}\n") + docker_dir = tmp_path / "docker" + docker_dir.mkdir() + (docker_dir / "docker-compose.yml").write_text("services: {}\n") + (docker_dir / "docker-compose.scaled.yml").write_text("services: {}\n") bin_dir = tmp_path / "bin" bin_dir.mkdir() @@ -29,7 +31,7 @@ def _prod_fixture(tmp_path, monkeypatch): "exit 0\n", ) _write_executable( - tmp_path / "gen_compose.py", + docker_dir / "gen_compose.py", "#!/usr/bin/env bash\n" 'echo "gen_compose $* PROJECT=$CLIMATECLAW_PROJECT_NAME"' ' >> "$PROD_SH_TEST_LOG"\n' @@ -70,8 +72,14 @@ def test_prod_sh_project_flag_sets_project_and_uses_default_up_args( result = _run_prod(tmp_path, "--project", "codes") assert result.returncode == 0 - assert "gen_compose docker-compose.yml codes PROJECT=codes" in log_path.read_text() - assert "podman-compose -f docker-compose.scaled.yml up -d" in log_path.read_text() + assert ( + "gen_compose docker/docker-compose.yml codes PROJECT=codes" + in log_path.read_text() + ) + assert ( + "podman-compose -f docker/docker-compose.scaled.yml up -d" + in log_path.read_text() + ) def test_prod_sh_project_equals_flag_sets_project(tmp_path, monkeypatch): @@ -80,7 +88,10 @@ def test_prod_sh_project_equals_flag_sets_project(tmp_path, monkeypatch): result = _run_prod(tmp_path, "--project=codes") assert result.returncode == 0 - assert "gen_compose docker-compose.yml codes PROJECT=codes" in log_path.read_text() + assert ( + "gen_compose docker/docker-compose.yml codes PROJECT=codes" + in log_path.read_text() + ) def test_prod_sh_reads_project_from_env_file(tmp_path, monkeypatch): @@ -90,7 +101,10 @@ def test_prod_sh_reads_project_from_env_file(tmp_path, monkeypatch): result = _run_prod(tmp_path) assert result.returncode == 0 - assert "gen_compose docker-compose.yml codes PROJECT=codes" in log_path.read_text() + assert ( + "gen_compose docker/docker-compose.yml codes PROJECT=codes" + in log_path.read_text() + ) def test_prod_sh_project_flag_overrides_env_file(tmp_path, monkeypatch): @@ -100,7 +114,10 @@ def test_prod_sh_project_flag_overrides_env_file(tmp_path, monkeypatch): result = _run_prod(tmp_path, "--project", "codes") assert result.returncode == 0 - assert "gen_compose docker-compose.yml codes PROJECT=codes" in log_path.read_text() + assert ( + "gen_compose docker/docker-compose.yml codes PROJECT=codes" + in log_path.read_text() + ) def test_prod_sh_preserves_compose_args_after_flags(tmp_path, monkeypatch): @@ -110,5 +127,7 @@ def test_prod_sh_preserves_compose_args_after_flags(tmp_path, monkeypatch): assert result.returncode == 0 log = log_path.read_text() - assert "podman-compose -f docker-compose.scaled.yml up --force-recreate" in log + assert ( + "podman-compose -f docker/docker-compose.scaled.yml up --force-recreate" in log + ) assert "--project codes" not in log From 3d842e328a1498ec30227410117997d8920d0daf Mon Sep 17 00:00:00 2001 From: Gizem Ekinci Date: Fri, 2 Oct 2026 16:45:53 +0200 Subject: [PATCH 2/7] Anchor launcher scripts to repo root --- dev.sh | 3 +++ prod.sh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dev.sh b/dev.sh index 09aecfa8..033a9e2a 100755 --- a/dev.sh +++ b/dev.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -euo pipefail +ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +cd "${ROOT_DIR}" + # ------------------------------------------------------------------ # Simple dev launcher for ClimateClaw # diff --git a/prod.sh b/prod.sh index 05a647b7..67085faf 100755 --- a/prod.sh +++ b/prod.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -euo pipefail +ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +cd "${ROOT_DIR}" + usage() { cat < Date: Fri, 2 Oct 2026 16:57:22 +0200 Subject: [PATCH 3/7] Load root env file for relocated compose stacks --- .github/workflows/ci_job.yml | 2 ++ dev.sh | 7 ++++--- docker/docker-compose.dev.yml | 1 - prod.sh | 10 +++++----- tests/unit_tests/test_prod_sh.py | 5 +++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci_job.yml b/.github/workflows/ci_job.yml index a6c34bdb..98d5a39a 100644 --- a/.github/workflows/ci_job.yml +++ b/.github/workflows/ci_job.yml @@ -35,6 +35,7 @@ jobs: runs-on: ubuntu-latest env: COMPOSE_FILE: docker/docker-compose.dev.yml + COMPOSE_ENV_FILES: .env steps: - name: Checkout @@ -89,6 +90,7 @@ jobs: runs-on: ubuntu-latest env: COMPOSE_FILE: docker/docker-compose.yml + COMPOSE_ENV_FILES: .env steps: - name: Checkout diff --git a/dev.sh b/dev.sh index 033a9e2a..33d5e1d1 100755 --- a/dev.sh +++ b/dev.sh @@ -46,6 +46,7 @@ EOF export CLIMATECLAW_DEV=1 CLIMATECLAW_DEBUG="${CLIMATECLAW_DEBUG:-0}" +ENV_FILE=".env" COMPOSE_FILE="docker/docker-compose.dev.yml" BUILD_COMPOSE_FILE="${COMPOSE_FILE}" DO_BUILD=0 @@ -92,9 +93,9 @@ export CLIMATECLAW_DEBUG echo "[dev.sh] Using ${COMPOSE_FILE} with DEBUG=${CLIMATECLAW_DEBUG}" echo "[dev.sh] docker compose -f ${COMPOSE_FILE} ${COMPOSE_ARGS[*]}" -docker compose -f "${BUILD_COMPOSE_FILE}" --profile build-only build climateclaw-base +docker compose --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" --profile build-only build climateclaw-base if [ "${DO_BUILD}" = "1" ]; then echo "[dev.sh] Building images from ${BUILD_COMPOSE_FILE}" - docker compose -f "${BUILD_COMPOSE_FILE}" build + docker compose --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" build fi -docker compose -f "${COMPOSE_FILE}" "${COMPOSE_ARGS[@]}" +docker compose --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" "${COMPOSE_ARGS[@]}" diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index e583015e..71115213 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -122,7 +122,6 @@ services: --port=4000 --num_workers=8 --run_gunicorn - --detailed_debug 2>&1 | tee -a /app/logs/litellm.log env_file: ../.env ports: diff --git a/prod.sh b/prod.sh index 67085faf..7e9348d7 100755 --- a/prod.sh +++ b/prod.sh @@ -128,19 +128,19 @@ echo "[prod.sh] Using project: ${CLIMATECLAW_PROJECT_NAME}" ./docker/gen_compose.py "${COMPOSE_FILE}" "${PROJECT}" # --- Tear down previous deployment --- -${COMPOSE} -f "${SCALED_FILE}" down +${COMPOSE} --env-file "${ENV_FILE}" -f "${SCALED_FILE}" down echo "[prod.sh] Building climateclaw-base from ${COMPOSE_FILE}" -${COMPOSE} -f "${COMPOSE_FILE}" --profile build-only build climateclaw-base +${COMPOSE} --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" --profile build-only build climateclaw-base if [ "$do_build" = true ]; then echo "[prod.sh] Building images ..." - ${COMPOSE} -f "${COMPOSE_FILE}" build + ${COMPOSE} --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" build fi # --- Start --- if [ ${#args[@]} -eq 0 ]; then args=(up -d) fi -echo "[prod.sh] Starting: ${COMPOSE} -f ${SCALED_FILE} ${args[*]}" -${COMPOSE} -f "${SCALED_FILE}" "${args[@]}" +echo "[prod.sh] Starting: ${COMPOSE} --env-file ${ENV_FILE} -f ${SCALED_FILE} ${args[*]}" +${COMPOSE} --env-file "${ENV_FILE}" -f "${SCALED_FILE}" "${args[@]}" diff --git a/tests/unit_tests/test_prod_sh.py b/tests/unit_tests/test_prod_sh.py index 906014cb..f8d02792 100644 --- a/tests/unit_tests/test_prod_sh.py +++ b/tests/unit_tests/test_prod_sh.py @@ -77,7 +77,7 @@ def test_prod_sh_project_flag_sets_project_and_uses_default_up_args( in log_path.read_text() ) assert ( - "podman-compose -f docker/docker-compose.scaled.yml up -d" + "podman-compose --env-file .env -f docker/docker-compose.scaled.yml up -d" in log_path.read_text() ) @@ -128,6 +128,7 @@ def test_prod_sh_preserves_compose_args_after_flags(tmp_path, monkeypatch): assert result.returncode == 0 log = log_path.read_text() assert ( - "podman-compose -f docker/docker-compose.scaled.yml up --force-recreate" in log + "podman-compose --env-file .env -f docker/docker-compose.scaled.yml up --force-recreate" + in log ) assert "--project codes" not in log From 78594894abd44cbafc1a1e7924e160174b22c298 Mon Sep 17 00:00:00 2001 From: Gizem Ekinci Date: Mon, 5 Oct 2026 16:25:48 +0200 Subject: [PATCH 4/7] Merge branch 'main' into reorganize-docker From 63a68ec68a26695bf04b55f418bfe2adb51310ca Mon Sep 17 00:00:00 2001 From: Gizem Ekinci Date: Mon, 5 Oct 2026 16:31:23 +0200 Subject: [PATCH 5/7] Move ci compose to docker directory --- .github/workflows/ci_job.yml | 9 ++------- docker-compose.ci.yml => docker/docker-compose.ci.yml | 0 2 files changed, 2 insertions(+), 7 deletions(-) rename docker-compose.ci.yml => docker/docker-compose.ci.yml (100%) diff --git a/.github/workflows/ci_job.yml b/.github/workflows/ci_job.yml index ee289887..d1c95215 100644 --- a/.github/workflows/ci_job.yml +++ b/.github/workflows/ci_job.yml @@ -89,7 +89,7 @@ jobs: name: Production smoke test runs-on: ubuntu-latest env: - COMPOSE_FILE: docker/docker-compose.yml + COMPOSE_FILE: docker/docker-compose.yml:docker/docker-compose.ci.yml COMPOSE_ENV_FILES: .env steps: @@ -115,16 +115,11 @@ jobs: - name: Start production stack run: | - docker compose \ - -f docker-compose.yml \ - -f docker-compose.ci.yml \ - up climateclaw code-server web-search-server \ + docker compose up climateclaw code-server web-search-server \ -d --wait --build --remove-orphans || { docker ps -a docker compose \ - -f docker-compose.yml \ - -f docker-compose.ci.yml \ logs climateclaw mongodb code-server web-search-server litellm exit 1 diff --git a/docker-compose.ci.yml b/docker/docker-compose.ci.yml similarity index 100% rename from docker-compose.ci.yml rename to docker/docker-compose.ci.yml From ef9c0c2bee938596765c2612feae8276f415328b Mon Sep 17 00:00:00 2001 From: Gizem Ekinci Date: Mon, 5 Oct 2026 17:50:09 +0200 Subject: [PATCH 6/7] Preserve repository-based compose project name in prod --- prod.sh | 12 +++++++----- tests/unit_tests/test_prod_sh.py | 9 ++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/prod.sh b/prod.sh index 7e9348d7..e2d30f6b 100755 --- a/prod.sh +++ b/prod.sh @@ -3,6 +3,7 @@ set -euo pipefail ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" cd "${ROOT_DIR}" +COMPOSE_PROJECT_NAME="${ROOT_DIR##*/}" usage() { cat < Date: Mon, 5 Oct 2026 18:09:56 +0200 Subject: [PATCH 7/7] Preserve repository-based compose project name in dev --- dev.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev.sh b/dev.sh index d526fed1..9f99d284 100755 --- a/dev.sh +++ b/dev.sh @@ -3,6 +3,7 @@ set -euo pipefail ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" cd "${ROOT_DIR}" +COMPOSE_PROJECT_NAME="${ROOT_DIR##*/}" # ------------------------------------------------------------------ # Simple dev launcher for ClimateClaw @@ -94,9 +95,9 @@ export CLIMATECLAW_DEBUG echo "[dev.sh] Using ${COMPOSE_FILE} with DEBUG=${CLIMATECLAW_DEBUG}" echo "[dev.sh] docker compose -f ${COMPOSE_FILE} ${COMPOSE_ARGS[*]}" -docker compose --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" --profile build-only build climateclaw-base +docker compose --project-name "${COMPOSE_PROJECT_NAME}" --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" --profile build-only build climateclaw-base if [ "${DO_BUILD}" = "1" ]; then echo "[dev.sh] Building images from ${BUILD_COMPOSE_FILE}" - docker compose --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" build + docker compose --project-name "${COMPOSE_PROJECT_NAME}" --env-file "${ENV_FILE}" -f "${BUILD_COMPOSE_FILE}" build fi -docker compose --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" "${COMPOSE_ARGS[@]}" +docker compose --project-name "${COMPOSE_PROJECT_NAME}" --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" "${COMPOSE_ARGS[@]}"