title: Configuring a docker container to use host UID and generate files on the host system - Preferably at runtime
body: <p>I am currently working on a research tool that is supposed to be containerized using docker to hopefully be run on as many different systems as possible. This works fine for the most part, we have run into a permission problem because of the workflow though: The tool takes an input file (which we mount into the container), evaluates it using R scripts and is then supposed to generate a report on the input file exactly where the file was taken from on the host system.</p>
  
  <p>The latter part is problematic as at least in our university context, the internal container user lacks write permissions in the (non-root) user home folders, which we are currently taking our testing data from. This would obviously also be bad in a production context as we don't know how the potential users' system is set up, which is why we are trying to dynamically and temporarily set the permissions of the container user to the host user.</p>
  
  <p>I have found different solutions that involve passing the UID/GID to the docker daemon when building the container in some way or another:</p>
  
  <pre><code>docker build --build-arg USER_ID=$(id -u ${USER}) --build-arg GROUP_ID=$(id -g ${USER}) -t IMAGE .
  </code></pre>
  
  <p>I also changed the dockerfile accordingly using a tutorial that suggested replacing the internal www-data user:</p>
  
  <pre><code>[...Package installation steps that are supposed to be run as root...]
  
  ARG USER_ID
  ARG GROUP_ID
  
  RUN if [ ${USER_ID:-0} -ne 0 ] &amp;&amp; [ ${GROUP_ID:-0} -ne 0 ]; then \
      userdel -f www-data &amp;&amp;\
      if getent group www-data ; then groupdel www-data; fi &amp;&amp;\
      groupadd -g ${GROUP_ID} www-data &amp;&amp;\
      useradd -l -u ${USER_ID} -g www-data www-data &amp;&amp;\
      install -d -m 0755 -o www-data -g www-data /work/ &amp;&amp;\
      chown --changes --silent --no-dereference --recursive \
            --from=33:33 ${USER_ID}:${GROUP_ID} \
        /work \
  ;fi
  
  USER www-data
  
  WORKDIR     /work
  RUN     mkdir files
  
  COPY            data/ /opt/MTB/data/
  COPY        helpers/ /opt/MTB/helpers/
  COPY        src/www/ /opt/MTB/www/
  COPY        tmp/ /opt/MTB/tmp/
  COPY        example_data/ /opt/MTB/example_data/
  COPY        src/ /opt/MTB/src/
  
  EXPOSE      8080
  
  ENTRYPOINT      ["/opt/MTB/src/starter_s_c.sh"]
  </code></pre>
  
  <p>The entrypoint script <code>starter_s_c.sh</code> is a small bashscript that feeds the trailing argument to the corresponding R script as an input file - the R script writes the report.</p>
  
  <p>This works, but requires the container to be built again for every new user. What we are looking for is a solution that handles the dynamic permission setting at runtime, so that we only have to build the container once and can use it with many different user configurations.</p>
  
  <p>I have found <a href="https://stackoverflow.com/questions/45696676/set-docker-image-username-at-container-creation-time">this</a> but I am not entirely sure how to implement it as it would replace our entrypoint script and I'm not sure how to integrate this solution into our project.</p>
  
  <p>Here is our current entrypoint script which already needs the permissions to be set so <code>localmaster.r</code> can generate the report in the host directory:</p>
  
  <pre><code>#!/bin/sh
  file="$1"
  cd $(dirname $0)/..
  if [ $# -eq 0 ]; then
      echo '.libPaths(c("~/lib/R/library", .libPaths())); library(shiny); library(shinyjs); runApp("src")' | R --vanilla 
  else
      echo "Rscript --vanilla /opt/MTB/src/localmaster.r "$file"" 
      Rscript --vanilla /opt/MTB/src/localmaster.r "$file"
  fi
  </code></pre>
  
  <p>(If no arguments are given, it starts a shiny app, just to avoid confusion)</p>
  
  <p>Any help or tips would be much appreciated! Thank you.</p>