-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
88 lines (74 loc) · 3.17 KB
/
Copy pathDockerfile
File metadata and controls
88 lines (74 loc) · 3.17 KB
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
84
85
86
87
88
###########################################################
# Container that contains basic configurations used by all other containers
# It should only contain variables that don't change or change very infrequently
# so that the cache is not needlessly invalidated
FROM python:3.14-slim-trixie AS base
ENV USER=swissgeo
ENV GROUP=swissgeo
ENV INSTALL_DIR=/opt/service-drawings
RUN apt-get -qq update > /dev/null \
&& apt-get -qq clean \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd -r ${GROUP} \
&& useradd -r -s /bin/false -g ${GROUP} ${USER}
###########################################################
# Builder container
FROM base AS builder
COPY --from=ghcr.io/astral-sh/uv:0.11.4 /uv /uvx /bin/
# Enable bytecode compilation
ENV UV_COMPILE_BYTECODE=1
# Copy from the cache instead of linking since it's a mounted volume
ENV UV_LINK_MODE=copy
# Omit development dependencies
ENV UV_NO_DEV=1
# Ensure installed tools can be executed out of the box
ENV UV_TOOL_BIN_DIR=/usr/local/bin
# Disable Python downloads, because we want to use the system interpreter
# across both images. If using a managed Python version, it needs to be
# copied from the build image into the final image; see `standalone.Dockerfile`
# for an example.
ENV UV_PYTHON_DOWNLOADS=0
# Install all the dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked
COPY --chown=${USER}:${GROUP} app/ ${INSTALL_DIR}/app/
###########################################################
# Container to use in production
FROM base AS production
LABEL target=production
# Install the .venv at the root because this is expected by fastapi script
COPY --from=builder .venv/ /.venv/
COPY --from=builder ${INSTALL_DIR}/ ${INSTALL_DIR}/
# Activate virtual environment
ENV VIRTUAL_ENV=/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
ENV PYTHONHOME=""
# Overwrite the version.py from source with the actual version
ARG VERSION=unknown
RUN echo "__version__ = '$VERSION'" > ${INSTALL_DIR}/app/version.py
ARG GIT_HASH=unknown
ARG GIT_BRANCH=unknown
ARG GIT_DIRTY=""
ARG AUTHOR=unknown
LABEL git.hash=$GIT_HASH
LABEL git.branch=$GIT_BRANCH
LABEL git.dirty=$GIT_DIRTY
LABEL author=$AUTHOR
LABEL version=$VERSION
# production container must not run as root
WORKDIR ${INSTALL_DIR}/
USER ${USER}
# expose the default port of uvicorn
EXPOSE 8000
# Here we use uvicorn directly in order to configure its logging configuration file
# This can be done by using the CMD arg during docker run.
#
# --proxy-headers alone is not enough: it only enables the middleware, while
# --forwarded-allow-ips declares which peers may set X-Forwarded-*. It defaults to
# 127.0.0.1, but behind the ALB the peer is the load balancer's private IP, so the
# default silently drops X-Forwarded-Proto and every generated URL comes out as http.
# '*' is safe only because the task's security group accepts traffic from the ALB
# security group only; if that ever changes, pin the VPC CIDR here instead.
ENTRYPOINT ["uvicorn", "app.main:app", "--proxy-headers", "--forwarded-allow-ips", "*", "--host", "0.0.0.0", "--loop", "uvloop", "--http", "httptools"]