Skip to content

Commit 73d6f22

Browse files
committed
update
1 parent 993399b commit 73d6f22

6 files changed

Lines changed: 204 additions & 22 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Rebuild 3.14 On Upstream Update
2+
3+
on:
4+
schedule:
5+
- cron: "0 */6 * * *"
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
rebuild-if-upstream-changed:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Install skopeo
20+
run: |
21+
sudo apt-get update
22+
sudo apt-get install -y skopeo
23+
24+
- name: Read latest upstream digest
25+
id: latest
26+
run: |
27+
set -euo pipefail
28+
digest="$(skopeo inspect --format '{{.Digest}}' docker://python:3.14-slim-bookworm)"
29+
echo "digest=${digest}" >> "$GITHUB_OUTPUT"
30+
31+
- name: Read stored digest
32+
id: stored
33+
run: |
34+
set -euo pipefail
35+
file=".github/state/python-3.14-slim-bookworm.digest"
36+
if [ -f "$file" ]; then
37+
echo "digest=$(cat "$file")" >> "$GITHUB_OUTPUT"
38+
else
39+
echo "digest=" >> "$GITHUB_OUTPUT"
40+
fi
41+
42+
- name: Print digest comparison
43+
run: |
44+
echo "latest: ${{ steps.latest.outputs.digest }}"
45+
echo "stored: ${{ steps.stored.outputs.digest }}"
46+
47+
- name: Login to Docker Hub
48+
if: steps.latest.outputs.digest != steps.stored.outputs.digest
49+
run: |
50+
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
51+
52+
- name: Build and push 3.14 images
53+
if: steps.latest.outputs.digest != steps.stored.outputs.digest
54+
run: |
55+
set -euo pipefail
56+
bash ./build-and-push-3_14.sh
57+
58+
- name: Persist latest digest
59+
if: steps.latest.outputs.digest != steps.stored.outputs.digest
60+
run: |
61+
set -euo pipefail
62+
mkdir -p .github/state
63+
echo "${{ steps.latest.outputs.digest }}" > .github/state/python-3.14-slim-bookworm.digest
64+
65+
git config user.name "github-actions[bot]"
66+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
67+
git add .github/state/python-3.14-slim-bookworm.digest
68+
git commit -m "chore: track python 3.14 slim-bookworm digest" || exit 0
69+
git push
70+
71+
- name: Skip build when unchanged
72+
if: steps.latest.outputs.digest == steps.stored.outputs.digest
73+
run: echo "Upstream python:3.14-slim-bookworm digest unchanged. Skipping build."

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ FROM python:${PYTHON_VERSION}-slim-bookworm AS base
88
ARG DOCKER_USER=bob
99
ARG DOCKER_GROUP=bob
1010

11+
# Persist runtime metadata used by fix-perm.sh in downstream images
12+
ENV DOCKER_USER=${DOCKER_USER} \
13+
DOCKER_GROUP=${DOCKER_GROUP}
14+
1115
# Add normal user that will use the container
1216
RUN set -ex; addgroup --gid 1000 ${DOCKER_GROUP} && \
1317
adduser --ingroup ${DOCKER_GROUP} --uid 1000 --disabled-password ${DOCKER_USER}

README.md

Lines changed: 123 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ Docker images used for ZCS Python applications.
44

55
Supported python versions:
66

7-
- `3.12`
87
- `3.11`
8+
- `3.12`
9+
- `3.13`
10+
- `3.14`
911

1012
Supported torch versions:
1113

@@ -15,26 +17,82 @@ Supported torch versions:
1517
- `2.5.1`
1618
- `2.6.0`
1719
- `2.7.0`
20+
- `2.8.0`
21+
- `2.9.0`
22+
- `2.9.1`
1823

1924
Supported platforms:
2025

2126
- `linux/amd64`
2227
- `linux/arm64`
2328

24-
## Example usage
29+
## Image variants
2530

26-
ZCS Python docker images are available in three flavours:
31+
ZCS Python docker images are available in four flavours:
2732

2833
- `base`: base image, mainly used by other stages
2934
- `dev`: image for local development
30-
- `dist`: image used for application distribution
35+
- `dist`: image used for application distribution (currently identical to `base`; naming is kept for standardization)
3136
- `torch-cpu`: image for distributing the final application with torch-cpu library
3237

