Skip to content

Commit 6655e79

Browse files
committed
Improve Docker/Compose build defaults and reproducibility
- Add x-default-args with sane defaults in compose.yaml - Fix Poetry dev options and add npm global packages config in .env.dist - Pin Poetry version during install and harden Arch mirrorlist setup - Avoid partial upgrades in vim-ide stage and make pacman cache cleanup non-interactive - Document NPM_GLOBAL_PACKAGES in README
1 parent ad84d15 commit 6655e79

5 files changed

Lines changed: 54 additions & 24 deletions

File tree

.dockerignore

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.git
2+
.gitignore
3+
4+
__pycache__/
5+
*.pyc
6+
.mypy_cache/
7+
.pytest_cache/
8+
.ruff_cache/
9+
10+
.venv/
11+
dist/
12+
build/
13+
.tox/
14+
15+
.env
16+
.DS_Store
17+
.idea/
18+
.vscode/

.env.dist

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ DOCKER_USER_HOME=/home/developer
99

1010
MIRROR_LIST_COUNTRY=RU
1111
BUILD_PACKAGES="pyenv git gnupg sudo postgresql-libs mariadb-libs openmp"
12-
VIM_PACKAGES="python vim ctags ripgrep bat npm nodejs-lts-jod openai-codex gemini-cli"
12+
VIM_PACKAGES="python vim ctags ripgrep bat npm nodejs-lts-jod"
13+
NPM_GLOBAL_PACKAGES="@openai/codex @google/gemini-cli"
1314

1415
PYTHON_VERSION=3.14
1516
PYTHONUNBUFFERED=1
1617
PIP_DEFAULT_TIMEOUT=100
1718
POETRY_VERSION=2.2.1
1819
POETRY_OPTIONS_APP="--only main --compile"
19-
POETRY_OPTIONS_DEV="--no-root --with dev --compile"
20+
POETRY_OPTIONS_DEV="--no-root --with-dev --compile"
2021
POETRY_NO_INTERACTION=1
2122

2223
JUPYTER_TOKEN=_change_me_please_!1_

