ThinkR-open / golem

A Framework for Building Robust Shiny Apps
https://thinkr-open.github.io/golem/
Other
885 stars 130 forks source link

Think about multistage docker build #1096

Open VincentGuyader opened 10 months ago

VincentGuyader commented 10 months ago

today, the add_dockerfile_with_renv fonction create 2 Dockerfile tu be able to reuse the renv cache from the first image, in se second one.

like this :

docker build -f Dockerfile_base --progress=plain -t wootwoot3_base .
docker build -f Dockerfile --progress=plain -t wootwoot3:latest .

we can set instead an unique Dockerfile with multistage :


FROM rocker/verse:4.2.2 AS base
RUN apt-get update -y && apt-get install -y  make zlib1g-dev git && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/local/lib/R/etc/ /usr/lib/R/etc/
RUN echo "options(renv.config.pak.enabled = TRUE, repos = c(CRAN = 'https://cran.rstudio.com/'), download.file.method = 'libcurl', Ncpus = 4)" | tee /usr/local/lib/R/etc/Rprofile.site | tee /usr/lib/R/etc/Rprofile.site
RUN R -e 'install.packages(c("renv","remotes"))'
COPY renv.lock.prod renv.lock
RUN R -e 'renv::restore()'

FROM base AS final
COPY renv.lock.prod renv.lock
RUN R -e 'renv::restore()'
COPY wootwoot3_*.tar.gz /app.tar.gz
RUN R -e 'remotes::install_local("/app.tar.gz",upgrade="never")'
RUN rm /app.tar.gz
EXPOSE 3838
CMD R -e "options('shiny.port'=3838,shiny.host='0.0.0.0');library(wootwoot3);wootwoot3::run_app()"

it works, but as far as i know if you change your renv.lock.prod fie it's not possible to only rerun final.

I have tried --target, --cache-from .. without succes.

some other people have the same need as us , see in python here :

https://pythonspeed.com/articles/faster-multi-stage-builds/

but the solution is not clean at all.

so I think that we will keed the actual solution, if anyone else wants to try looking, I'd be happy to since I have no experience with docker multistage

https://stackoverflow.com/questions/52697948/artifact-caching-for-multistage-docker-builds

dijitali commented 8 months ago

it works, but as far as i know if you change your renv.lock.prod fie it's not possible to only rerun final.

Is that a problem? If you change which packages your project uses, you want docker to install those changes, right?

If you have the previous docker image pulled then it should only run subsequent layers from the COPY renv.lock.prod renv.lock command onwards (not the entire base stage)

VincentGuyader commented 8 months ago

it works, but as far as i know if you change your renv.lock.prod fie it's not possible to only rerun final.

Is that a problem? If you change which packages your project uses, you want docker to install those changes, right?

If you have the previous docker image pulled then it should only run subsequent layers from the COPY renv.lock.prod renv.lock command onwards (not the entire base stage)

HI, COPY renv.lock.prod renv.lock is in both stage ... :(