Skip to content

Commit d8be023

Browse files
[WIP] ubuntu to distroless dockerfile
1 parent 4d551e9 commit d8be023

File tree

2 files changed

+200
-80
lines changed

2 files changed

+200
-80
lines changed

Dockerfile

Lines changed: 89 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,120 @@
1-
# using ubuntu LTS version
2-
FROM ubuntu:22.04 AS builder-image
1+
# SOURCE: https://github.com/alexdmoss/distroless-python
2+
3+
# several optimisations in python-slim images already, benefit from these
4+
FROM python:3.10.7-slim-bullseye AS builder-image
35

46
# avoid stuck build due to user prompt
57
ARG DEBIAN_FRONTEND=noninteractive
68

7-
RUN apt-get -qq update \
8-
&& apt-get -qq install \
9-
--no-install-recommends -y \
10-
aptitude \
11-
autoconf \
12-
automake \
13-
build-essential \
14-
ca-certificates \
15-
curl \
16-
git \
17-
locales \
18-
libbz2-dev \
19-
libffi-dev \
20-
libncurses-dev \
21-
libreadline-dev \
22-
libsqlite3-dev \
23-
libssl-dev \
24-
libtool \
25-
libxslt-dev \
26-
libyaml-dev \
27-
python3 \
28-
python3-dev \
29-
python3-pip \
30-
sqlite3 \
31-
unixodbc-dev \
32-
unzip \
33-
&& rm -rf /var/lib/apt/lists/*
9+
# setup standard non-root user for use downstream
10+
ARG USERNAME="appuser"
11+
ARG USER_GROUP=${USERNAME}
12+
13+
RUN groupadd ${USER_GROUP}
14+
RUN useradd -m ${USERNAME} -g ${USER_GROUP}
15+
16+
USER ${USERNAME}
17+
ENV HOME="/home/${USERNAME}"
18+
19+
ENV PATH="$HOME/.local/bin:$PATH"
20+
21+
# setup user environment with good python practices
22+
USER ${USERNAME}
23+
WORKDIR /home/${USERNAME}
3424

3525
# Set locale
36-
RUN locale-gen en_US.UTF-8
3726
ENV LANG=en_US.UTF-8
3827
ENV LANGUAGE=en_US:en
3928
ENV LC_ALL=en_US.UTF-8
4029

41-
ARG USERNAME=appuser
30+
# poetry for use elsewhere as builder image
31+
RUN pip install --upgrade pip \
32+
&& pip install --no-cache-dir --upgrade virtualenv poetry
33+
34+
COPY pyproject.toml poetry.lock ./
35+
RUN poetry config virtualenvs.in-project true \
36+
&& poetry install
37+
38+
# build from distroless C or cc:debug, because lots of Python depends on C
39+
FROM gcr.io/distroless/cc AS distroless
40+
41+
# # arch: x86_64-linux-gnu / aarch64-linux-gnu
42+
# ARG CHIPSET_ARCH=aarch64-linux-gnu
43+
44+
# # this carries more risk than installing it fully, but makes the image a lot smaller
45+
# COPY --from=builder-image /usr/local/lib/ /usr/local/lib/
46+
# COPY --from=builder-image /usr/local/bin/python /usr/local/bin/python
47+
# COPY --from=builder-image /etc/ld.so.cache /etc/ld.so.cache
48+
49+
# # required by lots of packages - e.g. six, numpy, wsgi
50+
# COPY --from=builder-image /lib/${CHIPSET_ARCH}/libz.so.1 /lib/${CHIPSET_ARCH}/
51+
52+
# non-root user setup
53+
ARG USERNAME="appuser"
54+
ARG ${PYTHON_VERSION:-3.10}
4255
ENV HOME="/home/${USERNAME}"
43-
ENV PATH="$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
4456

45-
RUN useradd --create-home $USERNAME
57+
COPY --from=builder-image /bin/echo /bin/echo
58+
COPY --from=builder-image /bin/rm /bin/rm
59+
COPY --from=builder-image /bin/sh /bin/sh
4660

47-
# install asdf then python latest
48-
RUN bash -c "git clone --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf \
49-
&& echo '. $HOME/.asdf/asdf.sh' >> $HOME/.bashrc \
50-
&& echo '. $HOME/.asdf/asdf.sh' >> $HOME/.profile"
51-
RUN asdf plugin-add python \
52-
&& asdf install python 3.10.7 \
53-
&& asdf global python 3.10.7
61+
RUN echo "${USERNAME}:x:1000:${USERNAME}" >> /etc/group
62+
RUN echo "${USERNAME}:x:1001:" >> /etc/group
63+
RUN echo "${USERNAME}:x:1000:1001::/home/${USERNAME}:" >> /etc/passwd
5464

55-
# TODO: test poetry via asdf
56-
ENV POETRY_HOME="$HOME/.poetry"
57-
RUN curl -sSL https://install.python-poetry.org | python3.10 -
58-
ENV PATH "${POETRY_HOME}/bin:$PATH"
65+
ENV VENV="/opt/venv"
66+
COPY . /app
67+
COPY --from=builder-image "${HOME}/.venv" "$VENV"
5968

60-
WORKDIR $$HOME/app
61-
COPY pyproject.toml poetry.lock ./
62-
RUN python3.10 -m venv /opt/venv
69+
ENV PATH="/app/.venv/bin:/app/.venv/lib/python${PYTHON_VERSION}/site-packages:$PATH"
6370

64-
# Install pip requirements
65-
RUN . /opt/venv/bin/activate && poetry install
71+
# TODO: QA runner-image before removing shell
72+
# RUN rm /bin/sh /bin/echo /bin/rm
6673

67-
# TODO: dive + docker-slim
68-
FROM ubuntu:22.04 AS runner-image
74+
# default to running as non-root, uid=1000
75+
ARG USERNAME="appuser"
76+
USER ${USERNAME}
6977

70-
ARG USERNAME=appuser
78+
ARG PYTHON_VERSION=3.10
7179
ENV HOME="/home/${USERNAME}"
72-
ENV VIRTUAL_ENV="/opt/venv"
73-
ENV PATH="${VIRTUAL_ENV}/bin:$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
80+
ENV VENV="/opt/venv"
81+
ENV PATH="$HOME/.local/bin:${VENV}/bin:${VENV}/lib/python${PYTHON_VERSION}/site-packages"
7482

75-
RUN useradd --create-home $USERNAME \
76-
&& mkdir -p ${HOME}/app
83+
# TODO: not finding python
84+
# quick validation that python still works whilst we have a shell
85+
RUN python --version
7786

78-
COPY --chown=${USERNAME}:${USERNAME} . $HOME/app
79-
COPY --from=builder-image --chown=${USERNAME}:${USERNAME} /opt/venv /opt/venv
80-
COPY --from=builder-image --chown=${USERNAME}:${USERNAME} $HOME/.asdf $HOME/.asdf
87+
# standardise on locale, don't generate .pyc, enable tracebacks on seg faults
88+
ENV LANG C.UTF-8
89+
ENV LC_ALL C.UTF-8
90+
ENV PYTHONDONTWRITEBYTECODE 1
91+
ENV PYTHONFAULTHANDLER 1
8192

82-
# avoid stuck build due to user prompt
83-
ARG DEBIAN_FRONTEND=noninteractive
93+
# ENTRYPOINT ["/usr/local/bin/python"]
94+
95+
FROM distroless AS runner-image
8496

85-
RUN apt-get -qq update \
86-
&& apt-get -qq install \
87-
--no-install-recommends -y \
88-
ca-certificates \
89-
curl \
90-
git \
91-
libsqlite3-dev \
92-
sqlite3 \
93-
&& rm -rf /var/lib/apt/lists/*
94-
95-
# Keeps Python from generating .pyc files in the container
97+
ARG ${PYTHON_VERSION:-3.10}
98+
ARG USERNAME=appuser
99+
ENV HOME="/home/${USERNAME}"
100+
101+
COPY . /app
102+
COPY --from=distroless "${HOME}/.venv" "${HOME}/.venv"
103+
104+
ENV PATH="$HOME/.local/bin:${HOME}/.venv/lib/python${PYTHON_VERSION}/site-packages"
105+
106+
# keeps Python from generating .pyc files in the container
96107
ENV PYTHONDONTWRITEBYTECODE=1
97108

98-
# Turns off buffering for easier container logging
109+
# turns off buffering for easier container logging
99110
ENV PYTHONUNBUFFERED=1
100111

101-
# activate virtual environment
102-
RUN python -m venv $VIRTUAL_ENV
103-
104-
USER appuser
112+
# workers per core (https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker/blob/master/README.md#web_concurrency)
113+
ENV WEB_CONCURRENCY=1
105114

106-
WORKDIR $HOME/app
115+
WORKDIR /app
107116

108117
# ENTRYPOINT ["python", "main.py"]
109118
# CMD ["gunicorn", "-c", "config/gunicorn.conf.py", "main:app"]
110-
CMD ["/bin/bash", "startup.sh"]
111-
# CMD ["/bin/bash"]
119+
# CMD ["/bin/sh", "startup.sh"]
120+
CMD ["/bin/sh"]

Dockerfile.og

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# using ubuntu LTS version
2+
FROM ubuntu:22.04 AS builder-image
3+
4+
# avoid stuck build due to user prompt
5+
ARG DEBIAN_FRONTEND=noninteractive
6+
7+
RUN apt-get -qq update \
8+
&& apt-get -qq install \
9+
--no-install-recommends -y \
10+
aptitude \
11+
autoconf \
12+
automake \
13+
build-essential \
14+
ca-certificates \
15+
curl \
16+
git \
17+
locales \
18+
libbz2-dev \
19+
libffi-dev \
20+
libncurses-dev \
21+
libreadline-dev \
22+
libsqlite3-dev \
23+
libssl-dev \
24+
libtool \
25+
libxslt-dev \
26+
libyaml-dev \
27+
python3 \
28+
python3-dev \
29+
python3-pip \
30+
sqlite3 \
31+
unixodbc-dev \
32+
unzip \
33+
&& rm -rf /var/lib/apt/lists/*
34+
35+
# Set locale
36+
RUN locale-gen en_US.UTF-8
37+
ENV LANG=en_US.UTF-8
38+
ENV LANGUAGE=en_US:en
39+
ENV LC_ALL=en_US.UTF-8
40+
41+
ARG USERNAME=appuser
42+
ENV HOME="/home/${USERNAME}"
43+
ENV PATH="$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
44+
45+
RUN useradd --create-home $USERNAME
46+
47+
# install asdf then python latest
48+
RUN bash -c "git clone --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf \
49+
&& echo '. $HOME/.asdf/asdf.sh' >> $HOME/.bashrc \
50+
&& echo '. $HOME/.asdf/asdf.sh' >> $HOME/.profile"
51+
RUN asdf plugin-add python \
52+
&& asdf install python 3.10.7 \
53+
&& asdf global python 3.10.7
54+
55+
# TODO: test poetry via asdf
56+
ENV POETRY_HOME="$HOME/.poetry"
57+
RUN curl -sSL https://install.python-poetry.org | python3.10 -
58+
ENV PATH "${POETRY_HOME}/bin:$PATH"
59+
60+
WORKDIR $$HOME/app
61+
COPY pyproject.toml poetry.lock ./
62+
RUN python3.10 -m venv /opt/venv
63+
64+
# Install pip requirements
65+
RUN . /opt/venv/bin/activate && poetry install
66+
67+
# TODO: dive + docker-slim
68+
FROM ubuntu:22.04 AS runner-image
69+
70+
ARG USERNAME=appuser
71+
ENV HOME="/home/${USERNAME}"
72+
ENV VIRTUAL_ENV="/opt/venv"
73+
ENV PATH="${VIRTUAL_ENV}/bin:$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
74+
75+
RUN useradd --create-home $USERNAME \
76+
&& mkdir -p ${HOME}/app
77+
78+
COPY --chown=${USERNAME}:${USERNAME} . $HOME/app
79+
COPY --from=builder-image --chown=${USERNAME}:${USERNAME} /opt/venv /opt/venv
80+
COPY --from=builder-image --chown=${USERNAME}:${USERNAME} $HOME/.asdf $HOME/.asdf
81+
82+
# avoid stuck build due to user prompt
83+
ARG DEBIAN_FRONTEND=noninteractive
84+
85+
RUN apt-get -qq update \
86+
&& apt-get -qq install \
87+
--no-install-recommends -y \
88+
ca-certificates \
89+
curl \
90+
git \
91+
libsqlite3-dev \
92+
sqlite3 \
93+
&& rm -rf /var/lib/apt/lists/*
94+
95+
# Keeps Python from generating .pyc files in the container
96+
ENV PYTHONDONTWRITEBYTECODE=1
97+
98+
# Turns off buffering for easier container logging
99+
ENV PYTHONUNBUFFERED=1
100+
101+
# activate virtual environment
102+
RUN python -m venv $VIRTUAL_ENV
103+
104+
USER appuser
105+
106+
WORKDIR $HOME/app
107+
108+
# ENTRYPOINT ["python", "main.py"]
109+
# CMD ["gunicorn", "-c", "config/gunicorn.conf.py", "main:app"]
110+
CMD ["/bin/bash", "startup.sh"]
111+
# CMD ["/bin/bash"]

0 commit comments

Comments
 (0)