Skip to content

Commit e29ab97

Browse files
author
Daniel Sanz
committed
ci: Cache Docker image
1 parent 1933aae commit e29ab97

File tree

2 files changed

+56
-23
lines changed

2 files changed

+56
-23
lines changed

.github/workflows/publish.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ on:
77
tags:
88
- "v*.*.*"
99

10-
permissions:
11-
contents: write
12-
1310
jobs:
1411
push_to_pypi:
1512
runs-on: ubuntu-latest
@@ -36,30 +33,44 @@ jobs:
3633
needs: push_to_pypi
3734
name: Push Docker image to Docker Hub
3835
runs-on: ubuntu-latest
36+
permissions:
37+
contents: write
38+
packages: write
39+
3940
steps:
4041
- name: Check out the repo
4142
uses: actions/checkout@v4
4243

4344
- name: Log in to Docker Hub
44-
uses: docker/login-action@v2
45+
uses: docker/login-action@v3
4546
with:
4647
username: ${{ secrets.DOCKER_USERNAME }}
4748
password: ${{ secrets.DOCKER_PASSWORD }}
4849

50+
- name: Login to GitHub Container Registry
51+
uses: docker/login-action@v3
52+
with:
53+
registry: ghcr.io
54+
username: ${{ github.actor }}
55+
password: ${{ secrets.GITHUB_TOKEN }}
56+
4957
- name: Extract metadata (tags, labels) for Docker
5058
id: meta
5159
uses: docker/metadata-action@v4
5260
with:
5361
images: elementsinteractive/twyn
5462

5563
- name: Build and push Docker image
56-
uses: docker/build-push-action@v4
64+
uses: docker/build-push-action@v5
5765
with:
5866
context: .
5967
file: ./Dockerfile
6068
push: true
6169
tags: ${{ steps.meta.outputs.tags }}
6270
labels: ${{ steps.meta.outputs.labels }}
71+
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache
72+
cache-to: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache,mode=max
73+
6374
release_notes:
6475
runs-on: ubuntu-latest
6576
needs: push_to_docker_hub

Dockerfile

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,49 @@
1+
ARG PYTHON_IMAGE=3.13-slim
2+
13
# --------------- `base` stage ---------------
2-
FROM python:3.13-slim AS base
4+
FROM python:${PYTHON_IMAGE} AS base
35

4-
# Define variables
6+
# Define global values. Define them as ARG so they are not present in the final image, and so they can be modified
57
ARG USER=twyn
68
ARG GROUP=twyn
79
ARG WORKDIR=/app
810
ARG VENV_PATH=${WORKDIR}/.venv
911

10-
# Set `WORKDIR`
1112
WORKDIR ${WORKDIR}
1213

1314
# Create a non-root user and group
1415
RUN groupadd -g 1001 ${GROUP} && \
15-
useradd -m -u 1001 -g ${GROUP} -s /bin/bash ${USER}
16-
17-
# Copy all the needed files, setting their user and group ownerships to the ones we just created
18-
COPY --chown=${USER}:${GROUP} src src
19-
COPY --chown=${USER}:${GROUP} pyproject.toml pyproject.toml
20-
COPY --chown=${USER}:${GROUP} README.md README.md
21-
COPY --chown=${USER}:${GROUP} poetry.lock poetry.lock
16+
useradd -m -u 1001 -g ${GROUP} -s /bin/false ${USER}
2217

2318
# --------------- `build` stage ---------------
2419
FROM base AS build
2520

21+
# Define stage variables
22+
ARG POETRY_VERSION=2.1.2
23+
ARG POETRY_PLUGIN_EXPORT_VERSION=1.9.0
24+
25+
# These should never change, define as ENV
26+
ENV POETRY_HOME="/opt/poetry"
27+
ENV PATH="${POETRY_HOME}/bin:${PATH}"
28+
29+
# Create venv and upgrade pip
30+
RUN python -m venv ${VENV_PATH} && \
31+
${VENV_PATH}/bin/pip install --no-cache-dir --upgrade pip
32+
2633
# Install poetry and set up the virtualenv configs
27-
RUN pip install --upgrade pip && \
28-
pip install poetry && \
29-
poetry config virtualenvs.in-project true && \
30-
poetry config virtualenvs.path ${VENV_PATH}
34+
RUN apt-get update && apt-get install -y curl \
35+
&& curl -sSL https://install.python-poetry.org | POETRY_VERSION=$POETRY_VERSION python3
36+
37+
RUN poetry self add poetry-plugin-export==${POETRY_PLUGIN_EXPORT_VERSION}
38+
39+
# Copy all the needed files, without write permissions
40+
COPY poetry.lock pyproject.toml ./
3141

32-
# Install `twyn` in the virtual environment
33-
RUN poetry install --only main
42+
# Export dependencies to requirements.txt (no dev deps)
43+
RUN poetry export --without-hashes --only main -f requirements.txt > requirements.txt
44+
45+
# Create and install dependencies in the virtual env
46+
RUN ${VENV_PATH}/bin/pip install --no-cache-dir -r requirements.txt
3447

3548
# --------------- `final` stage ---------------
3649
FROM base AS final
@@ -39,8 +52,17 @@ FROM base AS final
3952
USER ${USER}:${GROUP}
4053

4154
# Copy over the virtual environment with all its dependencies and the project installed
42-
COPY --from=build --chown=${USER}:${GROUP} ${VENV_PATH} ${VENV_PATH}
55+
COPY --from=build ${WORKDIR}/requirements.txt requirements.txt
4356
ENV PATH="${VENV_PATH}/bin:$PATH"
4457

45-
# Set `ENTRYPOINT`
58+
# Copy venv with all its dependencies along with pyproject.toml
59+
COPY --from=build --chown=${USER}:${GROUP} ${VENV_PATH} ${VENV_PATH}
60+
COPY --from=build --chown=${USER}:${GROUP} ${WORKDIR}/pyproject.toml .
61+
62+
# Copy source code
63+
COPY src src
64+
65+
# Install the CLI tool
66+
RUN $VENV_PATH/bin/pip install --no-cache-dir .
67+
4668
ENTRYPOINT [ "twyn" ]

0 commit comments

Comments
 (0)