Skip to content
Merged
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
36 changes: 27 additions & 9 deletions jobs/renewal-reminders/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
FROM mcr.microsoft.com/devcontainers/python:1-3.12-bullseye
FROM mcr.microsoft.com/devcontainers/python:3.14-bookworm

ENV PYTHONUNBUFFERED 1
# 1. FIX: Remove the broken Yarn repository list so apt-get update doesn't fail
RUN rm -f /etc/apt/sources.list.d/yarn.list

Check warning on line 4 in jobs/renewal-reminders/.devcontainer/Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this RUN instruction with the consecutive ones.

See more on https://sonarcloud.io/project/issues?id=bcgov_STRR&issues=AZ09loDnG4UEpUEQH0aS&open=AZ09loDnG4UEpUEQH0aS&pullRequest=1464

# [Optional] If your requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp

# [Optional] Uncomment this section to install additional OS packages.
# 2. SYSTEM DEPENDENCIES: Install Pango, Postgres, and Node.js prerequisites
# Added 'curl' and 'gnupg' to ensure we can fetch the NodeSource setup script.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends postgresql-client libpq-dev libpango1.0-0
&& apt-get -y install --no-install-recommends \
libpango-1.0-0 \
libpangoft2-1.0-0 \
postgresql-client \
curl \
gnupg \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# 3. NODE.JS & NPM: Install Node.js v20 (LTS) via NodeSource
# This installs both 'node' and 'npm'.
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# 4. GEMINI CLI: Install the official Google Gemini CLI globally
RUN npm install -g @google/gemini-cli

# 5. POETRY: Install via pip to avoid ARM64/SSL errors
RUN pip install --no-cache-dir poetry

# 6. CONFIG: Set Poetry defaults
RUN poetry config virtualenvs.in-project true
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
echo "Running post-create-command.sh"

poetry config virtualenvs.in-project true --local
poetry install --all-extras
58 changes: 35 additions & 23 deletions jobs/renewal-reminders/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/postgres
{
"name": "Python 3",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers-extra/features/poetry:2": {}
},

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
"name": "Python Poetry & Docker-in-Docker",
"build": {
"dockerfile": "Dockerfile"
},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// This can be used to network with other containers or the host.
// "forwardPorts": [5000, 5432],

"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"enableNonRootDocker": "true",
"moby": false
},
// We keep this feature to manage Python versions, but turn off tools we handle manually
"ghcr.io/devcontainers/features/python:1": {
"version": "3.14",
"installTools": false,
"installJupyterlab": false,
"installPoetry": false
}
},

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip install --user -r requirements.txt",
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install"
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-azuretools.vscode-docker",
"tamasfe.even-better-toml"
],
"settings": {
"python.defaultInterpreterPath": ".venv/bin/python",
"python.terminal.activateEnvironment": true
}
}
},

// Configure tool-specific properties.
// "customizations": {},
"postCreateCommand": ".devcontainer/commands/post-create-command.sh",

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
"remoteUser": "vscode"
}
25 changes: 25 additions & 0 deletions jobs/renewal-reminders/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: wsgi.py",
"type": "debugpy",
"request": "launch",
"program": "wsgi.py",
"console": "integratedTerminal"
},
{
"name": "Python: Debug Unit Tests",
"type": "debugpy",
"request": "launch",
"purpose": [
"debug-test"
],
"console": "integratedTerminal",
"justMyCode": false
}
]
}
12 changes: 12 additions & 0 deletions jobs/renewal-reminders/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"python.testing.pytestArgs": [
"tests"
],
"python.analysis.extraPaths": [
"../../tests/python-test-utils/src"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python-envs.defaultEnvManager": "ms-python.python:poetry",
"python-envs.defaultPackageManager": "ms-python.python:poetry"
}
109 changes: 41 additions & 68 deletions jobs/renewal-reminders/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,91 +1,64 @@
FROM python:3.12.2-bullseye AS development_build
# Using Python 3.14 (Bookworm is the 2026 stable Debian base)
FROM python:3.14-bookworm

USER root

# Build Metadata
ARG VCS_REF="missing"
ARG BUILD_DATE="missing"

ENV VCS_REF=${VCS_REF}
ENV BUILD_DATE=${BUILD_DATE}
ENV PORT=8080
ENV VCS_REF=${VCS_REF} \
BUILD_DATE=${BUILD_DATE} \
PORT=8080 \
# Python & Pip configurations
PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_ROOT_USER_ACTION=ignore \
# Poetry 2.x configurations
POETRY_VERSION=2.3.2 \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=false \
POETRY_CACHE_DIR='/var/cache/pypoetry' \
POETRY_HOME='/usr/local'

LABEL org.label-schema.vcs-ref=${VCS_REF} \
org.label-schema.build-date=${BUILD_DATE}

LABEL maintainer="bcros"
LABEL vendor="BCROS"

ARG APP_ENV \
# Needed for fixing permissions of files created by Docker:
UID=1000 \
GID=1000

ENV APP_ENV=${APP_ENV} \
# python:
PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PYTHONDONTWRITEBYTECODE=1 \
# pip:
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_DEFAULT_TIMEOUT=100 \
PIP_ROOT_USER_ACTION=ignore \
# poetry:
POETRY_VERSION=1.8.2 \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=false \
POETRY_CACHE_DIR='/var/cache/pypoetry' \
POETRY_HOME='/usr/local'
org.label-schema.build-date=${BUILD_DATE} \
maintainer="bcros" \
vendor="BCROS"

SHELL ["/bin/bash", "-eo", "pipefail", "-c"]

# Install system dependencies and latest Poetry
RUN apt-get update && apt-get upgrade -y \
&& apt-get install --no-install-recommends -y \
bash \
brotli \
build-essential \
curl \
gettext \
git \
libpq-dev \
wait-for-it \
&& curl -sSL 'https://install.python-poetry.org' | python - \
&& poetry --version \
# Cleaning cache:
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
&& apt-get install --no-install-recommends -y \
bash brotli build-essential curl gettext git libpq-dev wait-for-it \
&& curl -sSL https://install.python-poetry.org | python3 - --version ${POETRY_VERSION} \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*

WORKDIR /code

RUN groupadd -g "${GID}" -r web \
&& useradd -d '/code' -g web -l -r -u "${UID}" web \
&& chown web:web -R '/code'
# Create non-root user
RUN groupadd -g 1000 -r web \
&& useradd -d '/code' -g web -l -r -u 1000 web \
&& chown web:web -R '/code'

# Copy only requirements, to cache them in docker layer
# Copy dependency files first for layer caching
COPY --chown=web:web ./poetry.lock ./pyproject.toml /code/

COPY --chown=web:web ./src /code/src
COPY --chown=web:web ./README.md /code

# Project initialization:
# Install production dependencies only
# In Poetry 2.x, '--only main' remains the standard for production
RUN --mount=type=cache,target="$POETRY_CACHE_DIR" \
echo "$APP_ENV" \
&& poetry version \
&& poetry config installer.max-workers 1 \
# Install deps:
&& poetry run pip install -U pip \
&& poetry install \
$(if [ -z ${APP_ENV+x} ] | [ "$APP_ENV" = 'production' ]; then echo '--only main'; fi) \
--no-interaction --no-ansi

# Running as non-root user:
USER web
poetry config virtualenvs.create false \
&& poetry install --only main --no-interaction --no-ansi --no-root

# The following stage is only for production:
FROM development_build AS production_build
# Copy project source
COPY --chown=web:web . /code

# ENV PYTHONPATH=/opt/app-root/src
# Switch to non-root user
USER web

CMD [ "python", "-m", "renewal_reminders" ]
Loading