152 lines
3.7 KiB
Docker
152 lines
3.7 KiB
Docker
FROM docker.io/python:3.12-slim AS base
|
|
|
|
ENV \
|
|
LANG=C.UTF-8 \
|
|
LC_ALL=C.UTF-8 \
|
|
# python:
|
|
PYTHONFAULTHANDLER=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONHASHSEED=random \
|
|
PYTHONDONTWRITEBYTECODE=1
|
|
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
libmagic1 \
|
|
libpq5 \
|
|
libjpeg62-turbo \
|
|
libfreetype6 \
|
|
zlib1g \
|
|
gettext \
|
|
procps \
|
|
curl \
|
|
postgresql-client \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
ENV VIRTUAL_ENV=/venv
|
|
|
|
# Use production configuration.
|
|
ENV DJANGO_SETTINGS_MODULE=publichealth.settings.production
|
|
ENV DJANGO_CONFIGURATION=production
|
|
|
|
|
|
|
|
## Build frontend
|
|
|
|
FROM docker.io/node:18-slim AS frontend-builder
|
|
|
|
RUN mkdir -p /build
|
|
WORKDIR /build
|
|
|
|
# Install grunt-cli
|
|
RUN npm install -g grunt-cli
|
|
|
|
# Copy package files and pre-installed node_modules
|
|
COPY package.json package-lock.json Gruntfile.js ./
|
|
# Copy node_modules if they exist locally (avoids git clone issues)
|
|
COPY node_modules ./node_modules
|
|
|
|
# Copy static assets and libs
|
|
COPY publichealth/static/ ./publichealth/static/
|
|
RUN mkdir -p publichealth/static/libs && \
|
|
cp -r node_modules/@bower_components/* publichealth/static/libs/
|
|
|
|
# Build frontend assets (skip grunt if it fails, assets will be compiled at runtime)
|
|
RUN grunt || echo "Grunt build skipped, will use django-compressor at runtime"
|
|
|
|
|
|
|
|
## Build backend
|
|
|
|
FROM base AS backend-builder
|
|
|
|
ENV \
|
|
# pip:
|
|
PIP_NO_CACHE_DIR=off \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
|
PIP_DEFAULT_TIMEOUT=100
|
|
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
gcc \
|
|
libmagic-dev \
|
|
libpq-dev \
|
|
libjpeg-dev \
|
|
libfreetype6-dev \
|
|
zlib1g-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install python build tools.
|
|
RUN pip install --upgrade pip wheel
|
|
RUN python3 -m venv $VIRTUAL_ENV
|
|
|
|
RUN mkdir -p /build
|
|
WORKDIR /build
|
|
|
|
# Install python dependencies.
|
|
COPY requirements.txt .
|
|
RUN . /venv/bin/activate && pip install -r requirements.txt
|
|
# We will run dumb-init as pid 1.
|
|
RUN . /venv/bin/activate && pip install dumb-init
|
|
# We will run our app using gunicorn.
|
|
RUN . /venv/bin/activate && pip install gunicorn
|
|
# Install django-libsass for SASS compilation
|
|
RUN . /venv/bin/activate && pip install django-libsass
|
|
|
|
# Copy our own code into to the build image.
|
|
# WARNING: use .dockerignore file to exclude unwanted files
|
|
COPY . /build/
|
|
|
|
# Copy javascript assets from frontend builder
|
|
COPY --from=frontend-builder /build/publichealth/static /build/publichealth/static
|
|
|
|
# Remove problematic gh-pages folder from slick-lightbox
|
|
RUN rm -rf /build/publichealth/static/libs/slick-lightbox/gh-pages
|
|
|
|
# Copy code required for runtime to the /app folder.
|
|
RUN mkdir /app
|
|
|
|
# Collect static data into /app/static.
|
|
RUN . /venv/bin/activate && \
|
|
SECRET_KEY=dummy \
|
|
STATIC_DIR=/app/static ./manage.py collectstatic --no-input
|
|
|
|
# Compress static files offline (required for COMPRESS_OFFLINE=True in production).
|
|
RUN . /venv/bin/activate && \
|
|
SECRET_KEY=dummy \
|
|
STATIC_DIR=/app/static \
|
|
./manage.py compress --force
|
|
|
|
# Compile messages if locale directory exists
|
|
RUN if [ -d "locale" ]; then \
|
|
. /venv/bin/activate && \
|
|
SECRET_KEY=dummy \
|
|
./manage.py compilemessages; \
|
|
fi
|
|
|
|
# Copy application code to /app
|
|
RUN cp -r publichealth feedler manage.py /app/
|
|
RUN if [ -d "locale" ]; then cp -r locale /app/; fi
|
|
|
|
RUN ls -al /app/
|
|
|
|
|
|
|
|
### runtime image
|
|
|
|
FROM base AS runtime
|
|
|
|
COPY --from=backend-builder /venv /venv
|
|
COPY --from=backend-builder /app /app
|
|
|
|
RUN groupadd --gid 1001 app \
|
|
&& useradd --home-dir /app --shell /bin/bash --gid app --uid 1001 app \
|
|
&& chown -R app:app /app
|
|
USER app
|
|
WORKDIR /app
|
|
|
|
# Ensure exectutables from virtualenv are prefered.
|
|
ENV PATH="/venv/bin:$PATH"
|
|
|
|
ADD entrypoint /entrypoint
|
|
ENTRYPOINT ["/entrypoint"]
|