38+
Notes:
39+
40+
- The `dist` image is currently equivalent to `base`; the separate tag is preserved to keep image naming conventions consistent across pipelines.
41+
42+
## Why these image variants
43+
44+
### Non-root default user (`base` / `dist`)
45+
46+
Running Python applications as a non-root user is a safer default for production workloads.
47+
48+
Benefits:
49+
50+
- Reduces container breakout impact, because processes do not run with root privileges.
51+
- Prevents accidental writes to protected system locations.
52+
- Aligns with Kubernetes and platform security policies that discourage or block root containers.
53+
- Improves day-2 operations by making file ownership and runtime behavior more predictable.
54+
55+
How to use `dist`:
56+
57+
- Use `dist` for deployable application images.
58+
- Keep `dist` in CI/CD pipelines even if it is currently equivalent to `base`, so naming remains consistent as the platform evolves.
59+
- Build application layers on top of `dist` and keep runtime as the default non-root user.
60+
61+
### Host user mapping (`dev`)
62+
63+
The `dev` image includes `fix-perm.sh` to remap container UID/GID to the host user during build.
64+
65+
Benefits:
66+
67+
- Files created from the container are owned by the host developer user, not by root or an unexpected UID.
68+
- Prevents permission conflicts in bind-mounted source directories.
69+
- Preserves repository integrity by avoiding ownership drift that can break local tooling.
70+
- Makes local development smoother across Linux hosts and CI runners with different user IDs.
71+
72+
### Preinstalled PyTorch (`torch-cpu`)
73+
74+
The `torch-cpu` image provides a ready-to-use runtime with PyTorch already installed.
75+
76+
Benefits:
77+
78+
- Faster application builds due to reduced dependency installation work.
79+
- Better reproducibility when the PyTorch version is pinned in the image tag.
80+
- Fewer network-related build failures in downstream projects.
81+
- Simpler application Dockerfiles for ML services that always require PyTorch.
82+
83+
## Example usage
84+
3385
### Docker image for local development
3486

35-
The docker image for local development support permissions mapping between host user and docker user.
87+
Use the `dev` image when you want a local environment that behaves like your host machine from a file ownership perspective.
88+
89+
Why this matters in practice:
3690

37-
Dockerfile definition to use `dev` image in local environment mapping the image `bob` user to host user:
91+
- Source files generated inside the container remain writable from your host user.
92+
- Git operations on bind-mounted repositories avoid permission issues.
93+
- Teams with different host UID/GID values can still use the same Dockerfile pattern.
94+
95+
The following Dockerfile snippet maps container user/group IDs to your host IDs during build:
3896

3997
```docker
4098
FROM zcscompany/python:3.11-dev AS dev
@@ -49,55 +107,102 @@ RUN /fix-perm.sh
49107
USER bob
50108
```
51109

52-
Build command:
110+
Build command:
111+
53112
```bash
54113
docker build --build-arg FIX_UID="$(id -u)" --build-arg FIX_GID="$(id -g)" .
55114
```
56115

116+
What happens during build:
117+
118+
- `FIX_UID` and `FIX_GID` are set from your current host user.
119+
- `/fix-perm.sh` updates container user/group IDs to match the host values.
120+
- The final image still runs as non-root, but with host-compatible ownership.
121+
57122
### Docker image for target application with torch-cpu library
58123

59-
Dockerfile definition
124+
Use this image when your runtime always requires PyTorch CPU support and you want to avoid reinstalling it in every downstream build.
125+
126+
Typical scenarios:
127+
128+
- ML inference services running on CPU-only nodes.
129+
- Batch workloads where startup/build time should be minimized.
130+
- CI pipelines where deterministic dependency layers improve reliability.
131+
132+
Dockerfile definition:
60133

61134
```docker
62135
FROM zcscompany/python:3.11-torch-cpu-2.4.0
63136
64137
# Copy application requirement file
65-
COPY --chown=bob:bob app/requirements.txt .
138+
COPY --chown=${DOCKER_USER}:${DOCKER_GROUP} app/requirements.txt .
66139
67140
# Install app requirements
68141
RUN pip install --user --no-cache-dir --disable-pip-version-check -r requirements.txt
69142
70143
# Copy application code
71-
COPY --chown=bob:bob app/ .
144+
COPY --chown=${DOCKER_USER}:${DOCKER_GROUP} app/ .
72145
73-
# Build and install the library
74-
RUN python -m build && \
75-
pip install --user --no-cache-dir --disable-pip-version-check --editable .
146+
# Run application
147+
CMD ["python", "app.py"]
76148
```
77149

150+
Notes:
151+
152+
- Keep the `torch-cpu` tag version explicit to guarantee reproducible environments.
153+
- Install only application-specific requirements in child images.
154+
78155
### Docker image for target application
79156

