如何让docker容器启动时用自定义的用户

最近在处理项目时,遇到一个比较难搞的事情,项目时微服务架构的,很多服务都是用同一个java的基础镜像来构建的,服务镜像已经打好了,但是客户现场要求用自己定义的用户来启动,不能用我们构建镜像时指定的用户来启动,不可能每个镜像都去重新打包,一方面是因为镜像程序太多,另外一方面,不可能为了一个客户单独维护一份Jenkins流水线,那剩下的唯一的一条路,就是在镜像启动时执行一些脚本了和赋权了

1. 修改容器启动的docker-compose.yml

1)获取启动的自定义账号的uid、gid,在此以ywgl为例

ywgl 账号登录操作系统,执行命令id

bash 复制代码
su ywgl
id

2. 上传gosu文件到容器所在服务器,停掉容器

gosu 是一个专为容器环境设计的轻量级用户切换工具(类似 su/sudo,但更适合 Docker)。它的核心定位是:"以 Root 启动做初始化,最终降权以普通用户运行主程序"

2)上传docker-entrypoint.sh 、gosu 到cwos目录,

给账号权限:

bash 复制代码
chown -R ywgl:ywgl docker-entrypoint.sh
chown -R ywgl:ywgl gosu

给执行权限:

bash 复制代码
chmod +x docker-entrypoint.sh
chmod +x gosu

3)修改容器应用的docker-compose.yml 文件

yaml 复制代码
version: '3'
services:
  nginx:
    image: xxxxxxxxxxx/ai_docker_release/jcyw/nginx:R1.24.0.cwos
    container_name: "nginx"
    network_mode: bridge
    restart: always
    user: "0:0"   ##使用root用户进行=前置初始化
    ports:
      - 80:8080
      - 443:10444
      - 38760:38760

    environment:
      - "LANG=en_US.UTF-8"
      - USER_ID=2025   # 自动获取宿主机UID
      - GROUP_ID=2025   # 自动获取宿主机GID
      - GROUP_NAME=ywgl   # 自动获取宿主机组名
      - USER_NAME=ywgl   # 自动获取宿主机用户名

    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./logs:/var/log/nginx:z
      - /etc/hosts:/etc/hosts:ro
      - ./ssl:/etc/nginx/ssl:z
      - ./nginx.conf:/etc/nginx/nginx.conf:z
      - ./conf.d:/etc/nginx/conf.d:z
      - /data/cwos/h5live:/data/cwos/h5live
      - /data/cwos/video:/data/cwos/video
      - ../gosu:/usr/local/bin/gosu   ##把gosu文件映射到容器内部
      - ./nginx-entrypoint.sh:/docker-entrypoint.sh   ##容器文件初始化和权限降权的脚本
    entrypoint: ["/docker-entrypoint.sh"]   ##在启动时执行的脚本,注意和上面映射的路径必须完全一致

    command:
      - nginx
      - -g
      - daemon off;
    working_dir: /tmp/nginx-1.24.0
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

docker-entrypoint.sh文件的内容大致如下:

脚本说明:

1、容器启动时默认是 Root。脚本前半部分读取了 docker-compose 传入的环境变量(USER_NAME=ywg1, USER_ID=2025 等),动态创建用户和组,并 chown 相关目录(如 /var/cache/nginx、/etc/nginx),确保目录权限匹配

2、sh -c 'exec "@"′−−"@"' -- "@"′−−"@":在目标用户下启动 Shell 并执行原参数。0代表脚本本身或传入的命令,0 代表脚本本身或传入的命令,0代表脚本本身或传入的命令,@ 代表所有参数。

实际效果:结合 docker-compose 的 command: nginx -g daemon off;,这句最终等价于:以 ywg1 用户身份启动 Nginx。

3. 删除容器已有的logs,重新启动程序

4)换账号到ywgl,删除logs文件夹下的日志文件,重启应用

停止:docker-compose down

启动:docker-compose up -d

5)功能验证,nacos功能正常,日志生成账号为启动账号ywgl

修改后启动脚本后的,重新启动nginx容器生成的日志的信息

相关推荐
3095566665 小时前
股票接口返回 404 与空数组的排查笔记:证书状态与级别参数
java·笔记·python·ios·iphone·股票数据api·股票数据接口
nice_lcj5205 小时前
MySQL 存储引擎入门:InnoDB 和 MyISAM 到底怎么选
java·数据库·mysql·面试·innodb·存储引擎·myisam
文丑颜不良啊5 小时前
LeetCode2861~2880题目解析
java·leetcode
装不满的克莱因瓶5 小时前
设计模式之策略模式核心概念和应用场景
java·后端·设计模式·架构·系统架构·策略模式
晴天的雨.9925 小时前
【C++】继承篇
java·开发语言·c++
SomeOtherTime5 小时前
第 1 讲:内存布局与所有权解剖——栈帧、胖指针与“移动/拷贝”在汇编层面的真实面目
java·开发语言·汇编
qq_406981035 小时前
c++ lamda(三)Lambda表达式
java·前端·c++
头发还在的女程序员5 小时前
Java在线租房系统源码解析:Spring Boot+Vue 3+UniApp房源管理与预约看房方案
java·vue.js·spring boot·租房小程序·租房系统·租房软件
FYKJ_20105 小时前
springboot同人周边订单管理系统48955-计算机毕业设计、课程设计
java·javascript·vue.js·spring boot·django·php·课程设计
Flynn Liang6 小时前
LLM 应用安全:Prompt 注入、越权与输入输出护栏
java·人工智能·大模型·langchain4j·llm 安全·prompt 注入·guardrail