Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ on:
tags:
- "v*.*.*"

permissions:
contents: write

jobs:
push_to_pypi:
runs-on: ubuntu-latest
Expand All @@ -36,30 +33,44 @@ jobs:
needs: push_to_pypi
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
permissions:
contents: write
packages: write

steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: elementsinteractive/twyn

- name: Build and push Docker image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache
cache-to: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache,mode=max

release_notes:
runs-on: ubuntu-latest
needs: push_to_docker_hub
Expand Down
58 changes: 40 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,36 +1,49 @@
ARG PYTHON_IMAGE=3.13-slim

# --------------- `base` stage ---------------
FROM python:3.13-slim AS base
FROM python:${PYTHON_IMAGE} AS base

# Define variables
# Define global values. Define them as ARG so they are not present in the final image, and so they can be modified
ARG USER=twyn
ARG GROUP=twyn
ARG WORKDIR=/app
ARG VENV_PATH=${WORKDIR}/.venv

# Set `WORKDIR`
WORKDIR ${WORKDIR}

# Create a non-root user and group
RUN groupadd -g 1001 ${GROUP} && \
useradd -m -u 1001 -g ${GROUP} -s /bin/bash ${USER}

# Copy all the needed files, setting their user and group ownerships to the ones we just created
COPY --chown=${USER}:${GROUP} src src
COPY --chown=${USER}:${GROUP} pyproject.toml pyproject.toml
COPY --chown=${USER}:${GROUP} README.md README.md
COPY --chown=${USER}:${GROUP} poetry.lock poetry.lock
useradd -m -u 1001 -g ${GROUP} -s /bin/false ${USER}

# --------------- `build` stage ---------------
FROM base AS build

# Define stage variables
ARG POETRY_VERSION=2.1.2
ARG POETRY_PLUGIN_EXPORT_VERSION=1.9.0

# These should never change, define as ENV
ENV POETRY_HOME="/opt/poetry"
ENV PATH="${POETRY_HOME}/bin:${PATH}"

# Create venv and upgrade pip
RUN python -m venv ${VENV_PATH} && \
${VENV_PATH}/bin/pip install --no-cache-dir --upgrade pip

# Install poetry and set up the virtualenv configs
RUN pip install --upgrade pip && \
pip install poetry && \
poetry config virtualenvs.in-project true && \
poetry config virtualenvs.path ${VENV_PATH}
RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://install.python-poetry.org | POETRY_VERSION=$POETRY_VERSION python3

RUN poetry self add poetry-plugin-export==${POETRY_PLUGIN_EXPORT_VERSION}

# Copy all the needed files, without write permissions
COPY poetry.lock pyproject.toml ./

# Install `twyn` in the virtual environment
RUN poetry install --only main
# Export dependencies to requirements.txt (no dev deps)
RUN poetry export --without-hashes --only main -f requirements.txt > requirements.txt

# Create and install dependencies in the virtual env
RUN ${VENV_PATH}/bin/pip install --no-cache-dir -r requirements.txt

# --------------- `final` stage ---------------
FROM base AS final
Expand All @@ -39,8 +52,17 @@ FROM base AS final
USER ${USER}:${GROUP}

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

# Set `ENTRYPOINT`
# Copy venv with all its dependencies along with pyproject.toml
COPY --from=build --chown=${USER}:${GROUP} ${VENV_PATH} ${VENV_PATH}
COPY --from=build --chown=${USER}:${GROUP} ${WORKDIR}/pyproject.toml .

# Copy source code
COPY src src

# Install the CLI tool
RUN $VENV_PATH/bin/pip install --no-cache-dir .

ENTRYPOINT [ "twyn" ]