157+
Use `dist` as the default base for deployable Python applications that do not need preinstalled PyTorch.
158+
159+
Why use this variant:
160+
161+
- Consistent naming in CI/CD (`*-dist` tags) across projects and stages.
162+
- Non-root runtime by default for safer production deployments.
163+
- Clean separation between development (`dev`) and deployment (`dist`) concerns.
164+
80165
```docker
81166
FROM zcscompany/python:3.11-dist
82167
83168
# Copy application requirement file
84-
COPY --chown=bob:bob app/requirements.txt .
169+
COPY --chown=${DOCKER_USER}:${DOCKER_GROUP} app/requirements.txt .
85170
86171
# Install app requirements
87172
RUN pip install --user --no-cache-dir --disable-pip-version-check -r requirements.txt
88173
89174
# Copy application code
90-
COPY --chown=bob:bob app/ .
175+
COPY --chown=${DOCKER_USER}:${DOCKER_GROUP} app/ .
91176
92-
# Build and install the library
93-
RUN python -m build && \
94-
pip install --user --no-cache-dir --disable-pip-version-check --editable .
177+
# Run application
178+
CMD ["python", "app.py"]
95179
```
96180

181+
Even though `dist` is currently equivalent to `base`, keeping `dist` in application Dockerfiles is recommended so future image specialization can be adopted without changing downstream naming conventions.
182+
97183
## Docker hub repository
98184

185+
The images in this repository are published to Docker Hub and versioned by tag.
186+
187+
Docker Hub page:
188+
99189
https://hub.docker.com/r/zcscompany/python
100190

191+
In most cases you can use these images directly in your application Dockerfiles (for example `FROM zcscompany/python:3.11-dist`) without rebuilding this repository locally.
192+
193+
This is useful when you want:
194+
195+
- Faster CI pipelines, because base images are already prebuilt.
196+
- Consistent environments across teams and projects.
197+
- Simpler onboarding, since developers can pull and use images immediately.
198+
199+
Example commands:
200+
201+
```bash
202+
docker pull zcscompany/python:3.11-dist
203+
docker run --rm -it zcscompany/python:3.11-dist python --version
204+
```
205+
101206

102207
## Support
103208

build-and-push-3_13.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=
1010

1111
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dev --build-arg PYTHON_VERSION=3.13 -t zcscompany/python:3.13-dev .
1212

13-
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target base --build-arg PYTHON_VERSION=3.13 -t zcscompany/python:3.13-dist .
13+
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dist --build-arg PYTHON_VERSION=3.13 -t zcscompany/python:3.13-dist .
1414

1515
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target torch-cpu --build-arg PYTHON_VERSION=3.13 --build-arg TORCH_VERSION=2.6.0 -t zcscompany/python:3.13-torch-cpu-2.6.0 .
1616

build-and-push-3_14.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=
1010

1111
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dev --build-arg PYTHON_VERSION=3.14 -t zcscompany/python:3.14-dev .
1212

13-
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target base --build-arg PYTHON_VERSION=3.14 -t zcscompany/python:3.14-dist .
13+
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dist --build-arg PYTHON_VERSION=3.14 -t zcscompany/python:3.14-dist .
1414

1515
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target torch-cpu --build-arg PYTHON_VERSION=3.14 --build-arg TORCH_VERSION=2.9.0 -t zcscompany/python:3.14-torch-cpu-2.9.0 .
1616

build-and-push.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=
1010

1111
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dev -t zcscompany/python:3.11-dev .
1212

13-
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target base -t zcscompany/python:3.11-dist .
13+
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dist -t zcscompany/python:3.11-dist .
1414

1515
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target base --build-arg PYTHON_VERSION=3.12 -t zcscompany/python:3.12-base .
1616

1717
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dev --build-arg PYTHON_VERSION=3.12 -t zcscompany/python:3.12-dev .
1818

19-
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target base --build-arg PYTHON_VERSION=3.12 -t zcscompany/python:3.12-dist .
19+
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target dist --build-arg PYTHON_VERSION=3.12 -t zcscompany/python:3.12-dist .
2020

2121
docker buildx build --platform linux/amd64,linux/arm64 --sbom=true --provenance=true --builder=container --pull ${PUSH} --target torch-cpu --build-arg TORCH_VERSION=2.4.0 -t zcscompany/python:3.11-torch-cpu-2.4.0 .
2222

0 commit comments

Comments
 (0)