Can't add a user with a high UID in docker Alpine
Asked Answered
S

5

13

I'm trying to create a new user with UID 1340816314 inside an Alpine Linux Docker container in order to have a user with an UID matching a specific user on the host.

The problem is that I'm facing adduser: number 1340816314 is not in 0..256000 range even if I redefine the value of UID_MAX inside /etc/login.defs by following adduser man page. I don't think by the way that it has any impact as the adduser command in Alpine is from BusyBox.

Here is the log of what I try to do:

$ docker run -it --rm alpine:3.4 sh
/ # adduser -D -g '' -u 1340816314 user
adduser: number 1340816314 is not in 0..256000 range
/ # echo "UID_MAX 1340816314" > /etc/login.defs
/ # adduser -D -g '' -u 1340816314 user
adduser: number 1340816314 is not in 0..256000 range
/ # echo "UID_MAX 1340816315" > /etc/login.defs
/ # adduser -D -g '' -u 1340816314 user
adduser: number 1340816314 is not in 0..256000 range

Do you know how to add a user with a large UID in Alpine Linux inside a Docker container?

Sate answered 23/1, 2017 at 13:0 Comment(3)
Alpine uses the busybox adduser, which may simply be limited in the maximum value it supports. The man page you're reading isn't necessarily the correct one (other distributions have an adduser command which is not the same as the one provided by busybox).Hydrophobic
Can the person who downvoted my question explain why here?Sate
I don't know why you were downvoted. I'm having the same problem.Beseem
S
9

Here is a working but dirty workaround, by manually creating the user, using $UID_TO_SET as the bash variable containing the high UID to set:

# Create user
echo "user:x:$UID_TO_SET:$UID_TO_SET::/home/user:" >> /etc/passwd
## thanks for https://mcmap.net/q/234367/-get-current-date-in-epoch-from-unix-shell-script to compute the creation date
echo "user:!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow
echo "user:x:$UID_TO_SET:" >> /etc/group
mkdir /home/user && chown user: /home/user
Sate answered 9/2, 2017 at 10:4 Comment(0)
D
20

There is a more elegant solution to the high UID/GID in Alpine.

The package shadow contains the useradd and groupadd utilities which in turn supports higher values. Not sure which is the upper bound of those utils and if the whole 2^32 space is supported, but I've tested with values over 600 million and it works.

For example the commands to achieve this would look something like this:

UID=666000666
GID=999000999
apk add shadow
/usr/sbin/groupadd -g ${GID} my_group
/usr/sbin/useradd -s /bin/sh -g ${GID} -u ${UID} my_user

Note that I'm passing the shell variable to useradd as by default it tries to use /bin/bash which is not installed.

Delossantos answered 4/12, 2018 at 1:20 Comment(3)
Confirmed shadow does not support the full 2^32 space. It seems to max out at 2,147,483,647: github.com/shadow-maint/shadow/issues/165Skunk
While this seems to work inside the container, it doesn't work on the Dockerfile as I believe the container needs to be restarted after installing shadow so it replaces busybox.Challenging
Not a clean solution. Requires an additional package at build time and does not work reliably, as described in earlier comments. It's most reliable to just manually add the user/group to its respective file.Inspector
S
9

Here is a working but dirty workaround, by manually creating the user, using $UID_TO_SET as the bash variable containing the high UID to set:

# Create user
echo "user:x:$UID_TO_SET:$UID_TO_SET::/home/user:" >> /etc/passwd
## thanks for https://mcmap.net/q/234367/-get-current-date-in-epoch-from-unix-shell-script to compute the creation date
echo "user:!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow
echo "user:x:$UID_TO_SET:" >> /etc/group
mkdir /home/user && chown user: /home/user
Sate answered 9/2, 2017 at 10:4 Comment(0)
W
1

While the "dirty" methods above do work, they are ugly and not easy for some people to use. It would be easy to make a mistake with copy and paste.

So given that this is related to Docker, I've got a better way using multi-stage builds.

## Busybox adduser doesn't allow UIDs over 60000
## So we'll use a debian image to make the user
## And then copy the files and grep out the new user into the busybox container
FROM debian as base

RUN useradd -D -g '' -u 1340816314 user

FROM alpine as image

COPY --from=base /etc/passwd /root/passwd

RUN grep user /root/passwd >> /etc/passwd && rm -f /root/passwd

USER user

While this example uses debian, you can use any container image you want in the first stage instead of Debian. As long as the container doesn't error out because of an arbitrarily low UID limit in the command you use, it should be fine, so I encourage you to play around with different containers as the base image and also check if both useradd and adduser commands are available and which one might support the UID number you need.

Wheresoever answered 22/7, 2022 at 18:28 Comment(0)
I
0

This problem actually inspired me to solve it in a way, which is convenient and easy to use for this specific use case of getting long IDs to work on Alpine and BusyBox based Docker images.

https://github.com/theAkito/userdef

Example Usage:

## Get the binary.
## The default Docker Tag provides the Alpine (musl) based binary.
FROM akito13/userdef AS base
## Pull the image you want to modify the executing user of.
FROM gitea/gitea:1.16.5-linux-amd64-rootless

## We temporarily need to use the root user,
## as we are doing administrative tasks, like e.g. modifying an OS user.
USER root:root
COPY --from=base /userdef /userdef
## 1. Change the existing user.
## 2. Use that user to `chown` relevant folders.
## 3. Remove the binary, because the user has been changed,
##    i.e. our job is done here.
RUN /userdef -h=/var/lib/gitea/git -n=git -u=9234 -g=9234 && \
  chown git:git -R /var/lib/gitea /etc/gitea && \
  rm -f /userdef

## Switch to the now relevant executing user.
USER 9234:9234
## Taken from https://github.com/go-gitea/gitea/blob/66f2210feca0b50d305a46a203c2b3d2f4d3790b/Dockerfile.rootless#L71-L72
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD []
Inspector answered 8/4, 2022 at 5:44 Comment(0)
L
0

Elaboration on the only working answer from @anthony-o

# FOR UID higher than 60000, users need to be added like this!
RUN export GUID_TO_SET=100 && \     
    export UID_TO_SET=66666 && \
    export USER=youruser && \
    echo "${USER}:x:${UID_TO_SET}:${GUID_TO_SET}:Linux User,,,:/home/${USER}:/bin/sh" >> /etc/passwd && \
    echo "${USER}:!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow && \
    mkdir /home/${USER} && \
    chown ${USER}:${GUID_TO_SET} /home/${USER}
Lighter answered 12/7, 2022 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.