How to add user with dockerfile? - docker

How can I add a user with Dockerfile - the following does not work.
USER vault
WORKDIR /usr/local/bin/vault
My full Dockerfile:
FROM alpine:3.4
RUN apk update && apk add curl unzip
RUN useradd -ms /bin/bash vault
USER vault
WORKDIR /usr/local/bin/vault
ADD /vault.hcl /etc/vault/vault.hcl
RUN curl -SL https://releases.hashicorp.com/vault/0.5.0/vault_0.5.0_linux_amd64.zip > vault.zip
RUN unzip vault.zip -d /usr/local/bin && rm vault.zip

Use useradd instead of its interactive adduser to add user.
RUN useradd -ms /bin/bash vault
Below command will not create user .
USER vault
WORKDIR /usr/local/bin/vault
it will use vault user
please Refer Dockerfile User Documentation
The USER instruction sets the user name or UID to use when running the
image and for any RUN, CMD and ENTRYPOINT instructions that follow it
in the Dockerfile.
NOTE : Ensures that bash is the default shell.
If default shell is /bin/sh you can do like:
RUN ln -sf /bin/bash /bin/sh
RUN useradd -ms /bin/bash vault

To add group and to associate a new user, use code below.
FROM <base image>
RUN groupadd -g 2000 go \
&& useradd -m -u 2001 -g go go
USER go
OR
RUN addgroup -g 1001 -S appuser && adduser -u 1001 -S appuser -G appuser

If you also want your user to have a password, use this for Alpine based-images:
FROM alpine
ARG USER=usernameThatYouWant
ARG PASS="some password"
RUN adduser -D $USER && echo "$USER:$PASS" | chpasswd
The ARG lines are there so you can (optionally) choose another username and password when building the image (without having to change the Dockerfile).
-D so that adduser doesn't set a password just yet.Without this option adduser would become interactive and ask for a password. It doesn't accept this from the regular STDIN, so piping the password is also not an option.
echo "$USER:$PASS" | chpasswd to finally set the password.
Note that I do not set a shell with -s /path/to/some/shell in adduser because Alpine only has ash and sh available. Both of these are just symlinks to busybox anyway.(But if you are going to install another shell in your image you probably do want to use it.)
For Ubuntu-based images use this:
FROM ubuntu
ARG USER=usernameThatYouWant
ARG PASS="some password"
RUN useradd -m -s /bin/bash $USER && echo "$USER:$PASS" | chpasswd
I am using:
useradd because here this is the program for non-interactive usage.
-m so that we the user has a homedir.
-s /bin/bash so that the user has bash as default shell.
(For most other base-images you will also need to use the Ubuntu-method )

Related

Docker CMD cannot add new user, permission denied

I have a docker image that at the end launch this script:
# Start the server
CMD [ "bash", "/app/start.sh"]
And then my script start.sh
# Create ssh user
useradd -m -d /home/${SSH_MASTER_USER} -G ssh ${SSH_MASTER_USER} -s /bin/bash
echo "${SSH_MASTER_USER}:${SSH_MASTER_PASS}" | chpasswd
echo 'PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin"' >> /home/${SSH_MASTER_USER}/.profile
And I keep getting this error:
useradd: Permission denied.
useradd: cannot lock /etc/passwd; try again later.
If run with sudo it says:
sudo: no tty present and no askpass program specified
Tried to fix it like this:
sudo -S useradd -m -d /home/${SSH_MASTER_USER} -G ssh ${SSH_MASTER_USER} -s /bin/bash
But now is asking me for a password, but there is not password...
my base image is using root.
so i am adding appuser and installing sudo like this:
RUN adduser --disabled-password --gecos "" appuser
RUN apt-get update
RUN apt-get install -y sudo
RUN echo "appuser ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/appuser && chmod 0440 /etc/sudoers.d/appuser
Later on when you ready to use new user for all commands:
USER appuser:appuser
that is it, now appuser which is going to be user by default can use sudo without password.
I have solved by adding my existing user to the sudo group:
RUN echo "myUser ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/docker && chmod 0440 /etc/sudoers.d/docker
then the:
sudo -S useradd -m -d /home/${SSH_MASTER_USER} -G ssh ${SSH_MASTER_USER} -s /bin/bash
worked without password

How do I set the password of an account in a Dockerfile?

