-
-
Notifications
You must be signed in to change notification settings - Fork 744
Expand file tree
/
Copy pathDockerfile
More file actions
222 lines (189 loc) · 9.15 KB
/
Copy pathDockerfile
File metadata and controls
222 lines (189 loc) · 9.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# syntax=docker/dockerfile:1
# trunk-ignore-all(trivy)
# trunk-ignore-all(checkov)
# trunk-ignore-all(hadolint/DL4006)
# Keep the pins in sync with the gme-build stage of docker/Dockerfile.
# trunk-ignore(hadolint/DL3029)
FROM --platform=linux/amd64 emscripten/emsdk:4.0.12@sha256:744fb6a68941970951bacf9d6632041a0398260492232691ef22bbf54b0585c6 AS emsdk-amd64
# trunk-ignore(hadolint/DL3029)
FROM --platform=linux/arm64 emscripten/emsdk:4.0.12-arm64@sha256:369a4cb655aa1066e6e450dde774243c502d999b1d93fb4890a9d1428daa9280 AS emsdk-arm64
# trunk-ignore(hadolint/DL3006)
FROM emsdk-${BUILDARCH} AS gme-build
ARG GME_VERSION=0.6.5
ARG GME_COMMIT=9e23d10f9fd2a6a2f33b10912dd8dc7153258995
ADD --checksum=${GME_COMMIT} "https://github.com/libgme/game-music-emu.git#${GME_VERSION}" /libgme
COPY docker/gme /romm-gme
RUN /romm-gme/build.sh /libgme /gme
# Browser player runtimes. Keep the pins in sync with the emulator stage of docker/Dockerfile.
FROM ubuntu:22.04 AS emulator-download
# trunk-ignore(hadolint/DL3008)
RUN apt-get update && apt-get install -y --no-install-recommends \
7zip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ARG EMULATORJS_VERSION=4.2.3
ARG EMULATORJS_SHA256=07d451bc06fa3ad04ab30d9b94eb63ac34ad0babee52d60357b002bde8f3850b
ADD --checksum=sha256:${EMULATORJS_SHA256} \
"https://github.com/EmulatorJS/EmulatorJS/releases/download/v${EMULATORJS_VERSION}/${EMULATORJS_VERSION}.7z" \
/downloads/emulatorjs.7z
RUN 7zz x -y /downloads/emulatorjs.7z -o/emulators/emulatorjs
ARG RUFFLE_VERSION=nightly-2025-08-14
ARG RUFFLE_FILE=ruffle-nightly-2025_08_14-web-selfhosted.zip
ARG RUFFLE_SHA256=178870c5e7dd825a8df35920dfc5328d83e53f3c4d5d95f70b1ea9cd13494151
ADD --checksum=sha256:${RUFFLE_SHA256} \
"https://github.com/ruffle-rs/ruffle/releases/download/${RUFFLE_VERSION}/${RUFFLE_FILE}" \
/downloads/ruffle.zip
RUN 7zz x -y /downloads/ruffle.zip -o/emulators/ruffle
ARG JSDOS_VERSION=8.4.1
ARG JSDOS_SHA256=26118692bbb180aec78ec1697eb1ea6b28ff410101870cfa3e68309914c7eaa6
ADD --checksum=sha256:${JSDOS_SHA256} \
"https://github.com/caiiiycuk/js-dos/releases/download/v${JSDOS_VERSION}/release.zip" \
/downloads/jsdos.zip
# The bundled index.html is a js-dos demo page that would be served unauthenticated;
# source maps, Emscripten symbol files and type declarations are unused at runtime.
RUN 7zz x -y /downloads/jsdos.zip -o/tmp/jsdos \
&& mv /tmp/jsdos/dist /emulators/jsdos \
&& rm -rf /emulators/jsdos/index.html /emulators/jsdos/emulators/types \
&& find /emulators/jsdos \( -name '*.map' -o -name '*.symbols' \) -exec rm -f {} +
# FAKE-08 (MIT) publishes no web build, so these come from p3a (Apache-2.0),
# which compiled them. Pinned by commit and checksum: that tree has no tags.
ARG FAKE08_P3A_COMMIT=6519efd9dd1ca853e5c66f7ae9146ace0b7073dc
ARG FAKE08_JS_SHA256=fd2cd4677956037e41a91dbd40fc1a9c4f5979355d55ce3f9312400e11da463e
ARG FAKE08_WASM_SHA256=4339a77e0aa5aa6f4a5bce9fd8286053eedf7f23f2d853db7f4900f6fff4c93a
# Created first, or ADD --chmod would also apply to the directory it creates.
RUN mkdir -p /emulators/pico8
ADD --checksum=sha256:${FAKE08_JS_SHA256} --chmod=644 \
"https://raw.githubusercontent.com/fabkury/p3a/${FAKE08_P3A_COMMIT}/webui/pico8/fake08.js" \
/emulators/pico8/fake08.js
ADD --checksum=sha256:${FAKE08_WASM_SHA256} --chmod=644 \
"https://raw.githubusercontent.com/fabkury/p3a/${FAKE08_P3A_COMMIT}/webui/pico8/fake08.wasm" \
/emulators/pico8/fake08.wasm
ARG EASYRPG_VERSION=0.8.1.1
ARG EASYRPG_SHA256=99b6963c943bb355e1b1221125cb4536ca2f627c329d8a89cee5a928cdd6a14f
ADD --checksum=sha256:${EASYRPG_SHA256} \
"https://easyrpg.org/downloads/player/${EASYRPG_VERSION}/easyrpg-player-${EASYRPG_VERSION}-js.tar.gz" \
/downloads/easyrpg.tar.gz
# games/ is where the player looks for games, which the server routes to the backend.
RUN mkdir -p /emulators/easyrpg && \
tar -xzf /downloads/easyrpg.tar.gz -C /emulators/easyrpg --strip-components=1 && \
rm -rf /emulators/easyrpg/games
# The free RTP (CC-BY-4.0) has no releases, so it is pinned by commit.
ARG EASYRPG_RTP_COMMIT=993d88cbc78c658d348bbfa74a3b424d393d27e5
ARG EASYRPG_RTP_SHA256=7e42abebbec94989f4ff214fc082511eef749114e76e3a342cb62d07c03d56e7
ADD --checksum=sha256:${EASYRPG_RTP_SHA256} \
"https://github.com/EasyRPG/RTP/archive/${EASYRPG_RTP_COMMIT}.tar.gz" \
/downloads/easyrpg-rtp.tar.gz
RUN mkdir /emulators/easyrpg/rtp && \
tar -xzf /downloads/easyrpg-rtp.tar.gz -C /emulators/easyrpg/rtp --strip-components=1 && \
find /emulators/easyrpg/rtp \( -name '.git*' -o -name Makefile \) -exec rm -f {} +
FROM ubuntu:22.04
# Prevent interactive prompts during installation
ENV DEBIAN_FRONTEND=noninteractive
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
make \
cmake \
gcc \
g++ \
libmariadb3 \
libmariadb-dev \
libpq-dev \
libffi-dev \
musl-dev \
curl \
ca-certificates \
libmagic-dev \
7zip \
libarchive-tools \
tzdata \
libbz2-dev \
libssl-dev \
libreadline-dev \
libsqlite3-dev \
zlib1g-dev \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install nvm
ENV NVM_DIR="/root/.nvm"
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash \
&& . "$NVM_DIR/nvm.sh" \
&& nvm install 24.16.0 \
&& nvm use 24.16.0 \
&& nvm alias default 24.16.0
ENV PATH="$NVM_DIR/versions/node/v24.16.0/bin:$PATH"
# Build and install RAHasher (optional for RA hashes)
# Tag 1.8.3. Keep the pin in sync with docker/Dockerfile.
ARG RALIBRETRO_COMMIT=8ab61f745ab753a70b5482f2a0ccb6a4ced5193f
RUN git clone --filter=blob:none https://github.com/RetroAchievements/RALibretro.git /tmp/RALibretro \
&& git -C /tmp/RALibretro checkout "${RALIBRETRO_COMMIT}" \
&& git -C /tmp/RALibretro submodule update --init --recursive
WORKDIR /tmp/RALibretro
RUN make HAVE_CHD=1 -f ./Makefile.RAHasher \
&& cp ./bin64/RAHasher /usr/bin/RAHasher
RUN rm -rf /tmp/RALibretro
# Install rom-converto (optional); its static musl build runs on this glibc image.
# Keep the version and both sums in sync with docker/Dockerfile.
ARG TARGETARCH
RUN ROM_CONVERTO_VERSION=v0.23.2 \
&& arch="${TARGETARCH:-$(dpkg --print-architecture)}" \
&& case "${arch}" in \
amd64) rc="linux-x64-musl"; sum="734ecccfa77d425c01dc3ba621261389c1c23d23f0e5d6b8e3346fda1879d687" ;; \
arm64) rc="linux-arm64-musl"; sum="e90cca392b08b859b79bab13fcd47300ffc613d5dca7da1b4d1e38e3a4bbc297" ;; \
*) echo "unsupported architecture: ${arch}" && exit 1 ;; \
esac \
&& curl -fsSL -o "/tmp/rom-converto-cli-${rc}" \
"https://github.com/DevYukine/rom-converto/releases/download/${ROM_CONVERTO_VERSION}/rom-converto-cli-${rc}" \
&& echo "${sum} /tmp/rom-converto-cli-${rc}" | sha256sum -c --status \
&& install -m 0755 "/tmp/rom-converto-cli-${rc}" /usr/bin/rom-converto \
&& rm -f "/tmp/rom-converto-cli-${rc}"
# Install frontend dependencies
COPY frontend/package.json /app/frontend/
WORKDIR /app/frontend
RUN npm install
# Install backend Node helpers (server-side ROM patching)
COPY backend/utils/rom_patcher/package.json /app/backend/utils/rom_patcher/
WORKDIR /app/backend/utils/rom_patcher
RUN npm install
# Set working directory
WORKDIR /app
# Install uv for the non-root user
COPY --from=ghcr.io/astral-sh/uv:0.12.19 /uv /uvx /usr/local/bin/
# Copy project files (including pyproject.toml and uv.lock)
COPY pyproject.toml uv.lock* .python-version /app/
# Install Python (pinned by .python-version) and the project dependencies
RUN uv python install \
&& uv sync --all-extras
ENV PATH="/app/.venv/bin:${PATH}"
# Build and install sigil (optional, for title ID extraction)
# Placed after `uv sync` because the extension is compiled with the venv's
# Python so the ABI matches. Keep the pin in sync with docker/Dockerfile.
ARG SIGIL_VERSION=8a3b0089676e07f74da2d9ad08979dedf5cae7c0
# One layer, so the clone and the cmake tree never reach the image.
# trunk-ignore(hadolint/DL3003)
RUN git clone --filter=blob:none https://github.com/rommapp/argosy-sigil.git /tmp/argosy-sigil \
&& cd /tmp/argosy-sigil \
&& git checkout "${SIGIL_VERSION}" \
&& git submodule update --init --recursive \
&& cmake -B ./build-python -S . -DSIGIL_BUILD_CLI=OFF -DSIGIL_BUILD_TESTS=OFF \
&& cmake --build ./build-python --target sigil \
&& uv pip install --python /app/.venv/bin/python cffi setuptools \
&& cd ./bindings/python \
&& /app/.venv/bin/python build_sigil.py \
&& SITE_PACKAGES="$(/app/.venv/bin/python -c 'import site; print(site.getsitepackages()[0])')" \
&& mkdir -p "${SITE_PACKAGES}/sigil" \
&& cp ./sigil/*.py ./sigil/_sigil.*.so "${SITE_PACKAGES}/sigil/" \
&& rm -rf /tmp/argosy-sigil
WORKDIR /app
# Kept outside /app/frontend because the ./frontend bind mount hides it;
# entrypoint.sh links the runtimes into the assets tree at startup.
ENV EMULATOR_ASSETS_DIR="/opt/romm/emulators"
COPY --from=emulator-download /emulators "${EMULATOR_ASSETS_DIR}"
COPY --from=gme-build /gme "${EMULATOR_ASSETS_DIR}/gme"
# Copy entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]