Commit f601667c authored by nimrod's avatar nimrod
Browse files

Added post about setting the user for builds inside Docker containers.

parent e538d04d
Loading
Loading
Loading
Loading

content/docker_uid.rst

0 → 100644
+68 −0
Original line number Diff line number Diff line
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

content/static/runas

0 → 100755
+6 −0
Original line number Diff line number Diff line
#!/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" -- "$@"