Skip to content

Commit

Permalink
Simplify Docker build (#865)
Browse files Browse the repository at this point in the history
  • Loading branch information
sissbruecker authored Sep 28, 2024
1 parent 791a5c7 commit d4c348c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 66 deletions.
42 changes: 15 additions & 27 deletions docker/alpine.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18-alpine AS node-build
FROM node:20-alpine AS node-build
WORKDIR /etc/linkding
# install build dependencies
COPY rollup.config.mjs postcss.config.js package.json package-lock.json ./
Expand All @@ -10,32 +10,16 @@ COPY bookmarks/styles ./bookmarks/styles
RUN npm run build


FROM python:3.12.6-alpine3.20 AS python-base
FROM python:3.12.6-alpine3.20 AS build-deps
# Add required packages
# alpine-sdk linux-headers pkgconfig: build Python packages from source
# libpq-dev: build Postgres client from source
# icu-dev sqlite-dev: build Sqlite ICU extension
# libffi-dev openssl-dev rust cargo: build Python cryptography from source
RUN apk update && apk add alpine-sdk linux-headers libpq-dev pkgconfig icu-dev sqlite-dev libffi-dev openssl-dev rust cargo
WORKDIR /etc/linkding


FROM python-base AS python-build
# install build dependencies
# install python dependencies
COPY requirements.txt requirements.txt
RUN pip install -U pip && pip install -r requirements.txt
# copy files needed for Django build
COPY . .
COPY --from=node-build /etc/linkding .
# remove style sources
RUN rm -rf bookmarks/styles
# run Django part of the build
RUN mkdir data && \
python manage.py collectstatic


FROM python-base AS prod-deps
COPY requirements.txt ./requirements.txt
# Need to build psycopg2 from source for ARM platforms
RUN sed -i 's/psycopg2-binary/psycopg2/g' requirements.txt
RUN mkdir /opt/venv && \
Expand All @@ -44,7 +28,7 @@ RUN mkdir /opt/venv && \
/opt/venv/bin/pip install -r requirements.txt


FROM python-base AS compile-icu
FROM build-deps AS compile-icu
# Defines SQLite version
# Since this is only needed for downloading the header files this probably
# doesn't need to be up-to-date, assuming the SQLite APIs used by the ICU
Expand Down Expand Up @@ -74,19 +58,23 @@ RUN set -x ; \
addgroup -g 82 -S www-data ; \
adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1
WORKDIR /etc/linkding
# copy prod dependencies
COPY --from=prod-deps /opt/venv /opt/venv
# copy output from build stage
COPY --from=python-build /etc/linkding/static static/
# copy python dependencies
COPY --from=build-deps /opt/venv /opt/venv
# copy output from node build
COPY --from=node-build /etc/linkding/bookmarks/static bookmarks/static/
# copy compiled icu extension
COPY --from=compile-icu /etc/linkding/libicu.so libicu.so
# copy application code
COPY . .
# Activate virtual env
ENV VIRTUAL_ENV=/opt/venv
ENV PATH=/opt/venv/bin:$PATH
# Generate static files, remove source styles that are not needed
RUN mkdir data && \
python manage.py collectstatic

# Expose uwsgi server at port 9090
EXPOSE 9090
# Activate virtual env
ENV VIRTUAL_ENV /opt/venv
ENV PATH /opt/venv/bin:$PATH
# Allow running containers as an an arbitrary user in the root group, to support deployment scenarios like OpenShift, Podman
RUN chmod g+w . && \
chmod +x ./bootstrap.sh
Expand Down
50 changes: 19 additions & 31 deletions docker/default.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18-alpine AS node-build
FROM node:20-alpine AS node-build
WORKDIR /etc/linkding
# install build dependencies
COPY rollup.config.mjs postcss.config.js package.json package-lock.json ./
Expand All @@ -10,7 +10,7 @@ COPY bookmarks/styles ./bookmarks/styles
RUN npm run build


FROM python:3.12.6-slim-bookworm AS python-base
FROM python:3.12.6-slim-bookworm AS build-deps
# Add required packages
# build-essential pkg-config: build Python packages from source
# libpq-dev: build Postgres client from source
Expand All @@ -20,24 +20,8 @@ RUN apt-get update && apt-get -y install build-essential pkg-config libpq-dev li
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
WORKDIR /etc/linkding


FROM python-base AS python-build
# install build dependencies
# install python dependencies
COPY requirements.txt requirements.txt
RUN pip install -U pip && pip install -r requirements.txt
# copy files needed for Django build
COPY . .
COPY --from=node-build /etc/linkding .
# remove style sources
RUN rm -rf bookmarks/styles
# run Django part of the build
RUN mkdir data && \
python manage.py collectstatic


FROM python-base AS prod-deps
COPY requirements.txt ./requirements.txt
# Need to build psycopg2 from source for ARM platforms
RUN sed -i 's/psycopg2-binary/psycopg2/g' requirements.txt
RUN mkdir /opt/venv && \
Expand All @@ -46,7 +30,7 @@ RUN mkdir /opt/venv && \
/opt/venv/bin/pip install -r requirements.txt


FROM python-base AS compile-icu
FROM build-deps AS compile-icu
# Defines SQLite version
# Since this is only needed for downloading the header files this probably
# doesn't need to be up-to-date, assuming the SQLite APIs used by the ICU
Expand All @@ -67,27 +51,31 @@ RUN wget https://www.sqlite.org/${SQLITE_RELEASE_YEAR}/sqlite-amalgamation-${SQL
gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-uc icu-io` -o libicu.so


FROM python:3.12.6-slim-bookworm as linkding
FROM python:3.12.6-slim-bookworm AS linkding
LABEL org.opencontainers.image.source="https://github.com/sissbruecker/linkding"
# install runtime dependencies
RUN apt-get update && apt-get -y install mime-support libpq-dev libicu-dev libssl3 curl
WORKDIR /etc/linkding
# copy prod dependencies
COPY --from=prod-deps /opt/venv /opt/venv
# copy output from build stage
COPY --from=python-build /etc/linkding/static static/
# copy python dependencies
COPY --from=build-deps /opt/venv /opt/venv
# copy output from node build
COPY --from=node-build /etc/linkding/bookmarks/static bookmarks/static/
# copy compiled icu extension
COPY --from=compile-icu /etc/linkding/libicu.so libicu.so
# copy application code
COPY . .
# Activate virtual env
ENV VIRTUAL_ENV=/opt/venv
ENV PATH=/opt/venv/bin:$PATH
# Generate static files
RUN mkdir data && \
python manage.py collectstatic

# Expose uwsgi server at port 9090
EXPOSE 9090
# Activate virtual env
ENV VIRTUAL_ENV /opt/venv
ENV PATH /opt/venv/bin:$PATH
# Allow running containers as an an arbitrary user in the root group, to support deployment scenarios like OpenShift, Podman
RUN ["chmod", "g+w", "."]
# Run bootstrap logic
RUN ["chmod", "+x", "./bootstrap.sh"]
RUN chmod g+w . && \
chmod +x ./bootstrap.sh

HEALTHCHECK --interval=30s --retries=3 --timeout=1s \
CMD curl -f http://localhost:${LD_SERVER_PORT:-9090}/${LD_CONTEXT_PATH}health || exit 1
Expand Down
8 changes: 0 additions & 8 deletions siteroot/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,6 @@
# Collect static files in static folder
STATIC_ROOT = os.path.join(BASE_DIR, "static")

STATICFILES_DIRS = [
# Resolve theme files from style source folder
os.path.join(BASE_DIR, "bookmarks", "styles"),
# Resolve downloaded files in dev environment
os.path.join(BASE_DIR, "data", "favicons"),
os.path.join(BASE_DIR, "data", "previews"),
]

# REST framework
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
Expand Down
8 changes: 8 additions & 0 deletions siteroot/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
# Allow access through ngrok
CSRF_TRUSTED_ORIGINS = ["https://*.ngrok-free.app"]

STATICFILES_DIRS = [
# Resolve theme files from style source folder
os.path.join(BASE_DIR, "bookmarks", "styles"),
# Resolve downloaded files in dev environment
os.path.join(BASE_DIR, "data", "favicons"),
os.path.join(BASE_DIR, "data", "previews"),
]

# Enable debug logging
LOGGING = {
"version": 1,
Expand Down

0 comments on commit d4c348c

Please sign in to comment.