title: How do I prevent root access to my docker container
body: <p>I am working on hardening our docker images, which I already have a bit of a weak understanding of.  With that being said, the current step I am on is preventing the user from running the container as root.  To me, that says "when a user runs 'docker exec -it my-container bash', he shall be an unprivileged user" (correct me if I'm wrong).</p>
  
  <p>When I start up my container via docker-compose, the start script that is run needs to be as root since it deals with importing certs and mounted files (created externally and seen through a volume mount).  After that is done, I would like the user to be 'appuser' for any future access.  This question seems to match pretty well what I'm looking for, but I am using docker-compose, not docker run: <a href="https://stackoverflow.com/questions/43814416/how-to-disable-the-root-access-of-a-docker-container">How to disable the root access of a docker container?</a></p>
  
  <p>This seems to be relevant, as the startup command differs from let's say tomcat.  We are running a Spring Boot application that we start up with a simple 'java -jar jarFile', and the image is built using maven's dockerfile-maven-plugin.  With that being said, should I be changing the user to an unprivileged user before running that, or still after?</p>
  
  <p>I believe changing the user inside of the Dockerfile instead of the start script will do this... but then it will not run the start script as root, thus blowing up on calls that require root.  I had messed with using ENTRYPOINT as well, but could have been doing it wrong there.  Similarly, using "user:" in the yml file seemed to make the start.sh script run as that user instead of root, so that wasn't working.</p>
  
  <p>Dockerfile:</p>
  
  <pre><code>FROM parent/image:latest
  
  ENV APP_HOME                            /apphome
  ENV APP_USER                            appuser
  ENV APP_GROUP                           appgroup
  
  # Folder containing our application, i.e. jar file, resources, and scripts.
  # This comes from unpacking our maven dependency
  ADD target/classes/app ${APP_HOME}/
  
  # Primarily just our start script, but some others
  ADD target/classes/scripts /scripts/
  
  # Need to create a folder that will be used at runtime
  RUN mkdir -p ${APP_HOME}/data &amp;&amp; \
      chmod +x /scripts/*.sh &amp;&amp; \
      chmod +x ${APP_HOME}/*.*
  
  # Create unprivileged user
  RUN groupadd -r ${APP_GROUP} &amp;&amp; \
      useradd -g ${APP_GROUP} -d ${APP_HOME} -s /sbin/nologin  -c "Unprivileged User" ${APP_USER} &amp;&amp; \
      chown -R ${APP_USER}:${APP_GROUP} ${APP_HOME}
  
  WORKDIR $APP_HOME
  
  EXPOSE 8443
  
  CMD /opt/scripts/start.sh
  </code></pre>
  
  <p>start.sh script:</p>
  
  <pre><code>#!/bin/bash
  
  # setup SSL, modify java command, etc
  
  # run our java application
  java -jar "boot.jar"
  
  # Switch users to always be unprivileged from here on out? 
  # Whatever "hardening" wants...  Should this be before starting our application?
  exec su -s "/bin/bash" $APP_USER
  </code></pre>
  
  <p>app.yml file:</p>
  
  <pre><code>version: '3.3'
  
  services:
    app:
      image: app_image:latest
      labels:
        c2core.docker.compose.display-name: My Application
        c2core.docker.compose.profiles: a_profile
      volumes:
        - "data_mount:/apphome/data"
        - "cert_mount:/certs"
      hostname: some-hostname
      domainname: some-domain
      ports:
      - "8243:8443"
      environment:
        - some_env_vars
      depends_on:
      - another-app
      networks:
        a_network:
          aliases:
            - some-network
  networks:
    a_network:
      driver: bridge
  volumes:
    data_mount:
    cert_mount:
  </code></pre>
  
  <p>docker-compose shell script:</p>
  
  <pre><code>docker-compose -f app.yml -f another-app.yml $@
  </code></pre>
  
  <p>What I would expect is that anyone trying to access the container internally will be doing so as appuser and not root.  The goal is to prevent someone from messing with things they shouldn't (i.e. docker itself).</p>
  
  <p>What is happening is that the script will change users after the app has started (proven via an echo command), but it doesn't seem to be maintained.  If I exec into it, I'm still root.</p>