-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
72 lines (58 loc) · 2.68 KB
/
Copy pathDockerfile
File metadata and controls
72 lines (58 loc) · 2.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
# ---- Stage 1: System deps + R packages ----
FROM rocker/geospatial:4.5.2 AS base
LABEL maintainer="Spatial Predictions Project"
LABEL description="Reproducible multi-country geospatial ETL + spatial ML pipeline"
# System libraries needed by R packages not in rocker/geospatial
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
libgit2-dev \
libsodium-dev \
python3-pip \
python3-venv \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /project
# Copy renv infrastructure first (Docker layer caching)
COPY renv.lock renv.lock
COPY .Rprofile .Rprofile
COPY renv/activate.R renv/activate.R
ENV RENV_CONFIG_CACHE_ENABLED=FALSE
# Redirect the "CRAN" repo to PPM's Ubuntu-noble binary mirror.
# renv.lock tags most packages as Repository: CRAN; pointing CRAN at PPM
# means those are installed as pre-built Linux binaries instead of being
# compiled from source, which avoids transient CRAN mirror failures and
# is significantly faster. Raise the download timeout for large packages.
RUN echo 'options(repos = c(CRAN = "https://packagemanager.posit.co/cran/__linux__/noble/latest"), timeout = 300)' \
>> /usr/local/lib/R/etc/Rprofile.site
# Pre-install LightGBM from PPM binary before renv::restore().
# LightGBM is on CRAN/PPM, but pre-installing it here follows the same pattern
# as CatBoost: a heavy native library that benefits from its own cache layer.
RUN R -q -e "install.packages('lightgbm', repos = 'https://packagemanager.posit.co/cran/__linux__/noble/latest')"
# Restore R packages from lockfile.
# Retries up to 5 times with back-off to handle transient download errors;
# already-installed packages are skipped on each subsequent attempt.
RUN for i in 1 2 3 4 5; do \
R -q -e "renv::restore(prompt = FALSE)" && break; \
echo "renv::restore attempt $i failed, retrying in 20 s..." >&2; \
sleep 20; \
done
# ---- Stage 2: Copy project files and validate ----
FROM base AS project
WORKDIR /project
# Copy project structure
COPY config/ config/
COPY R/ R/
COPY tests/ tests/
COPY _targets.R _targets.R
COPY docs/ docs/
COPY AGENTS.md AGENTS.md
COPY CLAUDE.md CLAUDE.md
# Create data directories (raw data is mounted at runtime, not baked in)
RUN mkdir -p data/raw data/intermediate data/final logs models cache
# Validate that packages restore correctly
RUN for i in 1 2 3 4 5; do \
R -q -e "renv::restore(prompt = FALSE)" && break; \
echo "renv::restore attempt $i failed, retrying in 20 s..." >&2; \
sleep 20; \
done \
&& R -q -e "library(sf); library(terra); library(arrow); library(duckdb); library(targets); library(exactextractr); cat('All packages OK\n')"
CMD ["R", "-q", "-e", "targets::tar_make()"]