Skip to content

Commit 2cdcba2

Browse files
authored
Fix: [AEA-0000] - set vscode user to be 1001 (#16)
## Summary - Routine Change ### Details - set vscode user to be 1001
1 parent d4f77d5 commit 2cdcba2

File tree

14 files changed

+206
-72
lines changed

14 files changed

+206
-72
lines changed

.github/workflows/build_multi_arch_image.yml

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,11 @@ jobs:
8282
8383
env:
8484
ARCHITECTURE: '${{ matrix.arch }}'
85-
DOCKER_TAG: '${{ inputs.docker_tag }}'
8685
CONTAINER_NAME: '${{ inputs.container_name }}'
87-
BASE_VERSION: ${{ inputs.docker_tag}}
88-
IMAGE_TAG: ":${{ inputs.docker_tag }}-${{ matrix.arch }}"
86+
MULTI_ARCH_TAG: '${{ inputs.docker_tag }}'
87+
BASE_VERSION_TAG: ${{ inputs.docker_tag}}
88+
IMAGE_TAG: "${{ inputs.docker_tag }}-${{ matrix.arch }}"
8989
BASE_FOLDER: "${{ inputs.base_folder }}"
90-
VSCODE_UID: "1001"
91-
VSCODE_GID: "1001"
9290
- name: Check docker vulnerabilities - json output
9391
uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284
9492
with:
@@ -133,6 +131,7 @@ jobs:
133131
run: |
134132
echo "Pushing image..."
135133
docker push "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-${ARCHITECTURE}"
134+
echo "## PUSHED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-${ARCHITECTURE}" >> "$GITHUB_STEP_SUMMARY"
136135
env:
137136
DOCKER_TAG: ${{ inputs.docker_tag }}
138137
CONTAINER_NAME: '${{ inputs.container_name }}'
@@ -143,6 +142,7 @@ jobs:
143142
docker tag "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-${ARCHITECTURE}" "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-${ARCHITECTURE}"
144143
echo "Pushing image..."
145144
docker push "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-${ARCHITECTURE}"
145+
echo "## PUSHED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-${ARCHITECTURE}" >> "$GITHUB_STEP_SUMMARY"
146146
env:
147147
DOCKER_TAG: ${{ inputs.docker_tag }}
148148
CONTAINER_NAME: '${{ inputs.container_name }}'
@@ -166,10 +166,20 @@ jobs:
166166

167167
- name: Push multi-arch tagged image
168168
run: |
169-
docker buildx imagetools create -t "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" \
169+
BUILD_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
170+
export BUILD_TIMESTAMP
171+
docker buildx imagetools create \
172+
--annotation "index:org.opencontainers.image.source=https://github.com/NHSDigital/eps-devcontainers" \
173+
--annotation "index:org.opencontainers.image.description=EPS devcontainer ${CONTAINER_NAME}:${DOCKER_TAG}" \
174+
--annotation "index:org.opencontainers.image.licenses=MIT" \
175+
--annotation "index:org.opencontainers.image.version=${DOCKER_TAG}" \
176+
--annotation "index:org.opencontainers.image.containerName=${CONTAINER_NAME}" \
177+
--annotation "index:org.opencontainers.image.created=${BUILD_TIMESTAMP}" \
178+
--annotation "index:org.opencontainers.image.authors=NHS England EPS Team" \
179+
--tag "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" \
170180
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-amd64" \
171181
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-arm64"
172-
echo "## PUSHED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" >> "$GITHUB_STEP_SUMMARY"
182+
echo "## PUSHED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" >> "$GITHUB_STEP_SUMMARY"
173183
env:
174184
DOCKER_TAG: ${{ inputs.docker_tag }}
175185
CONTAINER_NAME: '${{ inputs.container_name }}'

Makefile

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ install-node:
2121
install-hooks: install-python
2222
poetry run pre-commit install --install-hooks --overwrite
2323

24-
build-image: guard-CONTAINER_NAME guard-BASE_VERSION guard-BASE_FOLDER
24+
build-image: guard-CONTAINER_NAME guard-BASE_VERSION_TAG guard-BASE_FOLDER guard-IMAGE_TAG
2525
npx devcontainer build \
2626
--workspace-folder ./src/$${BASE_FOLDER}/$${CONTAINER_NAME} \
2727
--push false \
2828
--cache-from "${CONTAINER_PREFIX}$${CONTAINER_NAME}:latest" \
29-
--label "org.opencontainers.image.revision=$$DOCKER_TAG" \
30-
--image-name "${CONTAINER_PREFIX}$${CONTAINER_NAME}${IMAGE_TAG}"
29+
--image-name "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}"
3130

3231
scan-image: guard-CONTAINER_NAME guard-BASE_FOLDER
3332
@combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \
@@ -41,9 +40,9 @@ scan-image: guard-CONTAINER_NAME guard-BASE_FOLDER
4140
--config src/${BASE_FOLDER}/${CONTAINER_NAME}/trivy.yaml \
4241
--scanners vuln \
4342
--exit-code 1 \
44-
--format table "${CONTAINER_PREFIX}$${CONTAINER_NAME}"
43+
--format table "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}"
4544

46-
scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER
45+
scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER guard-IMAGE_TAG
4746
@combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \
4847
common="src/common/.trivyignore.yaml"; \
4948
specific="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore.yaml"; \
@@ -57,11 +56,11 @@ scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER
5756
--scanners vuln \
5857
--exit-code 1 \
5958
--format json \
60-
--output .out/scan_results_docker.json "${CONTAINER_PREFIX}$${CONTAINER_NAME}"
59+
--output .out/scan_results_docker.json "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}"
6160

62-
shell-image: guard-CONTAINER_NAME
61+
shell-image: guard-CONTAINER_NAME guard-IMAGE_TAG
6362
docker run -it \
64-
"${CONTAINER_PREFIX}$${CONTAINER_NAME}${IMAGE_TAG}" \
63+
"${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}" \
6564
bash
6665

6766
lint: lint-githubactions

README.md

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Images are built using using https://github.com/devcontainers/cli.
88

99
We build a base image based on mcr.microsoft.com/devcontainers/base:ubuntu-22.04 that other images are then based on
1010

11+
The images have vsocde user setup as user 1001 so that they can be used in github actions
12+
1113
The base image contains
1214
- latest os packages
1315
- asdf
@@ -31,24 +33,80 @@ asdf install and setup for these so they are available globally as vscode user
3133
Install and setup git-secrets
3234

3335
# Using the images
34-
In each eps project, you can put this in the devcontainer Dockerfile. You should not need to add any features.
36+
In each eps project, this should be the contents of .devcontainer/Dockerfile.
37+
3538
```
36-
FROM ghcr.io/nhsdigital/eps-devcontainers/node_24_python_3_13:<version>
39+
ARG IMAGE_NAME=node_24_python_3_14
40+
ARG IMAGE_VERSION=latest
41+
FROM ghcr.io/nhsdigital/eps-devcontainers/${IMAGE_NAME}:${IMAGE_VERSION}
3742
3843
USER root
3944
# specify DOCKER_GID to force container docker group id to match host
4045
RUN if [ -n "${DOCKER_GID}" ]; then \
41-
if ! getent group docker; then \
42-
groupadd -g ${DOCKER_GID} docker; \
43-
else \
44-
groupmod -g ${DOCKER_GID} docker; \
45-
fi && \
46-
usermod -aG docker vscode; \
46+
if ! getent group docker; then \
47+
groupadd -g ${DOCKER_GID} docker; \
48+
else \
49+
groupmod -g ${DOCKER_GID} docker; \
50+
fi && \
51+
usermod -aG docker vscode; \
4752
fi
48-
49-
USER vscode
53+
```
54+
And this should be the contents of .devcontainer/devcontainer.json.
55+
This file will be used in github workflows to calculate the version of container to use in builds, so it must be valid JSON (no comments).
56+
The name should be changed to match the name of the project.
57+
IMAGE_NAME and IMAGE_VERSION should be changed as appropriate.
58+
You should not need to add any features as these are already baked into the image
59+
```
60+
{
61+
"name": "eps-common-workflows",
62+
"build": {
63+
"dockerfile": "Dockerfile",
64+
"args": {
65+
"DOCKER_GID": "${env:DOCKER_GID:}",
66+
"IMAGE_NAME": "node_24_python_3_14",
67+
"IMAGE_VERSION": "v1.0.1",
68+
"USER_UID": "${localEnv:USER_ID:}",
69+
"USER_GID": "${localEnv:GROUP_ID:}"
70+
},
71+
"updateRemoteUserUID": false,
72+
"postAttachCommand": "git-secrets --register-aws; git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt",
73+
"mounts": [
74+
"source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind",
75+
"source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind",
76+
"source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind",
77+
"source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind"
78+
],
79+
"containerUser": "vscode",
80+
"remoteEnv": {
81+
"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
82+
},
83+
"features": {},
84+
"customizations": {
85+
... add any customisations you want here
86+
}
87+
}
88+
}
5089
```
5190

91+
This job should be used in github actions wherever you need to get the dev container name or tag
92+
93+
```
94+
get_config_values:
95+
runs-on: ubuntu-22.04
96+
outputs:
97+
devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }}
98+
devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
99+
steps:
100+
- name: Checkout code
101+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
102+
- name: Load config value
103+
id: load-config
104+
run: |
105+
DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
106+
DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
107+
echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT"
108+
echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_VERSION" >> "$GITHUB_OUTPUT"
109+
```
52110
# Project structure
53111
We have 3 types of dev container. These are defined under src
54112

@@ -58,9 +116,9 @@ We have 3 types of dev container. These are defined under src
58116

59117
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
60118

61-
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
119+
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. These files should be in the language specific folder.
62120

63-
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
121+
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 all known vulnerabilities
64122

65123
# Pull requests and merge to main process
66124
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
@@ -72,7 +130,9 @@ The base image is built first, and then language images, and finally project ima
72130
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.
73131

74132
For pull requests, images are tagged with the pr-<pull request id>-<short commit sha>.
75-
For merges to main, images are tagged with the <short commit sha>
133+
For merges to main, images are tagged with the <short commit sha>.
134+
135+
When a pull request is merged to main or closed, all associated images are deleted from the registry using the github workflow delete_old_images
76136

77137
# Release workflow
78138
There is a release workflow that runs weekly at 18:00 on Thursday and on demand.
@@ -86,22 +146,25 @@ You can use these commands to build images
86146
Base image
87147
```
88148
CONTAINER_NAME=base \
89-
BASE_VERSION=latest \
149+
BASE_VERSION_TAG=latest \
90150
BASE_FOLDER=. \
151+
IMAGE_TAG=local-build \
91152
make build-image
92153
```
93154
Language images
94155
```
95156
CONTAINER_NAME=node_24_python_3_12 \
96-
BASE_VERSION=latest \
157+
BASE_VERSION_TAG=local-build \
97158
BASE_FOLDER=languages \
159+
IMAGE_TAG=local-build \
98160
make build-image
99161
```
100162
Project images
101163
```
102164
CONTAINER_NAME=fhir_facade_api \
103-
BASE_VERSION=latest \
165+
BASE_VERSION_TAG=local-build \
104166
BASE_FOLDER=projects \
167+
IMAGE_TAG=local-build \
105168
make build-image
106169
```
107170

@@ -111,18 +174,21 @@ Base image
111174
```
112175
CONTAINER_NAME=base \
113176
BASE_FOLDER=. \
177+
IMAGE_TAG=local-build \
114178
make scan-image
115179
```
116180
Language images
117181
```
118182
CONTAINER_NAME=node_24_python_3_12 \
119183
BASE_FOLDER=languages \
184+
IMAGE_TAG=local-build \
120185
make scan-image
121186
```
122187
Project images
123188
```
124189
CONTAINER_NAME=fhir_facade_api \
125190
BASE_FOLDER=projects \
191+
IMAGE_TAG=local-build \
126192
make scan-image
127193
```
128194

@@ -131,19 +197,24 @@ You can use this to start an interactive shell on built images
131197
base image
132198
```
133199
CONTAINER_NAME=base \
200+
IMAGE_TAG=local-build \
134201
make shell-image
135202
```
136203
Language images
137204
```
138205
CONTAINER_NAME=node_24_python_3_12 \
206+
IMAGE_TAG=local-build \
139207
make shell-image
140208
```
141209
Project images
142210
```
143211
CONTAINER_NAME=fhir_facade_api \
212+
IMAGE_TAG=local-build \
144213
make shell-image
145214
```
146215

216+
## Using local or pull request images
217+
You can use local or pull request images by changing IMAGE_VERSION in devcontainer.json
147218

148219
## Generating a .trivyignore file
149220
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

src/base/.devcontainer/Dockerfile

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04
22

3-
ARG BASE_VERSION=latest
4-
ARG TARGETARCH
53
ARG SCRIPTS_DIR=/usr/local/share/eps
64
ARG CONTAINER_NAME
7-
ENV TARGETARCH=${TARGETARCH}
8-
ENV CONTAINER_NAME=${CONTAINER_NAME}
5+
ARG MULTI_ARCH_TAG
6+
ARG BASE_VERSION_TAG
7+
ARG IMAGE_TAG
8+
ARG TARGETARCH
9+
910
ENV SCRIPTS_DIR=${SCRIPTS_DIR}
10-
ENV BASE_VERSION=${BASE_VERSION}
11+
ENV CONTAINER_NAME=${CONTAINER_NAME}
12+
ENV MULTI_ARCH_TAG=${MULTI_ARCH_TAG}
13+
ENV BASE_VERSION_TAG=${BASE_VERSION_TAG}
14+
ENV IMAGE_TAG=${IMAGE_TAG}
15+
ENV TARGETARCH=${TARGETARCH}
1116

1217
LABEL org.opencontainers.image.source=https://github.com/NHSDigital/eps-devcontainers
13-
LABEL org.opencontainers.image.description="EPS base devcontainer"
18+
LABEL org.opencontainers.image.description="EPS devcontainer ${CONTAINER_NAME}:${IMAGE_TAG}"
1419
LABEL org.opencontainers.image.licenses=MIT
20+
LABEL org.opencontainers.image.version=${IMAGE_TAG}
21+
LABEL org.opencontainers.image.containerName=${CONTAINER_NAME}
22+
LABEL org.opencontainers.image.authors="NHS England EPS Team"
23+
LABEL org.opencontainers.image.base.image="mcr.microsoft.com/devcontainers/base:ubuntu-22.04"
1524

1625
COPY .tool-versions.asdf ${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf
1726
COPY --chmod=755 scripts ${SCRIPTS_DIR}/${CONTAINER_NAME}
@@ -26,3 +35,6 @@ COPY --chown=vscode:vscode .tool-versions /home/vscode/.tool-versions
2635
ENV PATH="/home/vscode/.asdf/shims/:$PATH"
2736
WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME}
2837
RUN ./vscode_install.sh
38+
39+
# Switch back to root to install the devcontainer CLI globally
40+
USER root

src/base/.devcontainer/devcontainer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
"build": {
77
"dockerfile": "Dockerfile",
88
"args": {
9-
"CONTAINER_NAME": "eps_devcontainer_base",
10-
"VSCODE_UID": "${localEnv:VSCODE_UID}",
11-
"VSCODE_GID": "${localEnv:VSCODE_GID}"
9+
"CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}",
10+
"MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}",
11+
"BASE_VERSION_TAG": "${localEnv:BASE_VERSION_TAG}",
12+
"IMAGE_TAG": "${localEnv:IMAGE_TAG}"
1213
}
1314
},
1415
"runArgs": [

src/base/.devcontainer/scripts/root_install.sh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,12 @@ mkdir -p /usr/share/secrets-scanner
6767
chmod 755 /usr/share/secrets-scanner
6868
curl -L https://raw.githubusercontent.com/NHSDigital/software-engineering-quality-framework/main/tools/nhsd-git-secrets/nhsd-rules-deny.txt -o /usr/share/secrets-scanner/nhsd-rules-deny.txt
6969

70-
# fix user and group ids for vscode user to match host, and ensure vscode owns their home directory
71-
requested_uid="${VSCODE_UID:-1000}"
72-
requested_gid="${VSCODE_GID:-1000}"
70+
# fix user and group ids for vscode user to be 1001 so it can be used by github actions
71+
requested_uid=1001
72+
requested_gid=1001
7373
current_uid="$(id -u vscode)"
7474
current_gid="$(id -g vscode)"
7575
if [ "${current_gid}" != "${requested_gid}" ]; then groupmod -g "${requested_gid}" vscode; fi
7676
if [ "${current_uid}" != "${requested_uid}" ]; then usermod -u "${requested_uid}" -g "${requested_gid}" vscode; fi
77-
chown -R vscode:vscode /home/vscode
7877

79-
# store base version in VERSION.txt for reference
80-
echo "VERSION=${BASE_VERSION}" > "${SCRIPTS_DIR}/VERSION.txt"
78+
chown -R vscode:vscode /home/vscode

src/base/.devcontainer/scripts/vscode_install.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,3 @@ asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git
2424
# install base asdf versions of common tools
2525
cd /home/vscode
2626
asdf install
27-
28-
# setup gitsecrets
29-
git-secrets --register-aws --global
30-
git-secrets --add-provider --global -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt

0 commit comments

Comments
 (0)