From f601667c876bd46e1824c632c3f42439e50e039f Mon Sep 17 00:00:00 2001 From: Adar Nimrod <nimrod@shore.co.il> Date: Sun, 26 Nov 2017 22:28:26 +0200 Subject: [PATCH] Added post about setting the user for builds inside Docker containers. --- content/docker_uid.rst | 68 ++++++++++++++++++++++++++++++++++++++++++ content/static/runas | 6 ++++ 2 files changed, 74 insertions(+) create mode 100644 content/docker_uid.rst create mode 100755 content/static/runas diff --git a/content/docker_uid.rst b/content/docker_uid.rst new file mode 100644 index 0000000..7542e51 --- /dev/null +++ b/content/docker_uid.rst @@ -0,0 +1,68 @@ +Building inside a Docker container with the correct user +######################################################## + +:date: 2017-11-26 +:summary: Building inside a Docker container with the correct user + +Lately I've been using Docker container as clean, easily portable and easily +removable build environments. In those cases the image contains the needed build +tools and the project is mounted to a volume inside the container. The artifacts +are then built inside the container but are placed inside the volume. However +a small problem arises, the artifacts (and whatever other files are created, +like cache) are owned by the default user, :code:`root`, making editing or +removing said files less straightforward. + +The trivial solution +-------------------- + +The trivial solution is to run the container with the correct user id, like so + +.. code:: shell + + uid="$(id -u)" + gid="$(id -g)" + docker run -v "$PWD:/volume" --user "$uid:$gid" buildimage make + +I personally find it a tiresome after the 3rd time I had to rebuild the +project because I forgot to specify the uid and gid and it's a (low) barrier +to entry for new users. + +A better solution +----------------- + +The solution I've come up with is this small script that sets the uid and gid +values to those of the owner and group for the volume and then execute the +commands. + +.. code:: shell + + #!/bin/sh + set -eu + command -v sudo > /dev/null || { echo "Can't find sudo, exiting."; exit 1; } + uid="$(stat . --format '%u')" + gid="$(stat . --format '%g')" + groupadd --force --non-unique --gid "$gid" builder + useradd --non-unique --gid "$gid" --home-dir /volume --no-create-home --shell /bin/sh builder + sudo -Eu "#$uid" -g "#$gid" -- "$@" + +The script is also available for `download +<https://www.shore.co.il/blog/static/runas>`_. The only dependency is +:code:`sudo`. You can download it and check to your VCS and incorporate it into +your Dockerfile, or download it via the :code:`ADD` directive, like so: + +.. code:: shell + + FROM debian:stable + RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y sudo build-essential + ADD [ "https://www.shore.co.il/blog/static/runas", "/entrypoint"] + ENTRYPOINT [ "/bin/sh", "/entrypoint" ] + VOLUME /volume + WORKDIR /volume + ENV HOME /volume + +And then finally, to build run + +.. code:: shell + + docker run -v "$PWD:/volume" buildimage make diff --git a/content/static/runas b/content/static/runas new file mode 100755 index 0000000..00dae93 --- /dev/null +++ b/content/static/runas @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu +command -v sudo > /dev/null || { echo "Can't find sudo, exiting."; exit 1; } +uid="$(stat . --format '%u')" +gid="$(stat . --format '%g')" +sudo -Eu "#$uid" -g "#$gid" -- "$@" -- GitLab