mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 06:46:00 +00:00
The `production-stage` stage was depending on the `python3` package from Alpine, which at the moment of writing is still Python 3.12. To avoid relying on Alpine's package and releases, we now copy the Python installation directly from its official Docker image. Other options were tested but did not work: - Trying to install Python 3.13 using `apk`. As mentioned, Alpine does not support Python 3.13 yet. - Installing Python 3.13 using `pyenv`. The installation worked, but the generated image was too large. Related `pyenv` discussion: https://github.com/orgs/pyenv/discussions/2868 - Installing Python 3.13 using `uv`. Only worked for `amd64` architecture, but the installation failed on `arm64`.
211 lines
6.9 KiB
Docker
211 lines
6.9 KiB
Docker
# Stages:
|
|
# - frontend-build: Build frontend
|
|
# - backend-build: Build backend environment
|
|
# - backend-dev-build: Similar to `backend-build`, but also compiles and installs development dependencies
|
|
# - rahasher-build: Build RAHasher
|
|
# - emulator-stage: Fetch and extract emulators
|
|
# - nginx-build: Build nginx modules
|
|
# - production-stage: Setup frontend and backend
|
|
# - slim-image: Slim image with only the necessary files
|
|
# - full-image: Full image with emulator stage
|
|
# - dev-slim: Slim image with development dependencies
|
|
# - dev-full: Full image with emulator stage and development dependencies
|
|
|
|
# Versions:
|
|
ARG ALPINE_VERSION=3.22
|
|
ARG NGINX_VERSION=1.29.0
|
|
ARG NODE_VERSION=20.19
|
|
ARG PYTHON_VERSION=3.13
|
|
|
|
# Alias stages:
|
|
FROM python:${PYTHON_VERSION}-alpine${ALPINE_VERSION} AS python-alias
|
|
|
|
|
|
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS frontend-build
|
|
WORKDIR /front
|
|
|
|
COPY ./frontend/package*.json ./
|
|
RUN npm ci
|
|
|
|
COPY ./frontend ./
|
|
RUN npm run build
|
|
|
|
|
|
FROM python-alias AS backend-build
|
|
|
|
# git is needed to install streaming-form-data fork
|
|
# linux-headers is needed to install py7zr
|
|
# libpq-dev is needed to build psycopg-c
|
|
# mariadb-connector-c-dev is needed to build mariadb-connector
|
|
RUN apk add --no-cache \
|
|
gcc \
|
|
git \
|
|
linux-headers \
|
|
libpq-dev \
|
|
mariadb-connector-c-dev \
|
|
musl-dev
|
|
|
|
COPY --from=ghcr.io/astral-sh/uv:0.7.19 /uv /uvx /bin/
|
|
|
|
WORKDIR /src
|
|
|
|
COPY ./pyproject.toml ./uv.lock /src/
|
|
RUN uv sync --locked --no-cache
|
|
|
|
|
|
FROM backend-build AS backend-dev-build
|
|
|
|
RUN uv sync --locked --no-cache --all-extras
|
|
|
|
|
|
FROM alpine:${ALPINE_VERSION} AS rahasher-build
|
|
|
|
RUN apk add --no-cache \
|
|
g++ \
|
|
git \
|
|
linux-headers \
|
|
make \
|
|
zlib-dev
|
|
|
|
ARG RALIBRETRO_VERSION=1.8.1
|
|
|
|
# TODO: Remove `sed` command adding "ctime", when RAHasher can be compiled without it.
|
|
# TODO: Remove `sed` command adding "unistd.h", when RAHasher can be compiled without it.
|
|
# Related pull request: https://github.com/madler/zlib/pull/1022
|
|
RUN git clone --recursive --branch "${RALIBRETRO_VERSION}" --depth 1 https://github.com/RetroAchievements/RALibretro.git && \
|
|
cd ./RALibretro && \
|
|
sed -i '22a #include <ctime>' ./src/Util.h && \
|
|
sed -i '6a #include <unistd.h>' \
|
|
./src/libchdr/deps/zlib-1.3.1/gzlib.c \
|
|
./src/libchdr/deps/zlib-1.3.1/gzread.c \
|
|
./src/libchdr/deps/zlib-1.3.1/gzwrite.c && \
|
|
make HAVE_CHD=1 -f ./Makefile.RAHasher
|
|
|
|
|
|
FROM alpine:${ALPINE_VERSION} AS emulator-stage
|
|
|
|
RUN apk add --no-cache \
|
|
7zip \
|
|
wget
|
|
|
|
ARG EMULATORJS_VERSION=4.2.3
|
|
RUN wget "https://github.com/EmulatorJS/EmulatorJS/releases/download/v${EMULATORJS_VERSION}/${EMULATORJS_VERSION}.7z" && \
|
|
7z x -y "${EMULATORJS_VERSION}.7z" -o/emulatorjs && \
|
|
rm -rf "${EMULATORJS_VERSION}.7z";
|
|
|
|
ARG RUFFLE_VERSION=nightly-2024-12-28
|
|
ARG RUFFLE_FILE=ruffle-nightly-2024_12_28-web-selfhosted.zip
|
|
RUN wget "https://github.com/ruffle-rs/ruffle/releases/download/${RUFFLE_VERSION}/${RUFFLE_FILE}" && \
|
|
unzip -o "${RUFFLE_FILE}" -d /ruffle && \
|
|
rm -f "${RUFFLE_FILE}";
|
|
|
|
FROM alpine:${ALPINE_VERSION} AS nginx-build
|
|
|
|
RUN apk add --no-cache \
|
|
gcc \
|
|
git \
|
|
libc-dev \
|
|
make \
|
|
pcre-dev \
|
|
zlib-dev
|
|
|
|
ARG NGINX_VERSION
|
|
# The specified commit SHA is the latest commit on the `master` branch at the time of writing.
|
|
# It includes a fix to correctly calculate CRC-32 checksums when using upstream subrequests.
|
|
# TODO: Move to a tagged release of `mod_zip`, once a version newer than 1.3.0 is released.
|
|
ARG NGINX_MOD_ZIP_SHA=8e65b82c82c7890f67a6107271c127e9881b6313
|
|
|
|
# Clone both nginx and `ngx_http_zip_module` repositories, needed to compile the module from source.
|
|
# This is needed to be able to dinamically load it as a module in the final image. `nginx` Docker
|
|
# images do not have a simple way to include third-party modules.
|
|
RUN git clone https://github.com/evanmiller/mod_zip.git && \
|
|
cd ./mod_zip && \
|
|
git checkout "${NGINX_MOD_ZIP_SHA}" && \
|
|
cd ../ && \
|
|
git clone --branch "release-${NGINX_VERSION}" --depth 1 https://github.com/nginx/nginx.git && \
|
|
cd ./nginx && \
|
|
./auto/configure --with-compat --add-dynamic-module=../mod_zip/ && \
|
|
make -f ./objs/Makefile modules && \
|
|
chmod 644 ./objs/ngx_http_zip_module.so
|
|
|
|
|
|
FROM nginx:${NGINX_VERSION}-alpine${ALPINE_VERSION} AS production-stage
|
|
ARG WEBSERVER_FOLDER=/var/www/html
|
|
|
|
# Install required packages and dependencies
|
|
RUN apk add --no-cache \
|
|
bash \
|
|
libmagic \
|
|
mariadb-connector-c \
|
|
libpq \
|
|
p7zip \
|
|
tzdata \
|
|
valkey
|
|
|
|
# Add Python by copying it from the official Docker image. This way, we don't rely on Alpine's
|
|
# Python version, which could not be the same as the one used in the backend build stage.
|
|
# TODO: Replace with a bundled installation of Python using `uv`, when it is supported.
|
|
# Related issue: https://github.com/astral-sh/uv/issues/7865
|
|
ARG PYTHON_VERSION
|
|
COPY --from=python-alias /usr/lib/* /usr/lib/
|
|
COPY --from=python-alias /usr/local/bin/* /usr/local/bin/
|
|
COPY --from=python-alias /usr/local/include/python${PYTHON_VERSION} /usr/local/include/python${PYTHON_VERSION}
|
|
COPY --from=python-alias /usr/local/lib/libpython* /usr/local/lib/
|
|
COPY --from=python-alias /usr/local/lib/python${PYTHON_VERSION} /usr/local/lib/python${PYTHON_VERSION}
|
|
|
|
COPY --from=rahasher-build /RALibretro/bin64/RAHasher /usr/bin/RAHasher
|
|
COPY --from=nginx-build ./nginx/objs/ngx_http_zip_module.so /usr/lib/nginx/modules/
|
|
COPY --from=frontend-build /front/dist ${WEBSERVER_FOLDER}
|
|
|
|
COPY ./frontend/assets ${WEBSERVER_FOLDER}/assets
|
|
COPY ./backend /backend
|
|
|
|
# Setup init script and config files
|
|
COPY ./docker/init_scripts/* /
|
|
COPY ./docker/nginx/js/ /etc/nginx/js/
|
|
COPY ./docker/nginx/templates/ /etc/nginx/templates/
|
|
COPY ./docker/nginx/default.conf /etc/nginx/nginx.conf
|
|
COPY ./docker/gunicorn/logging.conf /etc/gunicorn/logging.conf
|
|
|
|
# User permissions
|
|
# - Create default user `romm` (1000) and group `romm` (1000).
|
|
# - Create base directories and make default user/group the owner.
|
|
# - Make nginx configuration files writable by everyone, for `envsubst` to work
|
|
# when a custom UID/GID is used.
|
|
RUN addgroup -g 1000 -S romm && adduser -u 1000 -D -S -G romm romm && \
|
|
mkdir /romm /redis-data && chown romm:romm /romm /redis-data && \
|
|
chmod -R a+w /etc/nginx/conf.d
|
|
|
|
|
|
FROM scratch AS slim-image
|
|
|
|
COPY --from=production-stage / /
|
|
|
|
COPY --from=backend-build /src/.venv /src/.venv
|
|
|
|
ENV PATH="/src/.venv/bin:${PATH}"
|
|
|
|
# Declare the supported volumes
|
|
VOLUME ["/romm/resources", "/romm/library", "/romm/assets", "/romm/config", "/redis-data"]
|
|
|
|
# Expose ports and start
|
|
EXPOSE 8080 6379/tcp
|
|
WORKDIR /romm
|
|
|
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
|
CMD ["/init"]
|
|
|
|
|
|
FROM slim-image AS full-image
|
|
ARG WEBSERVER_FOLDER=/var/www/html
|
|
COPY --from=emulator-stage /emulatorjs ${WEBSERVER_FOLDER}/assets/emulatorjs
|
|
COPY --from=emulator-stage /ruffle ${WEBSERVER_FOLDER}/assets/ruffle
|
|
|
|
|
|
FROM slim-image AS dev-slim
|
|
COPY --from=backend-dev-build /src/.venv /src/.venv
|
|
|
|
|
|
FROM full-image AS dev-full
|
|
COPY --from=backend-dev-build /src/.venv /src/.venv
|