ENV USERNAME ros
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
My goal is to have an account with sudo privileges.
The context is that I am trying to create a Docker image with a working installation of ROS. The ROS installation is complicated and includes running many commands and scripts. I know the above statement is probably wrong because it is creating files with owner ros and group sudo.
Although I agree with the comments saying that in the majority of cases you avoid sudo in Docker, I also had the same situation where I needed to have a non-root user with passwordless sudo privileges inside Docker.
This is my Dockerfile that defines a sudo user
This is the relevant part from it:
# Set a passwordless sudoer user
RUN adduser --disabled-password --gecos "" ubuntu && \
usermod -aG sudo ubuntu && \
echo "%sudo ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/nopasswd
# Start the container as the user
WORKDIR /home/ubuntu
USER ubuntu
CMD bash
Hope this helps.

Dockerfile, groupadd with GUI parameter

I am trying to add group with id declared in dockerfile, however I always get error:
groups: cannot find name for group ID 1001
My dockerfile:
FROM python:3.7.1
ARG UID=1001
RUN apt-get update && apt-get install -y openssh-server sudo
RUN mkdir /var/run/sshd
RUN echo 'root:pycharm' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's#session\s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' -i /etc/pam.d/sshd
RUN groupadd -r charm -g 1001
RUN useradd -ms /bin/bash charm -g charm -u 1001
RUN echo "export VISIBLE=now" >> /etc/profile
ADD helpers /opt/.pycharm_helpers
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
Error message I get when I try to enter container with:
docker exec -ti -u 1001 pydebug1 bash
Group doesn't exists in /etc/group file. When I run commands inside container then works but I want to have them inside Dockerfile.
Saved your dockerfile content in Dockerfile and touched a file with name helpers.
Then build the image and enter into the image. Screen shot shows 2nd build, commit hash etc and id from the image. You can see all the commands in screen shot.
You may build as docker build -t pydebug1 . as well.

Dockerfile overriding env var at "docker run" time

Dockerfile
FROM ubuntu
ENV UID "1234"
ENV USERNAME "default"
RUN addgroup $USERNAME && useradd -u $UID -g $USERNAME -ms /bin/bash $USERNAME
CMD ["/usr/bin/id", "-u", "myname"]
and running docker via:
docker build -t setuser .
docker run -e UID=5555 -e USERNAME=myname setuser
OUTPUT
/usr/bin/id: 'myname': no such user
this error tells me that useradd in Dockerfile was not executed during "docker run" time.
how could I achieve this?
CMD ["/usr/bin/id", "-u", "default"] works but i want to be able to supply the UID and USERNAME at run time, not at Dockerfile build time
To elaborate Henry's answer
Following portion of your Dockerfile executed when you build your image.
FROM ubuntu
ENV UID "1234"
ENV USERNAME "default"
RUN addgroup $USERNAME && useradd -u $UID -g $USERNAME -ms /bin/bash $USERNAME
So, this time, UID=1234 & USERNAME=default are set.
When you run your image, It starts with ENTRYPOINT & CMD. It has no effect on RUN addgroup $USERNAME ...
So you need to run a script to use your passing ENV.
#!/bin/bash
addgroup $USERNAME && useradd -u $UID -g $USERNAME -ms /bin/bash $USERNAME
id -u $USERNAME
Here, your passing ENV values will be used.
The useradd was executed when the image was created. If you want to run some commands when the container is started put them into a script that is executed at start time.

How to use sudo inside a docker container?

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
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
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
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.
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
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
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
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.
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:
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
The main idea is that you need to create user that is a root user according to the container.
Main commands:
RUN echo "bot:bot" | chpasswd
RUN adduser bot sudo
the first sends the literal string bot:bot to chpasswd which creates the user bot with the password bot, chpasswd does:
The chpasswd command reads a list of user name and password pairs from standard input and uses this information to update a group of existing users. Each line is of the format:
user_name:password
By default the supplied password must be in clear-text, and is encrypted by chpasswd. Also the password age will be updated, if present.
The second command I assume adds the user bot as sudo.
Full docker container to play with:
FROM continuumio/miniconda3
# FROM --platform=linux/amd64 continuumio/miniconda3
MAINTAINER Brando Miranda "me#gmail.com"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ssh \
git \
m4 \
libgmp-dev \
opam \
wget \
ca-certificates \
rsync \
strace \
gcc \
rlwrap \
sudo
# https://github.com/giampaolo/psutil/pull/2103
RUN useradd -m bot
# format for chpasswd user_name:password
RUN echo "bot:bot" | chpasswd
RUN adduser bot sudo
WORKDIR /home/bot
USER bot
#CMD /bin/bash
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
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"]
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
I'm using an Ubuntu image, while using the docker desktop had faced this issue.
The following resolved the issue:
apt-get update
apt-get install sudo

Resources