This repo contains code to build a vscode devcontainers that can be used as a base image for all EPS projects.
Images are build for amd64 and arm64 and a manifest file created that can be pulled for both architectures. This is then pushed to github container registry.
Images are built using using https://github.com/devcontainers/cli.
We build a base image based on mcr.microsoft.com/devcontainers/base:ubuntu-22.04 that other images are then based on
The base image contains
- latest os packages
- asdf
- aws cli
- aws sam cli
It installs the following dev container features
- docker outside of docker
- github cli
As the vscode user the following also happens
asdf install and setup for these so they are available globally as vscode user
- shellcheck
- direnv
- actionlint
- ruby (for github pages)
- trivy
- yq
Install and setup git-secrets
In each eps project, you can put this in the devcontainer Dockerfile. You should not need to add any features.
FROM ghcr.io/nhsdigital/eps-devcontainers/node_24_python_3_13:<version>
USER root
# specify DOCKER_GID to force container docker group id to match host
RUN if [ -n "${DOCKER_GID}" ]; then \
if ! getent group docker; then \
groupadd -g ${DOCKER_GID} docker; \
else \
groupmod -g ${DOCKER_GID} docker; \
fi && \
usermod -aG docker vscode; \
fi
USER vscode
We have 3 types of dev container. These are defined under src
base - this is the base image that all others are based on.
languages - this installs specific versions of node and python.
projects - this is used for projects where more customization is needed than just a base language image
Each image to be built contains a .devcontainer folder that defines how the devcontainer should be built. At a minimum, this should contain a devcontainer.json file. See https://containers.dev/implementors/json_reference/ for options for this
Images under languages should point to a dockerfile under src/common that is based off the base image. This also runs .devcontainer/scripts/root_install.sh and .devcontainer/scripts/vscode_install.sh as vscode user as part of the build
We use trivy to scan for vulnerabilities in the built docker images. Known vulnerabilities in the base image are in src/common/.trivyignore.yaml. Vulnerabilities in specific images are in .trivyignore.yaml file in each images folder. These are combined before running a scan to exclude know vulnerabilities
For each pull request, and merge to main, images are built and scanned using trivy, but the images are not pushed to github container registry
Docker images are built for each pull request, and on merges to main.
Docker images are built for amd64 and arm64 architecture, and a combined manifest is created and pushed as part of the build.
The base image is built first, and then language images, and finally project images.
Docker images are scanned for vulnerabilities using trivy as part of a build step, and the build fails if vulnerabilities are found not in .trivyignore file.
For pull requests, images are tagged with the pr--.
For merges to main, images are tagged with the
There is a release workflow that runs weekly at 18:00 on Thursday and on demand.
This creates a new release tag, builds all images, and pushes them to github container registry.
Images are tagged with the release tag, and also with latest
You can use these commands to build images
Base image
CONTAINER_NAME=base \
BASE_VERSION=latest \
BASE_FOLDER=. \
make build-image
Language images
CONTAINER_NAME=node_24_python_3_12 \
BASE_VERSION=latest \
BASE_FOLDER=languages \
make build-image
Project images
CONTAINER_NAME=fhir_facade_api \
BASE_VERSION=latest \
BASE_FOLDER=projects \
make build-image
You can use these commands to scan images Base image
CONTAINER_NAME=base \
BASE_FOLDER=. \
make scan-image
Language images
CONTAINER_NAME=node_24_python_3_12 \
BASE_FOLDER=languages \
make scan-image
Project images
CONTAINER_NAME=fhir_facade_api \
BASE_FOLDER=projects \
make scan-image
You can use this to start an interactive shell on built images base image
CONTAINER_NAME=base \
make shell-image
Language images
CONTAINER_NAME=node_24_python_3_12 \
make shell-image
Project images
CONTAINER_NAME=fhir_facade_api \
make shell-image
You can generate a .trivyignore file for known vulnerabilities by either downloading the json scan output generated by the build, or by generating it locally using the scanning images commands above with a make target of scan-image-json
If generated locally, then the output goes into .out/scan_results_docker.json
Once you have the scan output, use the following to generate a .trivyignore
poetry run python \
scripts/trivy_to_trivyignore.py \
--input .out/scan_results_docker.json \
--output src/common/.trivyignore.yaml