# tjwater-server Customer Image Packaging Notes This repository is the customer-delivery backend package. Build delivery images from this repository root. ## Image Build Build the customer backend image: ```bash docker build -t tjwater-server:latest . ``` The `Dockerfile` already performs source encapsulation in the builder stage: ```bash python scripts/compile.py python scripts/compile.py --delete-source ``` The compiled and source-deleted `app/` directory is then copied into the final runner stage. The source deletion happens inside the Docker builder layer only; it does not delete local workspace files. ## Encapsulation Scope `scripts/compile.py` defaults to compiling these sensitive areas: - `app/services` - `app/native/wndb` - `app/algorithms` - `app/infra/epanet/epanet.py` These areas should not contain uncompiled `.py` source files in the delivered image. Public entry points, API route wiring, schemas, configuration, and operational files may remain readable when required for runtime. ## Verification After building, verify the image tag: ```bash docker image ls tjwater-server ``` Verify that core source files were removed and compiled extensions exist: ```bash docker run --rm --entrypoint sh tjwater-server:latest -c "\ printf 'core_py_count='; \ find /app/app/services /app/app/native/wndb /app/app/algorithms /app/app/infra/epanet/epanet.py -name '*.py' 2>/dev/null | wc -l; \ printf 'core_so_count='; \ find /app/app/services /app/app/native/wndb /app/app/algorithms /app/app/infra/epanet -name '*.so' 2>/dev/null | wc -l; \ python -c 'import app.main; print(\"import_app_main=ok\")'" ``` Expected delivery result: ```text core_py_count=0 core_so_count= import_app_main=ok ``` Warnings from third-party packages during import are not necessarily build failures. Treat non-zero exit codes, failed imports, or leftover core `.py` files as blockers. ## Export For Windows Delivery Export the image tarball to the Windows desktop from WSL: ```bash docker save -o /mnt/c/Users/admin/Desktop/tjwater-server-latest.tar tjwater-server:latest ``` Adjust the Windows username if needed. To find available desktop paths: ```bash find /mnt/c/Users -maxdepth 2 -type d \( -name Desktop -o -name 桌面 \) 2>/dev/null ``` On the target machine, import the image with: ```bash docker load -i tjwater-server-latest.tar ``` ## Deployment Caution The development `infra/docker/docker-compose.yml` bind-mounts local source: ```yaml volumes: - ../../app:/app/app - ../../resources:/app/resources ``` Do not use that source mount for customer delivery of the encapsulated image. Mounting `../../app` over `/app/app` replaces the compiled code inside the image with local source files and defeats the encapsulation. For delivery compose files, use the built image directly and mount only required runtime data/config paths. ## Local Safety Do not run this destructive command in the normal working tree: ```bash python scripts/compile.py --delete-source ``` Only use `--delete-source` in Docker builder stages or in a disposable delivery copy. The normal delivery image build already handles this safely.