Set current host user for docker container

Lenty Chang
FAUN — Developer Community 🐾
5 min readApr 7, 2019

--

Env: ubuntu 18.04, Docker 18.09.4, Docker-compose 1.23.2

TL;DR

I personally prefer to use docker-compose to mount all host password related files to the container. See Method3.
Remember to substitute all variables with uppercase with angle bracket. i.e. <VAR>

Warning
If you ues non-user with the same uid as current host user and mount a host volume, it means the data inside host volume is visible by host and can be operated by both host user and user in container because both user have same authority. Please consider whether there is safty issue in your application.

Motivation

When developing inside a container, sometimes it is problematic that you create a file which will be owned by root and not able to be operated with host user, unless the host user runs the command with sudo privileges.

When operating files in the volume from container and host, it often results in some problems due to ownership of files.

Method 1: Run directly from an image

In this method, we mount/overwrite the files related to password and user accounts from host to container.

Pros:

  • No extra work to change the existing system or images
  • The image is independent to user id
    means, the image is valid for everyone.

Cons:

  • No colorful output bash prompt if .bashrc is not in workdir
    Since you didn’t create a user inside the image if you don’t mount your home directory as workdir inside the container, there will be no .bashrc file, which results in mono bash prompt. Or you can add the bash script to enable colorful prompt. Link
  • Long command line
export UID=$(id -u)
export GID=$(id -g)
docker run -it \
--user $UID:$GID \
--workdir="/home/$USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
<IMAGE NAME> /bin/bash

ps. It might show that UID is a read-only variable. You can neglect it.

Method 2: Add user in Docker Image

In this method we install and add a new user to sudo and pass the arguments from command line when building the docker image.

Pros:

  • Colorful bash prompt
    since adduser -m created a home directory, there is a .bashrc in it.

Cons:

  • The image is dependent on user id
    means, this image only works for users who have the same uid on different hosts. i.e. person_A has user id 1000. Person_B with user id other than 1000, for instance 1001, cannot use the image built by person_A.
  • Default password argument is not encrypted.
    Or instead of using useradd, directly COPY files related to password and user accounts into the image [Not tested]

Step1: Create Dockerfile

# Dockerfile
ARG DOCKER_BASE_IMAGE=<BASE IMAGE NAME>
FROM $DOCKER_BASE_IMAGE
ARG USER=docker
ARG UID=1000
ARG GID=1000
# default password for user
ARG PW=docker
# Option1: Using unencrypted password/ specifying password
RUN useradd -m ${USER} --uid=${UID} && echo "${USER}:${PW}" | \
chpasswd
# Option2: Using the same encrypted password as host
#COPY /etc/group /etc/group
#COPY /etc/passwd /etc/passwd
#COPY /etc/shadow /etc/shadow
# Setup default user, when enter docker container
USER ${UID}:${GID}
WORKDIR /home/${USER}

Step2: Build Image

# bash
export UID=$(id -u)
export GID=$(id -g)
docker build --build-arg USER=$USER \
--build-arg UID=$UID \
--build-arg GID=$GID \
--build-arg PW=<PASSWORD IN CONTAINER> \
-t <IMAGE NAME> \
-f <DOCKERFILE NAME>\
.

Step3: Enter container

with the host user when building the image
docker exec -it <IMAGE NAME> /bin/bash

with root
docker exec --user root --workdir /root -it <IMAGE NAME> /bin/bash

Method 3: Docker-compose

Pros:

  • Easy command line
  • No extra work to change the existing system or images
  • The image is independent to user id

Cons:

  • No colorful output bash prompt if .bashrc is not in workdir
    Need to create .bashrc (Link) workdir in an image or mount the .bashrc
    In the example, host user’s home directory is mounted, so we still get colorful prompt.

Step1: Create docker-compose.yml

docker-compose manual

# docker-compose.yml
version: '3'
services:
<SERVICE NAME>:
image: <BASE IMAGE NAME>
user: $UID:$GID
working_dir: $HOME
stdin_open: true
volumes:
- /etc/group:/etc/group:ro
- /etc/passwd:/etc/passwd:ro
- /etc/shadow:/etc/shadow:ro
tty: true
command: tail -f /dev/null

Step2: Start container

export UID=$(id -u)
export GID=$(id -g)
docker-compose -f docker-compose.yml up <SERVICE NAME>

Step3: Enter container

The command is the same as the one in method 2.

Extra: Grant user sudo privileges

Since the characteristic of containerization is clean environment, installing packages or some other action that required sudo privileges should be avoided. If it’s a permanent change, you should add command in Dockerfile and rebuild the image.

But if you are lazy or confident that you can keep the consistency between the image and current container, please see the below.

ps. Known issue with sudo with tty, docker actually suggests using gosu (Link)

Step1: Append the following to Dockerfile and build the image

RUN apt-get update && apt-get install -y sudo && \
adduser ${USER} sudo

Step2.1: Mount extra volume, when start container with docker run

--volume="/etc/sudoers.d:/etc/sudoers.d:ro"

Or

Step2.2: Add the last line under the volume tag in the docker-compose file

volumnes:
- ...
- ...
- /etc/sudoers.d:/etc/sudoers.d:ro

References

http://wiki.ros.org/docker/Tutorials/GUI

Running docker containers as current host user

Running a Docker container as a non-root user

specifying user and group in docker-i2e

How-to-use-sudo-inside-a-docker-container

SSH into container

ssh docker container

But not suitable for ROS developer, since the communication between nodes is based on randomly assigned ports. Therefore, the network_mode of container should be host, which allow container to use the network from host. Therefore, it is not possible to redirect container’s port 22 to host port 2222, for example.(Link)

Which ports are needed for ROS

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--