# DevOps and cloud rules

Follow these CodeWiki-derived rules when you work in this project.

- Do not assume this is safe: putting an untrusted repository in a Dev Container does not make its code safe to execute.
  Why: `initializeCommand` runs directly on the host, lifecycle scripts execute repository code, and an editor may forward credential agents or sockets. Fix: Review `.devcontainer`, Dockerfiles, Compose files, and Feature sources before opening the environment. Do not mount the whole home directory or Docker socket. Reject `privileged`, devices, and extra capabilities unless the task specifically needs them.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- Do not assume this is safe: `containerEnv`, Compose `environment`, and Dockerfile `ENV` are not secret stores.
  Why: Values enter configuration, container metadata, process environments, or image layers. Placeholder passwords committed for local use also tend to escape into shared environments. Fix: Inject credentials at runtime through the supporting platform's secret mechanism and expose them only to the process that needs them. Prefer short-lived credentials, check logs and process arguments for leaks, and keep fixed local passwords clearly separate from real environments.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- `node:24-bookworm-slim`, a Feature at `:1`, and operating-system repositories can all change over time.
  Why: Committing one configuration file does not guarantee the same bits on a future rebuild. Fix: Use an image digest when strict reproduction matters, commit language package-manager lockfiles, and commit the CLI-generated `.devcontainer-lock.json`. Build with `--frozen-lockfile` in CI, and use a controlled process to update images and Features.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- Installing dependencies in `postStartCommand` slows every start.
  Why: Putting host preparation in `postCreateCommand` looks for host tools inside the container. A string command ending in `|| true` can turn a real setup failure into apparent success. Fix: Put repeatable host preparation in `initializeCommand`, first-creation container work in `onCreateCommand` through `postCreateCommand`, and only lightweight per-start work in `postStartCommand`. Prefer argument arrays or tested scripts and let failures stop the stage.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- Do not assume this is safe: setting only `remoteUser` does not change the entrypoint or every container operation.
  Why: Generated configurations often assume a user named `vscode`, although an image may provide `node`, `ubuntu`, or a custom account instead. Fix: Inspect the actual image user and understand the separate scopes of `containerUser` and `remoteUser`. Create files and run package managers as that account. On Linux bind mounts, test UID/GID and write access instead of recursively changing ownership of the whole workspace.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- Do not assume this is safe: the simple form of `depends_on` orders container starts but does not prove a service is ready.
  Why: `forwardPorts` also does not make separate containers communicate through `localhost`; Compose services have separate network namespaces. Fix: Give dependencies health checks and connect through their Compose service names. Test the in-container connection and the host-side forwarding separately, and expose only ports a developer actually needs to reach.
  Source: [Dev Containers](https://codewiki.com/devops/dev-containers/)
- Do not treat `latest` or a version tag as immutable lets the same Dockerfile resolve to different base content on different dates.
  Why: Testing only with the cache can keep reusing an old layer and hide that change. Fix: Record digests for release artifacts, and keep both warm-cache builds and periodic cold builds in CI. Let dependency tooling propose tag and digest changes, then scan and test them; “pinned” must not mean “never updated.”
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Passing a token through `ARG`, `ENV`, or `COPY` can place the secret in image configuration, build history, or a layer.
  Why: A later `RUN rm` only deletes the path in a new layer; it does not erase content already saved in an older one. Fix: Use a BuildKit secret mount during builds and the deployment platform's secret facility at runtime. Limit scope and lifetime, then inspect build logs, image history, and the final filesystem for leftover copies.
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Running as root and adding `--privileged`, capabilities, or the Docker socket to fix permission errors greatly expands the impact of a container compromise.
  Why: Bind-mounting the host root bypasses much of the filesystem isolation as well. Fix: Create and select a non-root image user, and add only the capabilities, devices, and read-only paths the task requires. Justify every mount and privilege. Untrusted workloads that need strong isolation require an additional sandbox or virtual-machine boundary.
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Do not assume this is safe: `EXPOSE` does not publish a port, and `localhost` inside a container refers only to that container.
  Why: Generated Compose files often configure a database at `localhost` or expose the database to the host merely for container-to-container traffic. Fix: Connect services on the same Compose network by service name, such as `db:5432`. Use `ports` only for access from the host or an external client, bind to an explicit address, and test inter-container connectivity separately from host publishing.
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Writing database data into the container's writable layer loses it when the container is replaced.
  Why: Conversely, `docker compose down -v` explicitly deletes project volumes, so a named volume is not an automatic backup. Fix: Declare a named volume or external store for persistent state and test recovery after replacing the container. Define backup, verification, and restore drills separately; inspect which volumes a cleanup command will remove before running it.
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Shell-form `CMD node app.mjs` starts `/bin/sh -c` first.
  Why: If the shell does not forward signals correctly, the application may miss the stop signal and eventually be killed; generated health checks also often call `curl` in an image that does not contain it. Fix: Prefer JSON exec form for the main process and use `exec` explicitly when a shell is necessary. Health checks must call tools present in the final image, and tests must cover startup, failure, timeout, and graceful shutdown.
  Source: [Docker](https://codewiki.com/devops/docker-guide/)
- Do not assume this is safe: generated Dockerfiles and Pods often assume a Wasm artifact contains `/bin/sh`, `curl`, a package manager, and Linux signal handlers.
  Why: A pure `application/wasm` layer supplies none of those files.
  Source: [WebAssembly containers](https://codewiki.com/devops/wasm-containers/)
- Listing a filesystem, HTTP, or randomness import in WIT or a core module says that the component needs an interface.
  Why: It neither restricts the resources reachable by the host implementation nor configures least privilege automatically.
  Source: [WebAssembly containers](https://codewiki.com/devops/wasm-containers/)
- Do not assume this is safe: an old tutorial builds a `wasm32-wasi` or `wasm32-wasip1` command module while generated deployment code assumes a `wasip2` component with `wasi:http` imports.
  Why: Both files end in `.wasm`, but their linking contracts differ.
  Source: [WebAssembly containers](https://codewiki.com/devops/wasm-containers/)
- Do not assume this is safe: `kubernetes.io/arch: wasm32` misstates the node's real CPU, while an invented `handler: spin` or `handler: wasmtime` does not install and configure the corresponding shim.
  Source: [WebAssembly containers](https://codewiki.com/devops/wasm-containers/)
- Do not assume this is safe: wasm validation does not establish artifact provenance or eliminate runtime and shim vulnerabilities.
  Why: A runwasi Wasmtime shim flaw disclosed in 2026 allowed malicious precompiled OCI layers to bypass the Wasm sandbox; affected versions were `<= 0.6.0`, and `0.6.1` fixed it.
  Source: [WebAssembly containers](https://codewiki.com/devops/wasm-containers/)
