diff --git a/.dockerignore b/.dockerignore
index 123097d..fe71012 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,34 +1,22 @@
-# Remove project files, data, tmp files, build files
-/.env
-/.idea
-/data
-/node_modules
-/tmp
-/docs
-/static
-/scripts
-/build
-/out
-/.git
-/.devcontainer
+# Ignore everything
+*
-/.dockerignore
-/.gitignore
-/.gitattributes
-/Dockerfile
-/docker-compose.yml
-/*.sh
-/*.iml
-/*.patch
-/*.md
-/*.js
-/*.log
-/*.pid
+# Include files required for build or at runtime
+!/bookmarks
+!/siteroot
-# Whitelist files needed in build or prod image
-!/rollup.config.js
-!/bootstrap.sh
!/background-tasks-wrapper.sh
+!/bootstrap.sh
+!/LICENSE.txt
+!/manage.py
+!/package.json
+!/package-lock.json
+!/requirements.prod.txt
+!/requirements.txt
+!/rollup.config.js
+!/supervisord.conf
+!/uwsgi.ini
+!/version.txt
-# Remove development settings
+ # Remove dev settings
/siteroot/settings/dev.py
diff --git a/README.md b/README.md
index 8ce6e75..7ea3475 100644
--- a/README.md
+++ b/README.md
@@ -58,9 +58,27 @@ The name comes from:
linkding is designed to be run with container solutions like [Docker](https://docs.docker.com/get-started/).
The Docker image is compatible with ARM platforms, so it can be run on a Raspberry Pi.
-By default, linkding uses SQLite as a database.
+linkding uses an SQLite database by default.
Alternatively linkding supports PostgreSQL, see the [database options](docs/Options.md#LD_DB_ENGINE) for more information.
+
+
+🧪 Alpine-based image
+
+The default Docker image (`latest` tag) is based on a slim variant of Debian Linux.
+Alternatively, there is an image based on Alpine Linux (`latest-alpine` tag) which has a smaller size, resulting in a smaller download and less disk space required.
+The Alpine image is currently about 45 MB in compressed size, compared to about 130 MB for the Debian image.
+
+To use it, replace the `latest` tag with `latest-alpine`, either in the CLI command below when using Docker, or in the `docker-compose.yml` file when using docker-compose.
+
+> [!WARNING]
+> The image is currently considered experimental in order to gather feedback and iron out any issues.
+> Only use it if you are comfortable running experimental software or want to help out with testing.
+> While there should be no issues with creating new installations, there might be issues when migrating existing installations.
+> If you plan to migrate your existing installation, make sure to create proper [backups](https://github.com/sissbruecker/linkding/blob/master/docs/backup.md) first.
+
+
+
### Using Docker
To install linkding using Docker you can just run the [latest image](https://hub.docker.com/repository/docker/sissbruecker/linkding) from Docker Hub:
diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile
new file mode 100644
index 0000000..e367436
--- /dev/null
+++ b/docker/alpine.Dockerfile
@@ -0,0 +1,89 @@
+FROM node:18.18.0-alpine AS node-build
+WORKDIR /etc/linkding
+# install build dependencies
+COPY rollup.config.js package.json package-lock.json ./
+RUN npm install
+# copy files needed for JS build
+COPY bookmarks/frontend ./bookmarks/frontend
+# run build
+RUN npm run build
+
+
+FROM python:3.10.13-alpine3.18 AS python-base
+RUN apk update && apk add alpine-sdk linux-headers libpq-dev pkgconfig icu-dev sqlite-dev
+WORKDIR /etc/linkding
+
+
+FROM python-base AS python-build
+# install build dependencies
+COPY requirements.txt requirements.txt
+# remove playwright from requirements as there is not always a distro and it's not needed for the build
+RUN sed -i '/playwright/d' requirements.txt
+RUN pip install -U pip && pip install -Ur requirements.txt
+# copy files needed for Django build
+COPY . .
+COPY --from=node-build /etc/linkding .
+# run Django part of the build
+RUN python manage.py compilescss && \
+ python manage.py collectstatic --ignore=*.scss && \
+ python manage.py compilescss --delete-files
+
+
+FROM python-base AS prod-deps
+COPY requirements.prod.txt ./requirements.txt
+RUN mkdir /opt/venv && \
+ python -m venv --upgrade-deps --copies /opt/venv && \
+ /opt/venv/bin/pip install --upgrade pip wheel && \
+ /opt/venv/bin/pip install -Ur requirements.txt
+
+
+FROM python-base 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
+# extension do not change
+ARG SQLITE_RELEASE_YEAR=2023
+ARG SQLITE_RELEASE=3430000
+
+# Compile the ICU extension needed for case-insensitive search and ordering
+# with SQLite. This does:
+# - Download SQLite amalgamation for header files
+# - Download ICU extension source file
+# - Compile ICU extension
+RUN wget https://www.sqlite.org/${SQLITE_RELEASE_YEAR}/sqlite-amalgamation-${SQLITE_RELEASE}.zip && \
+ unzip sqlite-amalgamation-${SQLITE_RELEASE}.zip && \
+ cp sqlite-amalgamation-${SQLITE_RELEASE}/sqlite3.h ./sqlite3.h && \
+ cp sqlite-amalgamation-${SQLITE_RELEASE}/sqlite3ext.h ./sqlite3ext.h && \
+ wget https://www.sqlite.org/src/raw/ext/icu/icu.c?name=91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60 -O icu.c && \
+ gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-uc icu-io` -o libicu.so
+
+
+FROM python:3.10.13-alpine3.18 AS final
+# install runtime dependencies
+RUN apk update && apk add bash curl icu libpq mailcap
+# create www-data user and group
+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 compiled icu extension
+COPY --from=compile-icu /etc/linkding/libicu.so libicu.so
+# copy application code
+COPY . .
+# 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
+
+HEALTHCHECK --interval=30s --retries=3 --timeout=1s \
+CMD curl -f http://localhost:${LD_SERVER_PORT:-9090}/${LD_CONTEXT_PATH}health || exit 1
+
+CMD ["./bootstrap.sh"]
diff --git a/Dockerfile b/docker/default.Dockerfile
similarity index 89%
rename from Dockerfile
rename to docker/default.Dockerfile
index 8f2111b..88ceb0d 100644
--- a/Dockerfile
+++ b/docker/default.Dockerfile
@@ -1,11 +1,11 @@
FROM node:18.18.0-alpine AS node-build
WORKDIR /etc/linkding
# install build dependencies
-COPY package.json package-lock.json ./
-RUN npm install -g npm && \
- npm install
-# compile JS components
-COPY . .
+COPY rollup.config.js package.json package-lock.json ./
+RUN npm install
+# copy files needed for JS build
+COPY bookmarks/frontend ./bookmarks/frontend
+# run build
RUN npm run build
@@ -17,9 +17,13 @@ WORKDIR /etc/linkding
FROM python-base AS python-build
# install build dependencies
COPY requirements.txt requirements.txt
+# remove playwright from requirements as there is not always a distro and it's not needed for the build
+RUN sed -i '/playwright/d' requirements.txt
RUN pip install -U pip && pip install -Ur requirements.txt
-# run Django part of the build
+# copy files needed for Django build
+COPY . .
COPY --from=node-build /etc/linkding .
+# run Django part of the build
RUN python manage.py compilescss && \
python manage.py collectstatic --ignore=*.scss && \
python manage.py compilescss --delete-files
diff --git a/scripts/build-docker.sh b/scripts/build-docker.sh
index dc0dbac..9311dac 100755
--- a/scripts/build-docker.sh
+++ b/scripts/build-docker.sh
@@ -3,6 +3,13 @@
version=$(