Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp Dockerfile #183

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 91 additions & 49 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,66 +1,108 @@
# Dockerfile for uWSGI wrapped Giftless Git LFS Server
# Shared build ARGs among stages
ARG WORKDIR=/app
ARG VENV="$WORKDIR/.venv"

### --- Build Depdendencies ---

FROM python:3.12 as builder
MAINTAINER "Shahar Evron <[email protected]>"

# Build wheels for uWSGI and all requirements
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& apt-get install -y build-essential libpcre3 libpcre3-dev git
RUN pip install -U pip
RUN mkdir /wheels

FROM python:3.12 AS builder
ARG UWSGI_VERSION=2.0.23
RUN pip wheel -w /wheels uwsgi==$UWSGI_VERSION

COPY requirements/main.txt /requirements.txt
RUN pip wheel -w /wheels -r /requirements.txt

### --- Build Final Image ---

FROM python:3.12-slim

RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& apt-get install -y libpcre3 libxml2 tini git \
&& apt-get clean \
&& apt -y autoremove

RUN mkdir /app

# Install dependencies
COPY --from=builder /wheels /wheels
RUN pip install /wheels/*.whl

# Copy project code
COPY . /app
RUN pip install -e /app

ARG USER_NAME=giftless
ARG STORAGE_DIR=/lfs-storage
ENV GIFTLESS_TRANSFER_ADAPTERS_basic_options_storage_options_path $STORAGE_DIR

RUN useradd -d /app $USER_NAME
RUN mkdir $STORAGE_DIR
RUN chown $USER_NAME $STORAGE_DIR

# Pip-install some common WSGI middleware modules
# Common WSGI middleware modules to be pip-installed
# These are not required in every Giftless installation but are common enough
ARG EXTRA_PACKAGES="wsgi_cors_middleware"
# expose shared ARGs
ARG WORKDIR
ARG VENV

# Set WORKDIR (also creates the dir)
WORKDIR $WORKDIR

# Install packages to build wheels for uWSGI and other requirements
RUN set -eux ;\
export DEBIAN_FRONTEND=noninteractive ;\
apt-get update ;\
apt-get install -y --no-install-recommends build-essential libpcre3 libpcre3-dev git ;\
rm -rf /var/lib/apt/lists/*

# Create virtual env to store dependencies, "activate" it
RUN python -m venv --upgrade-deps "$VENV"
ENV VIRTUAL_ENV="$VENV" PATH="$VENV/bin:$PATH"

# Set a couple pip-related settings
# Wait a bit longer for slow connections
ENV PIP_TIMEOUT=100
# Don't nag about newer pip
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
# Don't cache pip packages
ENV PIP_NO_CACHE_DIR=1
# Require activated virtual environment
ENV PIP_REQUIRE_VIRTUALENV=1
# Eventual python cache files go here (not to be copied)
ENV PYTHONPYCACHEPREFIX=/tmp/__pycache__

# Install runtime dependencies
RUN --mount=target=/build-ctx \
pip install -r /build-ctx/requirements/main.txt
RUN pip install uwsgi==$UWSGI_VERSION
# Install extra packages into the virtual env
RUN pip install ${EXTRA_PACKAGES}

WORKDIR /app
# Copy project contents necessary for an editable install
COPY .git .git/
COPY giftless giftless/
COPY pyproject.toml .
# Editable-install the giftless package (add a kind of a project path reference in site-packages)
# To detect the package version dynamically, setuptools-scm needs the git binary
RUN pip install -e .

ENV UWSGI_MODULE "giftless.wsgi_entrypoint"
### --- Build Final Image ---
FROM python:3.12-slim AS final
LABEL org.opencontainers.image.authors="Shahar Evron <[email protected]>"

ARG USER_NAME=giftless
# Writable path for local LFS storage
ARG STORAGE_DIR=/lfs-storage
# Set to true to add a runtime dockerhub deprecation warning
ARG IS_DOCKERHUB
# Override default docker entrypoint for dockerhub
RUN --mount=target=/build-ctx set -e ;\
if [ "$IS_DOCKERHUB" = true ]; then \
cp /build-ctx/scripts/docker-entrypoint-dockerhub.sh scripts/docker-entrypoint.sh ;\
# expose shared ARGs
ARG WORKDIR
ARG VENV

# Set WORKDIR (also creates the dir)
WORKDIR $WORKDIR

# Create a user and set local storage write permissions
RUN set -eux ;\
useradd -d "$WORKDIR" "$USER_NAME" ;\
mkdir "$STORAGE_DIR" ;\
chown "$USER_NAME" "$STORAGE_DIR"

# Install runtime dependencies
RUN set -eux ;\
export DEBIAN_FRONTEND=noninteractive ;\
apt-get update ;\
apt-get install -y libpcre3 libxml2 tini ;\
rm -rf /var/lib/apt/lists/*

# Use the virtual env with dependencies from builder stage
COPY --from=builder "$VENV" "$VENV"
ENV VIRTUAL_ENV="$VENV" PATH="$VENV/bin:$PATH"
# Copy project source back into the same path referenced by the editable install
COPY --from=builder "$WORKDIR/giftless" "giftless"

# Copy desired docker-entrypoint
RUN --mount=target=/build-ctx set -eux ;\
target_de=scripts/docker-entrypoint.sh ;\
mkdir -p "$(dirname "$target_de")" ;\
if [ "${IS_DOCKERHUB:-}" = true ]; then \
cp /build-ctx/scripts/docker-entrypoint-dockerhub.sh "$target_de" ;\
else \
cp /build-ctx/scripts/docker-entrypoint.sh "$target_de" ;\
fi

# Set runtime properties
USER $USER_NAME
ENV GIFTLESS_TRANSFER_ADAPTERS_basic_options_storage_options_path="$STORAGE_DIR"
ENV UWSGI_MODULE="giftless.wsgi_entrypoint"

ENTRYPOINT ["tini", "--", "scripts/docker-entrypoint.sh"]
CMD ["uwsgi", "-s", "127.0.0.1:5000", "-M", "-T", "--threads", "2", "-p", "2", \
Expand Down
4 changes: 1 addition & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,7 @@ urllib3==2.0.7
# responses
# types-requests
uv==0.5.8
# via
# -c requirements/main.txt
# -r requirements/dev.in
# via -r requirements/dev.in
vcrpy==6.0.1
# via pytest-vcr
virtualenv==20.25.1
Expand Down
3 changes: 0 additions & 3 deletions requirements/main.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,4 @@ boto3~=1.34
# GitHub AA Provider
cachetools~=5.3

# uv: fast pip replacement
uv

importlib-metadata; python_version < '3.13'
2 changes: 0 additions & 2 deletions requirements/main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ urllib3==2.0.7
# via
# botocore
# requests
uv==0.5.8
# via -r requirements/main.in
webargs==8.4.0
# via -r requirements/main.in
werkzeug==3.0.3
Expand Down
Loading