Location>code7788 >text

Using pdm to manage dependencies in the docker image of a python project

Popularity:948 ℃/2024-08-11 22:35:48

preamble

In the DjangoStarter project, I've used pdm as the default package manager, instead of using pip directly.

So the dockerfile and docker-compose configurations will have to be changed when deploying.

dockerfile

First, make a change to the dockerfile

ARG PYTHON_BASE=3.11

FROM python:$PYTHON_BASE

# Set python environment variables
ENV PYTHONUNBUFFERED=1
# Disable update checking
ENV PDM_CHECK_UPDATE=false

# Set domestic sources
RUN pip config set -url /pypi/simple/ && \
    # Install pdm
    pip install -U pdm && \
    # Configure the image
    pdm config "/pypi/simple/"

# Copy the files
COPY /project/
COPY . /project/

# Install dependencies and projects to the local package directory
WORKDIR /project
RUN pdm install --check --prod --no-editable && \
    pip install uwsgi

ENV PATH="/project/.venv/bin:$PATH"

Here are a few things to keep in mind:

  • If you want to use uwsgi, you have to use a Python image without slim, because uwsgi compilation depends on gcc, and slim images do not have a
  • pdm creates a virtual environment by default, but since it's in a docker image, you don't need one, so you can use thepdm config python.use_venv false Configuring a Disabled Virtual Environment
  • The last line of the environment variable configuration is very important, you must add the virtual environment created by pdm to the PATH, and then execute it in compose in order to use the correct environment.

docker-compose configuration

The usual rules apply, first the configuration, then the notes follow.

services:
  redis:
    image: redis
    restart: unless-stopped
    container_name: $APP_NAME-redis
    expose:
      - 6379
    networks:
      - default
  web:
    container_name: $APP_NAME
    restart: always
    build: .
    environment:
      - ENVIRONMENT=docker
      - URL_PREFIX=
      - DEBUG=true
    command: pdm run ./src/ runserver 0.0.0.0:8000
    # command: uwsgi 
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - redis
    networks:
      - default
      - swag

networks:
  default:
    name: $APP_NAME
  swag:
    external: true

Attention:

  • The new version of compose does not require the version number of the configuration file anymore, so the first line of version can be removed.
  • All containers are added container_name configuration, where the container name is placed in the environment variable configuration, my solution is to create the root directory in the.env file to hold environment variables. They can also be specified on the command line.
  • The network name also follows the environment variableAPP_NAME Come on, ditto on that point.
  • Here the entry command is changed topdm run ./src/ runserver 0.0.0.0:8000 Usepdm run Virtual environments can be enabled automatically.
  • The uwsgi version can be used, but the configuration in this compose does not come with an NGINX container, and after the whole project is started, the swag is also a container, and the static files in the project are not handled well there. So you still need to bring a lightweight web server like NGINX or candy in compose (actually NGINX is very light).

wrap-up

That's it. Just a few details.

That said, pdm is a lot smoother to use than poetry, and I haven't encountered any weird problems using it in docker, so I'm glad to hear it 👍

bibliography

  • /zh-cn/latest/usage/advanced/#dockerfile-pdm