无法在 docker Alpine 中添加具有高 UID 的用户



我正在尝试在Alpine Linux Docker容器中创建一个具有UID 1340816314的新用户,以便使具有与主机上的特定用户匹配UID的用户。

问题是,即使我按照 adduser 手册页重新定义UID_MAX /etc/login.defs 的值,我也面临着adduser: number 1340816314 is not in 0..256000 range。顺便说一下,我认为它没有任何影响,因为 Alpine 中的adduser命令来自 BusyBox。

这是我尝试做的日志:

$ 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

您知道如何在 Docker 容器中添加具有 Alpine Linux 中具有大UID的用户吗?

对于阿尔卑斯山的高 UID/GID,有一个更优雅的解决方案。

shadow包含useraddgroupadd实用程序,这些实用程序反过来支持更高的值。不确定这些实用程序的上限是什么,以及是否支持整个 2^32 空间,但我已经测试了超过 6 亿的值并且它可以工作。

例如,实现此目的的命令如下所示:

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

请注意,我将 shell 变量传递给useradd因为默认情况下它会尝试使用未安装的/bin/bash

这是一个有效但肮脏的解决方法,通过手动创建用户,使用 $UID_TO_SET 作为包含要设置的高UID的 bash 变量:

# Create user
echo "user:x:$UID_TO_SET:$UID_TO_SET::/home/user:" >> /etc/passwd
## thanks for http://stackoverflow.com/a/1094354/535203 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

虽然上面的"肮脏"方法确实有效,但它们很丑陋,对某些人来说不容易使用。复制和粘贴很容易出错。

因此,鉴于这与 Docker 有关,我有更好的方法来使用多阶段构建。

## 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

虽然此示例使用 debian,但您可以在第一阶段使用任何您想要的容器映像而不是 Debian。只要容器不会因为您使用的命令中的任意低 UID 限制而出错,它应该没问题,所以我鼓励您使用不同的容器作为基础映像,并检查 useraddadduser命令是否可用,以及哪一个可能支持您需要的 UID 编号。

这个问题实际上启发了我以某种方式解决它,对于获取长 ID 以在基于 Alpine 和 BusyBox 的 Docker 映像上工作的特定用例来说,这既方便又易于使用。

https://github.com/theAkito/userdef

示例用法:

## 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 []

阐述 @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}

最新更新