How to use sudo inside a docker container?

DockerSudoLinux Containers

Docker Problem Overview


Normally, docker containers are run using the user root. I'd like to use a different user, which is no problem using docker's USER directive. But this user should be able to use sudo inside the container. This command is missing.

Here's a simple Dockerfile for this purpose:

FROM ubuntu:12.04

RUN useradd docker && echo "docker:docker" | chpasswd
RUN mkdir -p /home/docker && chown -R docker:docker /home/docker
   
USER docker
CMD /bin/bash

Running this container, I get logged in with user 'docker'. When I try to use sudo, the command isn't found. So I tried to install the sudo package inside my Dockerfile using

RUN apt-get install sudo

This results in Unable to locate package sudo

Docker Solutions


Solution 1 - Docker

Just got it. As regan pointed out, I had to add the user to the sudoers group. But the main reason was I'd forgotten to update the repositories cache, so apt-get couldn't find the sudo package. It's working now. Here's the completed code:

FROM ubuntu:12.04

RUN apt-get update && \
      apt-get -y install sudo

RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

USER docker
CMD /bin/bash

Solution 2 - Docker

When neither sudo nor apt-get is available in container, you can also jump into running container as root user using command

docker exec -u root -t -i container_id /bin/bash

Solution 3 - Docker

The other answers didn't work for me. I kept searching and found a blog post that covered how a team was running non-root inside of a docker container.

Here's the TL;DR version:

RUN apt-get update \
 && apt-get install -y sudo

RUN adduser --disabled-password --gecos '' docker
RUN adduser docker sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER docker

# this is where I was running into problems with the other approaches
RUN sudo apt-get update 

I was using FROM node:9.3 for this, but I suspect that other similar container bases would work as well.

Solution 4 - Docker

For anyone who has this issue with an already running container, and they don't necessarily want to rebuild, the following command connects to a running container with root privileges:

docker exec -ti -u root container_name bash

You can also connect using its ID, rather than its name, by finding it with:

docker ps -l

To save your changes so that they are still there when you next launch the container (or docker-compose cluster) - note that these changes would not be repeated if you rebuild from scratch:

docker commit container_id image_name

To roll back to a previous image version (warning: this deletes history rather than appends to the end, so to keep a reference to the current image, tag it first using the optional step):

docker history image_name
docker tag latest_image_id my_descriptive_tag_name  # optional
docker tag desired_history_image_id image_name

To start a container that isn't running and connect as root:

docker run -ti -u root --entrypoint=/bin/bash image_id_or_name -s

To copy from a running container:

docker cp <containerId>:/file/path/within/container /host/path/target

To export a copy of the image:

docker save container | gzip > /dir/file.tar.gz

Which you can restore to another Docker install using:

gzcat /dir/file.tar.gz | docker load

It is much quicker but takes more space to not compress, using:

docker save container | dir/file.tar

And:

cat dir/file.tar | docker load

Solution 5 - Docker

if you want to connect to container and install something
using apt-get
first as above answer from our brother "Tomáš Záluský"

docker exec -u root -t -i container_id /bin/bash

then try to

> RUN apt-get update or apt-get 'anything you want'

it worked with me hope it's useful for all

Solution 6 - Docker

Here's how I setup a non-root user with the base image of ubuntu:18.04:

RUN \
    groupadd -g 999 foo && useradd -u 999 -g foo -G sudo -m -s /bin/bash foo && \
    sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
    echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "Customized the sudoers file for passwordless access to the foo user!" && \
    echo "foo user:";  su - foo -c id

What happens with the above code:

  • The user and group foo is created.
  • The user foo is added to the both the foo and sudo group.
  • The uid and gid is set to the value of 999.
  • The home directory is set to /home/foo.
  • The shell is set to /bin/bash.
  • The sed command does inline updates to the /etc/sudoers file to allow foo and root users passwordless access to the sudo group.
  • The sed command disables the #includedir directive that would allow any files in subdirectories to override these inline updates.

Solution 7 - Docker

If SUDO or apt-get is not accessible inside the Container, You can use, below option in running container.

docker exec -u root -it f83b5c5bf413 ash

"f83b5c5bf413" is my container ID & here is working example from my terminal:

enter image description here

Solution 8 - Docker

Unlike accepted answer, I use usermod instead.

Assume already logged-in as root in docker, and "fruit" is the new non-root username I want to add, simply run this commands:

apt update && apt install sudo
adduser fruit
usermod -aG sudo fruit

Remember to save image after update. Use docker ps to get current running docker's <CONTAINER ID> and <IMAGE>, then run docker commit -m "added sudo user" <CONTAINER ID> <IMAGE> to save docker image.

Then test with:

su fruit
sudo whoami

Or test by direct login(ensure save image first) as that non-root user when launch docker:

docker run -it --user fruit <IMAGE>
sudo whoami

You can use sudo -k to reset password prompt timestamp:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password

Solution 9 - Docker

This may not work for all images, but some images contain a root user already, such as in the jupyterhub/singleuser image. With that image it's simply:

USER root
RUN sudo apt-get update

Solution 10 - Docker

If you have a container running as root that runs a script (which you can't change) that needs access to the sudo command, you can simply create a new sudo script in your $PATH that calls the passed command.

e.g. In your Dockerfile:

RUN if type sudo 2>/dev/null; then \ 
     echo "The sudo command already exists... Skipping."; \
    else \
     echo -e "#!/bin/sh\n\${@}" > /usr/sbin/sudo; \
     chmod +x /usr/sbin/sudo; \
    fi

Solution 11 - Docker

There is no answer on how to do this on CentOS. On Centos, you can add following to Dockerfile

RUN echo "user ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user && \
    chmod 0440 /etc/sudoers.d/user

Solution 12 - Docker

An example Dockerfile for Centos7. In this example we add prod_user with privilege of sudo.

FROM centos:7

RUN yum -y update && yum clean all

RUN yum -y install openssh-server  python3 sudo

RUN adduser -m prod_user && \
    echo "MyPass*49?" | passwd prod_user --stdin && \
    usermod -aG wheel prod_user && \
    mkdir /home/prod_user/.ssh && \
    chown prod_user:prod_user -R  /home/prod_user/ && \
    chmod 700 /home/prod_user/.ssh

RUN echo "prod_user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers

RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config

RUN systemctl enable sshd.service

VOLUME [ "/sys/fs/cgroup" ]

ENTRYPOINT ["/usr/sbin/init"]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondrubbView Question on Stackoverflow
Solution 1 - DockerdrubbView Answer on Stackoverflow
Solution 2 - DockerTomáš ZáluskýView Answer on Stackoverflow
Solution 3 - DockerM. Scott FordView Answer on Stackoverflow
Solution 4 - DockerChrisView Answer on Stackoverflow
Solution 5 - DockerIsmailView Answer on Stackoverflow
Solution 6 - DockerSeth BergmanView Answer on Stackoverflow
Solution 7 - DockerYogi GhorechaView Answer on Stackoverflow
Solution 8 - Docker林果皞View Answer on Stackoverflow
Solution 9 - DockerAlex KaszynskiView Answer on Stackoverflow
Solution 10 - DockerXtraSimplicityView Answer on Stackoverflow
Solution 11 - DockerAnimeshView Answer on Stackoverflow
Solution 12 - DockerErkan ŞirinView Answer on Stackoverflow