-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDockerfile
83 lines (68 loc) · 2.69 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# syntax=docker/dockerfile:1.9
FROM python:3.12 AS build
# The following does not work in Podman unless you build in Docker
# compatibility mode: <https://github.com/containers/podman/issues/8477>
# You can manually prepend every RUN script with `set -ex` too.
SHELL ["sh", "-exc"]
# Security-conscious organizations should package/review uv themselves.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# - Silence uv complaining about not being able to use hard links,
# - tell uv to byte-compile packages for faster application startups,
# - prevent uv from accidentally downloading isolated Python builds,
# - pick a Python,
# - and finally declare `/app` as the target for `uv sync`.
ENV UV_LINK_MODE=copy \
UV_COMPILE_BYTECODE=1 \
UV_PYTHON_DOWNLOADS=never \
UV_PYTHON=python3.12 \
UV_PROJECT_ENVIRONMENT=/app
### End Build Prep -- this is where your Dockerfile should start.
# Since there's no point in shipping lock files, we move them
# into a directory that is NOT copied into the runtime image.
# The trailing slash makes COPY create `/_lock/` automagically.
COPY pyproject.toml /_lock/
COPY uv.lock /_lock/
# Synchronize DEPENDENCIES without the application itself.
# This layer is cached until uv.lock or pyproject.toml change.
# You can create `/app` using `uv venv` in a separate `RUN`
# step to have it cached, but with uv it's so fast, it's not worth
# it and we let `uv sync` create it for us automagically.
RUN --mount=type=cache,target=/root/.cache <<EOT
ls /
cd /_lock
uv sync \
--frozen \
--no-dev \
--no-install-project
EOT
# Now install the APPLICATION from `/src` without any dependencies.
# `/src` will NOT be copied into the runtime container.
# LEAVE THIS OUT if your application is NOT a proper Python package.
COPY . /src
RUN --mount=type=cache,target=/root/.cache \
uv pip install \
--python=$UV_PROJECT_ENVIRONMENT \
--no-deps \
/src
##########################################################################
FROM python:3.12
SHELL ["sh", "-exc"]
# Optional: add the application virtualenv to search path.
ENV PATH=/app/bin:$PATH
# Don't run your app as root.
RUN adduser --system --no-create-home app
ENTRYPOINT ["python3", "-m", "ocpp_mqtt_bridge"]
# See <https://hynek.me/articles/docker-signals/>.
STOPSIGNAL SIGINT
# Copy the pre-built `/app` directory to the runtime container
# and change the ownership to user app and group app in one step.
COPY --from=build --chown=app:app /app /app
COPY logging_config.toml /app/
USER app
WORKDIR /app
# Strictly optional, but I like it for introspection of what I've built
# and run a smoke test that the application can, in fact, be imported.
RUN <<EOT
python -V
python -Ic 'import ocpp_mqtt_bridge'
EOT