How do I add a user when I'm using Alpine as a base image?
I'm using alpine
(or an image that is based on Alpine) as the base image in my Dockerfile. Which instructions do I need to add to create a user?
Eventually I'll use this user to run the application I'll place into the container so that the root user does not.
Solution 1:
Alpine uses the command adduser
and addgroup
for creating users and groups (rather than useradd
and usergroup
).
FROM alpine:latest
# Create a group and user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Tell docker that all future commands should run as the appuser user
USER appuser
The flags for adduser
are:
Usage: adduser [OPTIONS] USER [GROUP] Create new user, or add USER to GROUP -h DIR Home directory -g GECOS GECOS field -s SHELL Login shell -G GRP Group -S Create a system user -D Don't assign a password -H Don't create home directory -u UID User id -k SKEL Skeleton directory (/etc/skel)
Add new user official docs
Solution 2:
The commands are adduser
and addgroup
.
Here's a template for Docker you can use in busybox environments (alpine) as well as Debian-based environments (Ubuntu, etc.):
ENV USER=docker
ENV UID=12345
ENV GID=23456
RUN adduser \
--disabled-password \
--gecos "" \
--home "$(pwd)" \
--ingroup "$USER" \
--no-create-home \
--uid "$UID" \
"$USER"
Note the following:
-
--disabled-password
prevents prompt for a password -
--gecos ""
circumvents the prompt for "Full Name" etc. on Debian-based systems -
--home "$(pwd)"
sets the user's home to the WORKDIR. You may not want this. -
--no-create-home
prevents cruft getting copied into the directory from/etc/skel
The usage description for these applications is missing the long flags present in the code for adduser and addgroup.
The following long-form flags should work both in alpine as well as debian-derivatives:
adduser
BusyBox v1.28.4 (2018-05-30 10:45:57 UTC) multi-call binary.
Usage: adduser [OPTIONS] USER [GROUP]
Create new user, or add USER to GROUP
--home DIR Home directory
--gecos GECOS GECOS field
--shell SHELL Login shell
--ingroup GRP Group (by name)
--system Create a system user
--disabled-password Don't assign a password
--no-create-home Don't create home directory
--uid UID User id
One thing to note is that if --ingroup
isn't set then the GID is assigned to match the UID. If the GID corresponding to the provided UID already exists adduser will fail.
addgroup
BusyBox v1.28.4 (2018-05-30 10:45:57 UTC) multi-call binary.
Usage: addgroup [-g GID] [-S] [USER] GROUP
Add a group or add a user to a group
--gid GID Group id
--system Create a system group
I discovered all of this while trying to write my own alternative to the fixuid project for running containers as the hosts UID/GID.
My entrypoint helper script can be found on GitHub.
The intent is to prepend that script as the first argument to ENTRYPOINT
which should cause Docker to infer UID and GID from a relevant bind mount.
An environment variable "TEMPLATE" may be required to determine where the permissions should be inferred from.
(At the time of writing I don't have documentation for my script. It's still on the todo list!!)
Solution 3:
There is package shadow
that brings useradd
& usermod
.
adduser
has some stupid limitations:
$ sudo adduser --disabled-password root
adduser: user 'root' in use
but usermod
not:
$ sudo apk add shadow
$ sudo usermod --unlock root