A Docker for your python scripts

Yes, I know. I did say - somewhere on this blog - that I was podman all the way, baby.

I lied.

Anyways. I needed to deploy a script onto an older server where manually installing python > 3.11 just was too much hassle. I did have docker tho.

First, the Dockerfile

FROM python:3.11
RUN apt-get update && apt-get install -y \
curl

WORKDIR /usr/src/myapp
ADD src ./src
ADD logs ./logs

COPY .env .
COPY poetry.lock .
COPY pyproject.toml .

RUN curl -sSL https://install.python-poetry.org | python3
ENV PATH="/root/.local/bin:$PATH"
RUN poetry install --only main

Nothing much happening here. We install curl in the image just to be sure. It's probably there already and we do install poetry and add it to the PATH.

The docker-compose.yml

version: '3'
services:
    mymagnificentapp:
        container_name: myapp
        env_file: .env
        build: .
        volumes:
            - ./logs:/usr/src/myapp/logs
            - ./src:/usr/src/myapp/src
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro

We mount both the logs and the src directory. This is afaik the only way to get persistent logs w/o using external logging facilities. We mount the src directory so we can make configuration changes between runs.

The Makefile

CMD := $1

build:
   docker-compose -f docker-compose.yml build $(c)

firstcmd:
   docker-compose -f docker-compose.yml run mymagnificentapp poetry run src/main1.py

secondcmd:
   docker-compose -f docker-compose.yml run mymagnificentapp poetry run src/main2.py

Executing make from the command line will build the app. Executing make firstcmd will run the defined command.

However, you might get a permission error if you, like me, have made a habit of forgetting to add the #SHEBANG to your main.py files.

#! /usr/bin/env python3
"""My magnificent main."""

def main():
    ...

if __name__ == "__main__":
    main()

That's it. You have a semi-isolated python 3.11 environment in which to run scripts.