Add local development standards and guide - #140
Conversation
|
|
||
| Teams must not constrain their local development setup to a specific device or operating system. Deployed services run on Linux, per the [container standards](container_standards.md), and local development should be consistent with that: on Windows, use Windows Subsystem for Linux rather than the native Windows filesystem and tooling; on macOS, use the native environment directly. Both give a Linux-like environment that matches how the service is built and deployed. | ||
|
|
||
| Only work directly on the Windows filesystem when it is unavoidable, for example a technology that does not work through WSL such as .NET Framework. |
There was a problem hiding this comment.
I'm not sure I've worded this in the best way. There are plenty of stuff that we do that will only work on Windows or works far better on Windows like Robotics, Dynamics, Power Platform etc. I could create a bullet list of examples maybe?
I don't want to mislead anyone into doing a load of extra setup work with WSL that doesn't give any value, whilst at the same time discourage using Windows when it brings "baggage" to the team.
Refocus docker_guidance.md on container craft: base images, multi-stage builds, security, and Compose reference. Remove the local development workflow and testing sections that duplicate the local development patterns guide, and drop the principles list now covered by the local development standards. Restore Compose project isolation for CI, which the rewrite had dropped. Standardise on src/ and compose.yaml, and state the env_file plus environment layering consistently in both guides.
| `docker-compose.yaml` - builds image and runs **ServiceA** | ||
| `docker-compose.override.yaml` - runs Artemis ActiveMQ container | ||
| `docker-compose.link.yaml` - runs **ServiceA** in a named Docker network | ||
| Give each dependency a `healthcheck` and make the app `depends_on` it with `condition: service_healthy`. Without this, the app can start before the dependency is ready and fail to connect: |
There was a problem hiding this comment.
Can we recommend service_completed_successfully if one of the service listed is a script that needs running before another service. Maybe it's too niche, not sure.
|
|
||
| Changes to any of the directories listed above would automatically be picked up in the running container. | ||
| Bind only what needs watching. Do not bind `node_modules`, because the host and the image can hold different platform binaries, and there is no value in binding files such as a `README`. | ||
|
|
There was a problem hiding this comment.
| The Defra base images set `WORKDIR /home/node`, so application source lives at `/home/node/src` and dependencies at `/home/node/node_modules`. Because the mount targets `/home/node/src` only, the image's `node_modules` is never shadowed. If your service uses a different working directory, adjust the mount target to match your Dockerfile. |
| ### .dockerignore | ||
|
|
||
| When the image is built then all files in the repository are copied to the image. In this scenario, it is not ideal for performance and disk space reasons to copy the `node_modules`, `LICENCE`, `Dockerfile` or `README.md` to the image. | ||
| A `.dockerignore` file prevents local files being copied into an image during build. This keeps images small and avoids copying artifacts such as `node_modules`, local `.env` files, and test files. |
There was a problem hiding this comment.
Should we be more prescriptive about using a .dockerignore? When reading this snippet, I am not sure it emphasises enough it is highly recommended.
.dockerignore should be treated as a security control, as well as an optimisation. It should include as a minimum .git, .env , node_modules , and test files.
|
|
||
| There is an issue where Git Bash may not correctly interpret volume paths when running Docker Compose on Windows. | ||
| ```bash | ||
| git config --global core.autocrlf input |
There was a problem hiding this comment.
Maybe recommending to adopt this approach could help? It depends if we have any windows-specific files ever like bat or cmd?
| git config --global core.autocrlf input | |
| Commit a `.gitattributes` file so the setting applies to everyone rather than relying on each developer configuring their machine: | |
| * text=auto eol=lf |
| Notes on this example: | ||
|
|
||
| ``` | ||
| - **Pin the base image** with `ARG PARENT_VERSION` and use the same version for both stages. `3.1.1-node24.18.0` is the current Node 24 (LTS) Defra base at the time of writing. Check [defra-docker-node](https://github.com/DEFRA/defra-docker-node) for the latest. |
There was a problem hiding this comment.
| - **Pin the base image** with `ARG PARENT_VERSION` and use the same version for both stages. `3.1.1-node24.18.0` is the current Node 24 (LTS) Defra base at the time of writing. Check [defra-docker-node](https://github.com/DEFRA/defra-docker-node) for the latest. | |
| - **Pin the base image version.** Never depend on `latest`. An unpinned tag makes builds non-reproducible and can pull in changes you did not ask for. | |
| - **Let a bot do the chasing.** Enable Dependabot for the `docker` ecosystem. Version bumps then arrive as pull requests and your test suite decides whether they are safe. Nobody should be watching [defra-docker-node](https://github.com/DEFRA/defra-docker-node) by hand. | |
| - **Watch out for `ARG` in `FROM`.** Dependabot reads the tag literally, so `FROM defradigital/node:${PARENT_VERSION}` is invisible to it and will never be updated. If you use Dependabot, write the version out in each `FROM` line instead. The small duplication across stages is worth it. |
No description provided.