如何通过Jenkins环境变量为带Alpine/SFTP的Docker容器动态传入用户密码
针对你的需求,我整理了几个完全符合要求的可行方案,都是通过Jenkins环境变量传递密码到Docker容器,而且完全避开了Git存密码、Docker Compose/Services的限制:
方案1:Docker Run时通过
--env直接传递环境变量(最常用) 这是最直接的方式,Jenkins把凭证里的密码绑定成环境变量,然后在docker run命令里传递给容器,容器的启动脚本读取这些变量来创建用户。
步骤:
Jenkins端配置:
- 在Jenkins的凭证管理里添加Secret Text类型的凭证,分别存储SFTP和VSFTP的密码(用户名也可以存在凭证里,或者直接用固定值/另一个凭证)。
- 在构建任务的环境变量设置里,把凭证绑定为环境变量,比如
JENKINS_SFTP_USER、JENKINS_SFTP_PASS、JENKINS_VSFTP_USER、JENKINS_VSFTP_PASS,记得勾选“隐藏敏感参数”避免密码泄露。
Jenkins构建脚本:
在“执行shell”步骤里运行:docker run -d \ --name ftp-sftp-container \ -p 22:22 -p 21:21 -p 20:20 -p 30000-30010:30000-30010 \ --env SFTP_USERNAME=$JENKINS_SFTP_USER \ --env SFTP_PASSWORD=$JENKINS_SFTP_PASS \ --env VSFTP_USERNAME=$JENKINS_VSFTP_USER \ --env VSFTP_PASSWORD=$JENKINS_VSFTP_PASS \ your-custom-image:latest容器启动脚本(entrypoint.sh):
在你的Dockerfile里指定ENTRYPOINT ["/bin/bash", "/entrypoint.sh"],脚本内容如下:#!/bin/bash # 检查必要环境变量是否存在 if [ -z "$SFTP_USERNAME" ] || [ -z "$SFTP_PASSWORD" ] || [ -z "$VSFTP_USERNAME" ] || [ -z "$VSFTP_PASSWORD" ]; then echo "Error: Missing required credentials environment variables" exit 1 fi # 创建SFTP用户并设置密码 adduser -D $SFTP_USERNAME echo "$SFTP_USERNAME:$SFTP_PASSWORD" | chpasswd # 配置SFTP目录权限(根据你的需求调整) mkdir -p /home/$SFTP_USERNAME/sftp chown root:$SFTP_USERNAME /home/$SFTP_USERNAME chmod 755 /home/$SFTP_USERNAME chown $SFTP_USERNAME:$SFTP_USERNAME /home/$SFTP_USERNAME/sftp # 创建VSFTP用户并设置密码 adduser -D $VSFTP_USERNAME echo "$VSFTP_USERNAME:$VSFTP_PASSWORD" | chpasswd # 配置VSFTP用户目录(根据你的需求调整) mkdir -p /home/$VSFTP_USERNAME/ftp chown $VSFTP_USERNAME:$VSFTP_USERNAME /home/$VSFTP_USERNAME/ftp # 启动supervisord管理SFTP和VSFTP服务 exec /usr/bin/supervisord -c /etc/supervisord.conf
方案2:Jenkins生成临时密码文件,挂载到容器读取
如果你担心环境变量会通过ps命令在容器内暴露,可以用文件挂载的方式,Jenkins生成临时密码文件,容器启动时读取文件内容创建用户。
步骤:
Jenkins端配置:和方案1一样,把密码绑定为环境变量。
Jenkins构建脚本:
# 创建临时密码文件(注意:Jenkins的工作目录要有权限写入) cat > /tmp/ftp_creds.txt << EOF $JENKINS_SFTP_USER:$JENKINS_SFTP_PASS $JENKINS_VSFTP_USER:$JENKINS_VSFTP_PASS EOF # 运行容器时挂载这个文件 docker run -d \ --name ftp-sftp-container \ -p 22:22 -p 21:21 -p 20:20 -p 30000-30010:30000-30010 \ --mount type=bind,source=/tmp/ftp_creds.txt,target=/tmp/ftp_creds.txt,readonly \ your-custom-image:latest # Jenkins端删除临时文件(避免泄露) rm /tmp/ftp_creds.txt容器启动脚本调整:
修改entrypoint.sh里的用户创建逻辑:#!/bin/bash # 检查密码文件是否存在 if [ ! -f /tmp/ftp_creds.txt ]; then echo "Error: Credentials file not found" exit 1 fi # 读取密码文件创建用户 while IFS=: read -r username password; do adduser -D $username echo "$username:$password" | chpasswd # 根据用户名判断配置SFTP还是VSFTP(比如前缀区分) if [[ $username == sftp-* ]]; then # SFTP配置逻辑 mkdir -p /home/$username/sftp chown root:$username /home/$username chmod 755 /home/$username chown $username:$username /home/$username/sftp else # VSFTP配置逻辑 mkdir -p /home/$username/ftp chown $username:$username /home/$username/ftp fi done < /tmp/ftp_creds.txt # 删除容器内的临时密码文件 rm /tmp/ftp_creds.txt # 启动supervisord exec /usr/bin/supervisord -c /etc/supervisord.conf
方案3:容器启动后通过
docker exec传递密码(补充场景) 如果需要在容器启动后动态添加用户,或者不想在启动时传递密码,可以用docker exec在容器启动后执行创建用户的命令。
步骤:
Jenkins端配置:同样绑定密码为环境变量。
Jenkins构建脚本:
# 先启动容器(不带密码) docker run -d \ --name ftp-sftp-container \ -p 22:22 -p 21:21 -p 20:20 -p 30000-30010:30000-30010 \ your-custom-image:latest # 等待容器初始化完成(可选,避免命令执行过早) sleep 5 # 创建SFTP用户 docker exec ftp-sftp-container bash -c "adduser -D $JENKINS_SFTP_USER && echo '$JENKINS_SFTP_USER:$JENKINS_SFTP_PASS' | chpasswd && mkdir -p /home/$JENKINS_SFTP_USER/sftp && chown root:$JENKINS_SFTP_USER /home/$JENKINS_SFTP_USER && chmod 755 /home/$JENKINS_SFTP_USER && chown $JENKINS_SFTP_USER:$JENKINS_SFTP_USER /home/$JENKINS_SFTP_USER/sftp" # 创建VSFTP用户 docker exec ftp-sftp-container bash -c "adduser -D $JENKINS_VSFTP_USER && echo '$JENKINS_VSFTP_USER:$JENKINS_VSFTP_PASS' | chpasswd && mkdir -p /home/$JENKINS_VSFTP_USER/ftp && chown $JENKINS_VSFTP_USER:$JENKINS_VSFTP_USER /home/$JENKINS_VSFTP_USER/ftp" # 重启supervisord服务让配置生效(可选,根据你的服务配置) docker exec ftp-sftp-container bash -c "supervisorctl restart all"
关键注意事项:
- Jenkins凭证安全:所有密码必须存在Jenkins的凭证管理里,绝对不能硬编码在脚本或Git仓库中,绑定环境变量时一定要勾选“隐藏敏感参数”,避免密码出现在构建日志里。
- 容器内安全:不管用哪种方式,创建用户后尽量删除临时文件或确保环境变量不会被非授权用户读取(比如限制容器内用户权限)。
- Alpine兼容性:Alpine的
adduser和chpasswd命令参数和Debian系不同,要确保脚本适配Alpine的语法(比如adduser -D是创建无密码用户,然后用echo user:pass | chpasswd设置密码)。
内容的提问来源于stack exchange,提问作者SirStephanikus
相关产品推荐
相关产品推荐

