Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs/docker best practices #9542

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4bc181b
use run_pip of env in executor (#2701)
jstriebel Jul 24, 2020
0f565f8
feat(docs, docker): init draft
gianfa Jun 19, 2024
9afee37
Merge branch 'develop' into docs/docker-best-practices
gianfa Jul 10, 2024
29a7ca9
feat(docker-examples): add minimum-poetry
gianfa Jul 10, 2024
2ca1352
feat(docker-examples): add poetry-multistage
gianfa Jul 10, 2024
25c30d9
feat(docs, docker-best-practices): add minimum-poetry and poetry-mult…
gianfa Jul 10, 2024
45e964e
fix(project): remove unrelated file
gianfa Jul 10, 2024
a9b16f2
feat(docs, docker): init draft
gianfa Jun 19, 2024
32d4e36
feat(docker-examples): add minimum-poetry
gianfa Jul 10, 2024
e2d89e8
feat(docker-examples): add poetry-multistage
gianfa Jul 10, 2024
5500497
feat(docs, docker-best-practices): add minimum-poetry and poetry-mult…
gianfa Jul 10, 2024
8e616ad
pre-commit
radoering Oct 12, 2024
4e4159f
fix weight
radoering Oct 12, 2024
aaa83a3
set draft to false to see if page will be visible in preview
radoering Oct 12, 2024
f0b51e9
remove table of contents because it is created automatically in the s…
radoering Oct 12, 2024
8d62c5a
use relative links
radoering Oct 12, 2024
08ad09c
temp: fix links (have to be changed to main before merging)
radoering Oct 12, 2024
b8f105c
fix link, formatting and typo
radoering Oct 12, 2024
85c7f6e
Merge branch 'docs/docker-best-practices' of https://github.com/gianf…
gianfa Oct 12, 2024
439feae
feat(docs, docker-best-practices): add 'Use cases' in README of poetr…
gianfa Oct 12, 2024
c541178
feat(docs, docker-best-practices): add 'Use Docker cache mounts'
gianfa Oct 12, 2024
452caed
feat(docker-examples, minimum-poetry): add COPY poetry.lock; add 'ins…
gianfa Oct 12, 2024
10454a3
feat(docker-examples, poetry-multistage): add COPY poetry.loc
gianfa Oct 12, 2024
246e181
Merge branch 'main' into docs/docker-best-practices
gianfa Oct 12, 2024
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
1 change: 1 addition & 0 deletions docker-examples/minimum-poetry/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
poetry.lock
18 changes: 18 additions & 0 deletions docker-examples/minimum-poetry/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.11-slim

ARG POETRY_VERSION=1.8

# See https://python-poetry.org/docs/#ci-recommendations
RUN pip install "poetry==${POETRY_VERSION}"

WORKDIR /app

# --- Reproduce the environment ---
# You can comment the following two lines if you prefer to manually install
# the dependencies from inside the container.
COPY pyproject.toml .
gianfa marked this conversation as resolved.
Show resolved Hide resolved

RUN poetry install
gianfa marked this conversation as resolved.
Show resolved Hide resolved
# --- --- --- --- --- --- --- --- ---

ENTRYPOINT ["bash"]
38 changes: 38 additions & 0 deletions docker-examples/minimum-poetry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Minimum Poetry image

## Description

Minimum-poetry is the minimum-constructible image containing poetry, from an official python base image.

Expected size: ~218 MB, virtual env layer excluded.

## Use cases

This image is especially useful when you don't yet have in mind a clear idea of the environment requirements you need, but need a reproducible first starting point for a python development environment. It' a quick and easy way to start.

## How to use it

Run the following commmands from the *minimum-poetry* folder. They are just an example of how to use it. You can wrrite your custom commands according to Docker API. For more information about Docker please see the [official documentation](https://docs.docker.com/).

### Build the image

```bash
# This will build the image

TAG="minimum-poetry:0.1.0"
docker build \
-t $TAG \
--build-arg POETRY_VERSION="1.8.3" \
"."
```

### Run the container

```bash
# This will run the container

docker run \
--rm -it \
-v ${PWD}:/app/shared \
"$TAG"
```
18 changes: 18 additions & 0 deletions docker-examples/minimum-poetry/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[tool.poetry]
name = "minimum-poetry"
version = "0.1.0"
description = "A minimum functioning example of Docker image based on Poetry"
authors = ["gianfa <[email protected]>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.9"

numpy = "^2.0.0"
matplotlib = "^3.9.1"
pandas = "^2.2.2"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
1 change: 1 addition & 0 deletions docker-examples/poetry-multistage/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
poetry.lock
38 changes: 38 additions & 0 deletions docker-examples/poetry-multistage/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM python:3.11-slim as builder

# --- Install Poetry ---
ARG POETRY_VERSION=1.8

ENV POETRY_HOME=/opt/poetry
ENV POETRY_NO_INTERACTION=1
ENV POETRY_VIRTUALENVS_IN_PROJECT=1
ENV POETRY_VIRTUALENVS_CREATE=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Tell Poetry where to place its cache and virtual environment
ENV POETRY_CACHE_DIR=/opt/.cache

RUN pip install "poetry==${POETRY_VERSION}"

WORKDIR /app

# --- Reproduce the environment ---
# You can comment the following two lines if you prefer to manually install
# the dependencies from inside the container.
COPY pyproject.toml .
gianfa marked this conversation as resolved.
Show resolved Hide resolved

# Install the dependencies and clear the cache afterwards.
# This may save some MBs.
RUN poetry install --no-root && rm -rf $POETRY_CACHE_DIR

# Now let's build the runtime image from the builder.
# We'll just copy the env and the PATH reference.
FROM python:3.11-slim as runtime

ENV VIRTUAL_ENV=/app/.venv
ENV PATH="/app/.venv/bin:$PATH"

COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}


ENTRYPOINT ["bash"]
38 changes: 38 additions & 0 deletions docker-examples/poetry-multistage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Minimum Poetry multistage image

## Description

poetry-multistage is a minimum-constructible multistage image containing Poetry, from an official Python base image.

Expected size: ~130MB, virtual env layer excluded.

## Use cases

This image is especially useful when ...

## How to use it

Run the following commmands from the *poetry-multistage* folder. They are just an example of how to use it. You can wrrite your custom commands according to Docker API. For more information about Docker please see the [official documentation](https://docs.docker.com/).

### Build the image

```bash
# This will build the image

TAG="poetry-multistage:0.1.0"
docker build \
-t $TAG \
--build-arg POETRY_VERSION="1.8.3" \
"."
```

### Run the container

```bash
# This will run the container

docker run \
--rm -it \
-v ${PWD}:/app/shared \
"$TAG"
```
18 changes: 18 additions & 0 deletions docker-examples/poetry-multistage/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[tool.poetry]
name = "poetry-multistage"
version = "0.1.0"
description = "A minimum functioning example of multistage Docker image based on Poetry"
authors = ["gianfa <[email protected]>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.9"

numpy = "^2.0.0"
matplotlib = "^3.9.1"
pandas = "^2.2.2"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
68 changes: 68 additions & 0 deletions docs/docker-best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: "Docker Best Practices"
draft: false
type: docs
layout: "docs"

menu:
docs:
weight: 130
---

# Docker Best Practices

Poetry is a very valuable tool for increasing the robustness and reproducibility of a virtual environment on which your python code is based. When integrating Poetry into a Docker image, adopting some best practices will help improve build efficiency, container security, and help achieve lighter images. In this section, we will explore best practices for creating optimized and secure Docker images for projects managed with Poetry.
This section is a developing project, so you are warmly invited to contribute new suggestions.

## Best Practices

The following best practices should be kept in mind

- [optional] Set the latest python version, in order to get the latest security patch.
- CAVEAT: It might reduce the reproducibility of the code, between one image build and another, since some function might change from one version of python to another.
- [highly suggested] Use `pip` to install poetry (see [CI recommendations]({{< ref "#ci-recommendations" >}})).
- [highly suggested] Clear Poetry cache after the installation.
- [critical] Never hardcode credentials to private sources.
- [optional] Install Poetry in a dedicated venv
- [highly suggested] Install the virtual env in the Python project (see `POETRY_VIRTUALENVS_IN_PROJECT`). This will be more convenient for carrying the env around with everything you need, making the project more self-contained.
- [highly suggested] Take advantage of Docker's layer caching mechanism to rebuild the image much faster. This means that you should reduce the variability points in the Dockerfile and the files linked to it (e.g. ARGS that may change). In alternative you can move them as far down in the Dockerfile as possible. For more info please see:
- https://docs.docker.com/build/cache/
- https://pythonspeed.com/docker/
- [highly suggested] copy source code only after `poetry install`. For more info see: [FAQ]({{< relref "faq/#poetry-busts-my-docker-cache-because-it-requires-me-to-copy-my-source-files-in-before-installing-3rd-party-dependencies" >}})

## Imags examples and use cases

Below are general examples of Docker images, along with their typical use cases, to help you get started with developing your specific application.

### Minimum-poetry

[Minimum-poetry](https://github.com/gianfa/poetry/tree/docs/docker-best-practices/docker-examples/minimum-poetry/README.md) is the minimum-constructible image containing poetry, from an official python base image.

Expected size: ~218 MB, virtual env layer excluded.

#### Specifics

- Based on *python:3.11-slim* official image.
- Just installs Poetry via pip.
- A basic virtual environment is created passing a pyproject.toml, via build context.

#### Use cases

As in the case of [Minimum-poetry](https://github.com/gianfa/poetry/tree/docs/docker-best-practices/docker-examples/minimum-poetry/README.md), this image is useful when you need to create a virtual self-content environment, complex at will.

### Poetry-multistage

[Poetry-multistage](https://github.com/gianfa/poetry/tree/docs/docker-best-practices/docker-examples/poetry-multistage/README.md) is a minimum-constructible multistage image containing Poetry, from an official Python base image. It is very similar to [Minimum-poetry](#minimum-poetry), except that it may be more complex as it implements at least 2 more best practices.

Expected size: ~130MB, virtual env layer excluded.

#### Specifics

- Based on *python:3.11-slim* official image.
- Installs Poetry via pip.
- A basic virtual environment is created in the project folder (`POETRY_VIRTUALENVS_IN_PROJECT=1`, `POETRY_VIRTUALENVS_CREATE=1`).
- A multistage build is implemented, allowing you to directly copy only the project virtual env and set its reference in path, so as to minimize memory waste.

#### Use cases

The usefulness of this image lies in the Dockerfile that shows an example of how to build a multistage image, to optimize the construction of the virtual environment. Always use it as a starting point for your images that you want to optimize in size.
Loading