Dockerfile

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ RUN set -eux; \
1919
useradd --no-log-init -g $DOCKER_USER --uid=$DOCKER_HOST_UID \
2020
-d $DOCKER_USER_HOME -ms /bin/bash $DOCKER_USER
2121
RUN mkdir /application && chown $DOCKER_USER:$DOCKER_USER /application
22-
RUN curl -s \
23-
"https://archlinux.org/mirrorlist/?country=$MIRROR_LIST_COUNTRY&protocol=http&protocol=https&ip_version=4" \
24-
| sed -e 's/^#Server/Server/' -e '/^#/d' > /etc/pacman.d/mirrorlist
25-
RUN pacman -Syu --noconfirm && pacman -S --noconfirm $BUILD_PACKAGES
22+
RUN set -eux; \
23+
curl -fsSL "https://archlinux.org/mirrorlist/?country=${MIRROR_LIST_COUNTRY}&protocol=http&protocol=https&ip_version=4" \
24+
| sed -e 's/^\s*#Server/Server/' -e '/^\s*#/d' \
25+
> /etc/pacman.d/mirrorlist; \
26+
grep -q '^Server' /etc/pacman.d/mirrorlist
27+
RUN pacman -Syu --noconfirm && pacman -S --noconfirm --needed $BUILD_PACKAGES
2628
RUN echo "${DOCKER_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
2729
ENV PYENV_ROOT=$DOCKER_USER_HOME/.pyenv
2830
ENV PATH=$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
29-
RUN pyenv install $PYTHON_VERSION
31+
RUN pyenv install --skip-existing $PYTHON_VERSION
3032
RUN pyenv global $PYTHON_VERSION
3133
RUN pyenv rehash
3234
ENV PYTHONUNBUFFERED=1
@@ -39,7 +41,7 @@ ENV VIRTUAL_ENV=/opt/venv
3941
RUN python -m venv --copies $VIRTUAL_ENV
4042
ENV PATH=$VIRTUAL_ENV/bin:$PATH
4143
RUN pip install --upgrade pip
42-
RUN curl -sSL https://install.python-poetry.org | python -
44+
RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=$POETRY_VERSION python -
4345
ENV PATH=$POETRY_HOME/bin:$PATH
4446
ENV PYTHONPATH=/application/src
4547
ENV PROJECT_ROOT=/application
@@ -62,14 +64,17 @@ ARG POETRY_OPTIONS_APP="--only main --compile"
6264
RUN poetry install $POETRY_OPTIONS_APP -n -v -C /build && \
6365
rm -rf $POETRY_CACHE_DIR/* && rm -rf $PIP_CACHE_DIR/*
6466
RUN sed -i "/\b\($DOCKER_USER\)\b/d" /etc/sudoers
65-
RUN pacman -Scc <<< Y <<< Y
67+
RUN pacman -Scc --noconfirm
6668
USER $DOCKER_USER
6769
WORKDIR /application
6870

6971
FROM python-base AS build-deps-dev
72+
ARG DOCKER_USER=devuser
7073
ARG POETRY_OPTIONS_DEV="--no-root --with-dev --compile"
7174
COPY pyproject.toml poetry.lock /build/
7275
RUN poetry install $POETRY_OPTIONS_DEV -n -v -C /build
76+
RUN mkdir -p $POETRY_CACHE_DIR $PIP_CACHE_DIR && \
77+
chown -R $DOCKER_USER $POETRY_CACHE_DIR $PIP_CACHE_DIR
7378

7479
FROM build-deps-dev AS dev-build
7580
ARG DOCKER_USER=devuser
@@ -80,7 +85,9 @@ FROM build-deps-dev AS vim-ide
8085
ARG DOCKER_USER=devuser
8186
ARG DOCKER_USER_HOME=/home/devuser
8287
ARG VIM_PACKAGES="python vim ctags ripgrep bat npm nodejs-lts-jod"
83-
RUN pacman -Sy && pacman -S --noconfirm $VIM_PACKAGES
88+
ARG NPM_GLOBAL_PACKAGES=""
89+
RUN pacman -S --noconfirm --needed $VIM_PACKAGES
90+
RUN if [ -n "$NPM_GLOBAL_PACKAGES" ]; then npm install -g --no-fund --no-audit $NPM_GLOBAL_PACKAGES; fi
8491
USER $DOCKER_USER
8592
RUN curl -fLo $DOCKER_USER_HOME/.vim/autoload/plug.vim --create-dirs \
8693
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Use it as-is or tailor it to match your team's development workflow.
6464

6565
```bash
6666
cp .env.dist .env
67-
vim .env # Set OS packages, Python version, Poetry version, etc., and your API keys for OPENAI_API_KEY and GEMINI_API_KEY.
67+
vim .env # Set OS packages, a released PYTHON_VERSION, Poetry version, etc., and your API keys for OPENAI_API_KEY and GEMINI_API_KEY.
6868
```
6969

7070
2. Set up Python project dependencies
@@ -114,6 +114,7 @@ docker compose run --rm app
114114
```
115115

116116
- Optional: Run Codex or Gemini (see more examples below)
117+
- Note: `codex` and `gemini` CLIs are installed during the image build via `NPM_GLOBAL_PACKAGES` in `.env`.
117118

118119
```bash
119120
docker compose build codex

compose.yaml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,27 @@ x-default-env: &default-env
33
PIP_DEFAULT_TIMEOUT: "100"
44
PYTHONUNBUFFERED: "1"
55

6+
x-default-args: &default-args
7+
TZ: ${TZ:-Asia/Vladivostok}
8+
DOCKER_HOST_UID: ${DOCKER_HOST_UID:-1000}
9+
DOCKER_HOST_GID: ${DOCKER_HOST_GID:-1000}
10+
DOCKER_USER: ${DOCKER_USER:-developer}
11+
DOCKER_USER_HOME: ${DOCKER_USER_HOME:-/home/developer}
12+
MIRROR_LIST_COUNTRY: ${MIRROR_LIST_COUNTRY:-RU}
13+
BUILD_PACKAGES: ${BUILD_PACKAGES:-pyenv git gnupg sudo postgresql-libs mariadb-libs openmp}
14+
VIM_PACKAGES: ${VIM_PACKAGES:-python vim ctags ripgrep bat npm nodejs-lts-jod}
15+
PYTHON_VERSION: ${PYTHON_VERSION:-3.14}
16+
POETRY_VERSION: ${POETRY_VERSION:-2.2.1}
17+
POETRY_OPTIONS_APP: ${POETRY_OPTIONS_APP:---only main --compile}
18+
POETRY_OPTIONS_DEV: ${POETRY_OPTIONS_DEV:---no-root --with-dev --compile}
19+
NPM_GLOBAL_PACKAGES: ${NPM_GLOBAL_PACKAGES:-}
20+
621
services:
722
python-base:
823
platform: linux/amd64
924
build:
1025
target: python-base
11-
args: &default-args
12-
- TZ=${TZ}
13-
- DOCKER_HOST_UID=${DOCKER_HOST_UID}
14-
- DOCKER_HOST_GID=${DOCKER_HOST_GID}
15-
- DOCKER_USER=${DOCKER_USER}
16-
- DOCKER_USER_HOME=${DOCKER_USER_HOME}
17-
- MIRROR_LIST_COUNTRY=${MIRROR_LIST_COUNTRY}
18-
- BUILD_PACKAGES=${BUILD_PACKAGES}
19-
- VIM_PACKAGES=${VIM_PACKAGES}
20-
- PYTHON_VERSION=${PYTHON_VERSION}
21-
- POETRY_VERSION=${POETRY_VERSION}
22-
- POETRY_OPTIONS_APP=${POETRY_OPTIONS_APP}
23-
- POETRY_OPTIONS_DEV=${POETRY_OPTIONS_DEV}
26+
args: *default-args
2427
environment:
2528
<<: *default-env
2629
poetry:

0 commit comments

Comments
 (0)