Files
OpenFrontIO/Dockerfile
Aleksey Orekhovsky ee459b7410 Reduce Docker image size by refactoring map loading (#1621)
## Description:

This PR implements a major refactoring of how map data is stored and
loaded, as described in #1242. Previously, map data (`.bin` files) was
bundled directly into the client-side JavaScript by Webpack using
`binary-loader`. This approach led to data duplication and increased
bundle/image sizes.

This refactoring changes the strategy entirely:
- `GameMapLoader` interface has been introduced to decouple the map
loading mechanism from the components that use it.
- New `FetchGameMapLoader` implementation loads map data by fetching it
from static server endpoint.
- Webpack configuration and `Dockerfile` have been updated to serve the
map files as static assets and to remove the source `resources/maps`
directory from the final image, thus eliminating data duplication.

This leads to several key improvements:
- Docker image size is reduced from ~750 MB to ~600 MB.
- Build time is decreased. On my local machine, the docker image build
time went from 48s to 43s.
Most of this speed-up comes from faster Webpack builds (reduced from 16s
to 11s), as it no longer needs to process large binary files. This
performance gain will be noticeable for all developers during local
development, not just in the CI workflow.

## Please complete the following:

- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [X] I have read and accepted the CLA agreement (only required once).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

aaa4xu
2025-08-01 04:49:07 +00:00

98 lines
2.7 KiB
Docker

# Use an official Node runtime as the base image
FROM node:24-slim AS base
# Set the working directory in the container
WORKDIR /usr/src/app
# Create dependency layer
FROM base AS dependencies
RUN apt-get update && apt-get install -y \
nginx \
git \
curl \
jq \
wget \
apache2-utils \
&& rm -rf /var/lib/apt/lists/*
# Update worker_connections in the existing nginx.conf
RUN sed -i 's/worker_connections [0-9]*/worker_connections 8192/' /etc/nginx/nginx.conf
FROM dependencies AS build
ARG GIT_COMMIT=unknown
ENV GIT_COMMIT="$GIT_COMMIT"
# Disable Husky hooks
ENV HUSKY=0
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm ci
# Copy the rest of the application code
COPY . .
# Build the client-side application
RUN npm run build-prod
# So we can see which commit was used to build the container
# https://openfront.io/commit.txt
RUN echo "$GIT_COMMIT" > static/commit.txt
# Remove maps data from final image
FROM base AS prod-files
COPY . .
RUN rm -rf resources/maps
FROM dependencies AS npm-dependencies
# Disable Husky hooks
ENV HUSKY=0
ENV NPM_CONFIG_IGNORE_SCRIPTS=1
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm ci --omit=dev
# Final image
FROM base
RUN apt-get update && apt-get install -y \
nginx \
supervisor \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy installed packages from dependencies stage
RUN curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb > cloudflared.deb \
&& dpkg -i cloudflared.deb \
&& rm cloudflared.deb
# Copy Nginx configuration and ensure it's used instead of the default
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN rm -f /etc/nginx/sites-enabled/default
COPY --from=dependencies /etc/nginx/nginx.conf /etc/nginx/nginx.conf
# Copy npm dependencies
COPY --from=npm-dependencies /usr/src/app/node_modules node_modules
COPY package.json .
# Copy the rest of the application code
COPY --from=prod-files /usr/src/app/ /usr/src/app/
# Copy frontend
COPY --from=build /usr/src/app/static static
# Setup supervisor configuration
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy and make executable the startup script
COPY startup.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/startup.sh
RUN mkdir -p /etc/cloudflared && \
chown -R node:node /etc/cloudflared && \
chmod -R 755 /etc/cloudflared
# Set Cloudflared config directory to a volume mount location
ENV CF_CONFIG_PATH=/etc/cloudflared/config.yml
ENV CF_CREDS_PATH=/etc/cloudflared/creds.json
# Use the startup script as the entrypoint
ENTRYPOINT ["/usr/local/bin/startup.sh"]