-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathDockerfile
More file actions
84 lines (68 loc) · 3.68 KB
/
Dockerfile
File metadata and controls
84 lines (68 loc) · 3.68 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
# Run the build stage on the builder's native platform: the output is
# arch-independent static files, so emulating arm64 with QEMU here only
# slows down multi-arch builds without changing the result.
# ($BUILDPLATFORM is a Docker-provided automatic ARG, set by BuildKit.)
FROM --platform=$BUILDPLATFORM node:22-alpine AS build
WORKDIR /app
# Copy every workspace member's package.json before npm ci so the install
# layer is cached. Adding a new package under apps/ or packages/ requires
# adding its package.json here, or npm ci fails with a missing workspace.
COPY package.json package-lock.json ./
COPY apps/geolibre-desktop/package.json apps/geolibre-desktop/package.json
COPY packages/core/package.json packages/core/package.json
COPY packages/map/package.json packages/map/package.json
COPY packages/plugins/package.json packages/plugins/package.json
COPY packages/processing/package.json packages/processing/package.json
COPY packages/ui/package.json packages/ui/package.json
RUN npm ci
COPY . .
ARG GEOLIBRE_APP_BASE=/
ARG VITE_GEE_OAUTH_CLIENT_ID=
ENV GEOLIBRE_APP_BASE=${GEOLIBRE_APP_BASE}
ENV VITE_GEE_OAUTH_CLIENT_ID=${VITE_GEE_OAUTH_CLIENT_ID}
RUN npm run build
# Runtime image bundles the static web app (served by nginx) and the optional
# Python conversion/Whitebox sidecar (uvicorn), reverse-proxied at /sidecar.
# A glibc base (not alpine/musl) is required for the prebuilt geo wheels
# (duckdb, rasterio/rio-cogeo, freestiler, whitebox-workflows).
FROM python:3.12-slim-bookworm AS runtime
# TARGETARCH is provided by BuildKit (amd64 / arm64).
ARG TARGETARCH
# libexpat1 is a runtime dependency of rasterio (pulled in by rio-cogeo) that
# the slim base image does not ship.
RUN apt-get update \
&& apt-get install -y --no-install-recommends nginx libexpat1 \
&& rm -rf /var/lib/apt/lists/* \
&& rm -f /etc/nginx/sites-enabled/default
# Install the sidecar package plus the core conversion stack. duckdb and
# rio-cogeo (rasterio) publish linux/arm64 wheels, so Vector->GeoParquet,
# CSV->GeoParquet and Raster->COG work on both architectures.
COPY backend/geolibre_server /opt/geolibre_server
RUN pip install --no-cache-dir /opt/geolibre_server \
&& pip install --no-cache-dir "duckdb>=1.1.0" "rio-cogeo>=5.0.0"
# freestiler (PMTiles) and whitebox-workflows publish no linux/arm64 wheels, so
# they are installed on amd64 only. On arm64 those tools report unavailable
# while the other conversions keep working.
RUN if [ "$TARGETARCH" = "amd64" ]; then \
pip install --no-cache-dir "freestiler>=0.1.0" "whitebox-workflows>=2.0.2"; \
else \
echo "Skipping freestiler + whitebox-workflows on $TARGETARCH (no wheels)"; \
fi
# Point the sidecar at this interpreter so it skips the managed-runtime
# bootstrap and uses the prebaked packages. Confine conversion reads/writes to
# /data by default: the sidecar is reachable same-origin through the nginx
# proxy, so without this an arbitrary same-origin caller could read or
# overwrite container paths. Mount input files at /data (read-write for
# outputs); override GEOLIBRE_CONVERSION_ROOTS to widen or disable.
ENV GEOLIBRE_CONVERSION_PYTHON=/usr/local/bin/python \
WBW_EXTERNAL_PYTHON=/usr/local/bin/python \
GEOLIBRE_CONVERSION_ROOTS=/data
RUN mkdir -p /data
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
COPY --from=build /app/apps/geolibre-desktop/dist /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1/', timeout=4).status==200 else 1)" || exit 1
CMD ["/usr/local/bin/entrypoint.sh"]