I’m trying to dockerize my shiny app made with {golem}
(the app is packaged as a library) and I’m running into problems because I have some bootstrap dependencies in my custom.scss
file (such as @include media-breakpoint-up(lg)
) and it seems that these dependencies cannot be automatically linked inside a docker container, while working locally. I am using {bslib}
inside the app as well.
Everything works smoothly when installing/running the app locally (even on a remote server), but when trying to dockerize the app, it cannot interpret the custom.scss
file, the link with bootstrap dependencies don’t work. The error when listening to the app is Error: File to import not found or unreadable: /tmp/RtmpWzfgRD/R.INSTALL682a228ec/<APPNAME>/inst/app/www/custom.scss. on line 71:1 of /stdin >> @import "/tmp/RtmpWzfgRD/R.INSTALL682a228ec/<APPNAME>/inst/app/www/custom.scs ^
The theme in my app_ui.R
file is built as follow :
bslib::bs_theme(version = 5, preset = "bootstrap") |>
bslib::bs_add_rules(sass::sass_file("./inst/app/www/custom.scss")) # add complementary scss file
The .scss
file can be viewed here (it’s called custom_bs5.scss
in this version on GitHub) : https://github.com/mick-weber/eneRgyVD/blob/main/inst/app/www/custom_bs5.scss
I have achieved the following :
-
The app works perfectly locally,
custom.scss
is correctly interpreted and the@include media-breakpoint-up(lg)
features work as expected, though no explicit import to bootstrap dependencies is made insidecustom.scss
-
Adding the whole bootstrap github repository inside the app and importing it from
custom.scss
with@ import 'bootstrap-main/scss/bootstrap';
: this launches the app correctly but messes with the whole theme really bad, I can barely recognize the app. -
The app within a docker container works fine as long as there’s no mention of these
@include media-breakpoint-up(lg)
calls. The dockerfile contains all R librairies (loaded withrenv.lock
) see below for the content of the dockerfiles
Is there anything I’m missing ? Why can’t my docker container make the same implicit link between the @include media-breakpoint-up(lg)
queries and the bootstrap files ? If any explicit links must be made, how should I make them (e.g. @import ...
but linking to which files in my docker container ?)
Dockerfiles are generated with golem::add_dockerfile_with_renv(lockfile = 'renv.lock')
:
Dockerfile_base :
FROM rocker/verse:4.4.1
RUN apt-get update -y && apt-get install -y make pandoc zlib1g-dev libicu-dev libxml2-dev libx11-dev git libcurl4-openssl-dev libssl-dev libfontconfig1-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libjpeg-dev libpng-dev libtiff-dev libgdal-dev gdal-bin libgeos-dev libproj-dev libsqlite3-dev libudunits2-dev && 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 = FALSE, 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("remotes")'
RUN R -e 'remotes::install_version("renv", version = "1.0.11")'
Dockerfile :
FROM energyvd_base
COPY renv.lock renv.lock
RUN R -e 'options(renv.config.pak.enabled = FALSE);renv::restore(exclude = "eneRgyVD")'
COPY eneRgyVD_*.tar.gz /app.tar.gz
RUN R -e 'remotes::install_local("/app.tar.gz",upgrade="never")'
RUN rm /app.tar.gz
EXPOSE 80
USER rstudio
CMD R -e "options('shiny.port'=80,shiny.host='0.0.0.0');library(eneRgyVD);eneRgyVD::run_app()"
Running procedure :
docker build -f Dockerfile_base --progress=plain -t energyvd_base .
docker build -f Dockerfile --progress=plain -t energyvd:latest .
docker run -p 80:80 energyvd:latest
EDIT :
With this code I managed to create a custom.css
file which does not mess up with my theme :
sass::sass(input = sass::sass_file("inst/app/www/custom.scss"),
output = "inst/app/www/custom.css",
cache = NULL,
options = sass::sass_options(
include_path = system.file("lib/bs5/scss/", package = "bslib")))
I can then use custom.css
instead of custom.scss
as follow :
bslib::bs_theme(version = 5) |>
bslib::bs_add_rules(sass::sass_file("inst/app/www/custom.css"))
It’s still not exactly what I wanted since I’d like to refer to the .scss
file directly without having to make the .css
conversion manually, but I’m almost there !
2
Answers
Let me help you with that Bootstrap issue in Docker. Here’s what’s up:
Your Bootstrap isn’t playing nice with Docker, but don’t worry! Here are some practical solutions:
Solution 1: Direct Import
Add these Bootstrap imports to your
custom.scss
:Solution 2: Using bslib’s Path
Tweak your
app_ui.R
like this:Solution 3: Bootstrap in Docker
Add this to your Dockerfile:
What’s Going On:
bslib
is properly listed in yourrenv.lock
Pro Tip:
For quick SCSS testing during development, use this command:
The issue you’re experiencing is because recent versions of bslib handle Node dependencies differently. Instead of looking for
node_modules
directly, you can try this approach:The Bootstrap files are now typically located in the
lib/bs
directory within the package installation path. If you’re trying to access specific Bootstrap components, you might want to use bslib’s built-in functions instead of accessing the files directly:What specific Bootstrap components are you trying to access? This might help me provide a more targeted solution.