当前位置: 首页 > news >正文

非 root 用户运行 Docker 容器和同步主机和容器权限

非 root 用户运行 Docker 容器和同步主机和容器权限

简介

Docker 已成为开发者在可移植、一致的环境中创建、部署和运行应用程序的热门平台。
默认情况下,Docker 容器以 root 用户身份运行,如果容器受到攻击,这可能会带来安全风险。

此外,在主机和 Docker 容器之间共享文件夹时,以 root 用户身份运行可能会出现问题。

为了降低这些风险,我们将讨论如何使用自定义非 root 用户身份运行 Docker 容器,该用户身份与主机 Linux 用户的用户 ID (UID) 和组 ID (GID) 匹配,以确保已挂载文件夹的无缝权限处理。

我们将用ComfyUI代码仓库做案例,演示制作过程。

Dockerfile 添加普通用户

修改dockerfile文件,在构建镜像过程中使用普通用户,假设

  • 用户名是 aigc,用户组名 aigc
  • UID=1001, GID=1001

注意系统识别判别用户的机制是通过UID和GID,这点记住就好了。 OKAY,继续往下。

添加普通用户aigc

宿主机和容器内同时创建aigc用户

在Dockerfile文件中添加:

ARG UID=1001
ARG GID=1001
ENV USERNAME=aigc
RUN groupadd -g ${GID} ${USERNAME} && \
    useradd -l -u ${UID} -g ${GID} -m -s /bin/bash -N ${USERNAME}

这样操作的目的是:

  • 容器内用户和宿主机用户一致(适合挂载卷操作);
  • 避免默认 root 用户的安全隐患;
  • 默认进入用户 home 目录。

设置目录

在Dockerfile文件中添加:

ENV HOME_DIR=/home/${USERNAME}
ENV APP_DIR=${HOME_DIR}/app
ENV PIP_CACHE_DIR=${HOME_DIR}/.cache/pip

# 创建目录 + 修正权限
RUN mkdir -p ${HOME_DIR}  ${PIP_CACHE_DIR}  ${APP_DIR} && \
  chown -R ${USERNAME}:${USERNAME} ${HOME_DIR} ${APP_DIR}

创建你想要的目录,同时设置权限。

拷贝文件+设置权限

构建镜像时,免不了要拷贝文件

COPY --link  --chown=${USERNAME}:${USERNAME}  .  ${APP_DIR}
RUN chmod -R 755 ${APP_DIR}

COPY 文件时,用 --chown=aigc:aigc 来设置属主

同样要注意,不管是目录还是文件,都要设置权限。

COPY --link 是 Dockerfile 的 BuildKit 扩展功能,它的作用是:
📌 尽可能保留原始文件的硬链接关系(hard link),而不是创建一个新的复制文件。
✅ 简单解释:
通常,COPY 会复制文件的内容,新建一个文件副本。但使用 --link,Docker 会尝试让目标文件 和源文件共用 inode(即硬链接),从而:

  1. 减少镜像大小;
  2. 加快构建速度;
  3. 避免多余复制。

挂在目录

注意权限, 确保在宿主机里面,要挂在的目录权限是在aigc下。
示例 docker-compose.yml 片段:

services:
  comfyui:
    build: .
    image: comfyui:latest
    volumes:
      - ./data:/data  # 映射本地 data 文件夹
    user: "aigc:aigc"  # 容器进程以 aigc 用户身份运行

关于挂在目录权限问题,有很多方式处理,重点是权限要限制好
把宿主机的权限,锁死在aigc下

sudo chown -R aigc:aigc ./data

整版Dockerfile

FROM python:3.10-slim

# 设置无交互模式,避免 apt 安装过程中的提示卡住;
# 优先安装 wheel 格式的二进制包,加快 pip 安装速度。
ENV DEBIAN_FRONTEND=noninteractive
ENV PIP_PREFER_BINARY=1

ARG UID=1001
ARG GID=1001
ENV USERNAME=aigc
RUN groupadd -g ${GID} ${USERNAME} && \
    useradd -l -u ${UID} -g ${GID} -m -s /bin/bash -N ${USERNAME}

ENV HOME_DIR=/home/${USERNAME}
ENV APP_DIR=${HOME_DIR}/app
ENV PIP_CACHE_DIR=${HOME_DIR}/.cache/pip

# 创建目录 + 修正权限
RUN mkdir -p ${HOME_DIR}  ${PIP_CACHE_DIR}  ${APP_DIR} && \
  chown -R ${USERNAME}:${USERNAME} ${HOME_DIR} ${APP_DIR}
  
# 安装依赖
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

USER aigc
WORKDIR ${APP_DIR}

# pip 镜像(可选)
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/

# 克隆代码
RUN --mount=type=cache,target=${PIP_CACHE_DIR} \
  git clone https://github.com/comfyanonymous/ComfyUI.git . && \
  git checkout master && \
  git reset --hard 2f7d8159c32de22c15fbeea7ff9063f2231586bb && \

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 拷贝脚本并授权
COPY --chown=aigc:aigc ./entrypoint.sh /home/aigc/entrypoint.sh
RUN chmod +x /home/aigc/*.sh

ENV NVIDIA_VISIBLE_DEVICES=all \
  PYTHONPATH="${PYTHONPATH}:${PWD}" \
  CLI_ARGS=""
  
# 容器入口定义
ENTRYPOINT ["/home/aigc/entrypoint.sh"]
CMD ["python", "-u", "main.py", "--listen", "--port", "7860"  ${CLI_ARGS} ]

entrypoint.sh

#!/bin/sh

#!/bin/bash

set -Eeuo pipefail

# mkdir -vp /data/custom_nodes

declare -A MOUNTS

MOUNTS["${APP_DIR}/.cache"]="/data/.cache"
MOUNTS["${APP_DIR}/input"]="/data/input"
MOUNTS["${APP_DIR}/output"]="/data/output"
MOUNTS["${APP_DIR}/temp"]="/data/temp"

MOUNTS["${APP_DIR}/custom_nodes"]="/data/custom_nodes"
MOUNTS["${APP_DIR}/models"]="/data/models"

MOUNTS["${APP_DIR}/user/default/workflows"]="/data/user/default/workflows"

for to_path in "${!MOUNTS[@]}"; do
  set -Eeuo pipefail
  from_path="${MOUNTS[${to_path}]}"
  rm -rf "${to_path}"
  if [ ! -f "$from_path" ]; then
    mkdir -vp "$from_path"
  fi
  mkdir -vp "$(dirname "${to_path}")"
  ln -sT "${from_path}" "${to_path}"
  echo Mounted $(basename "${from_path}")
done

if [ -f "/data/config/comfy/startup.sh" ]; then
  pushd ${APP_DIR}
  . /data/config/comfy/startup.sh
  popd
fi

exec "$@"

docker-compose.yml

version: '3.8'
services:
  comfyui:
    build: .
    image: comfyui:latest
    container_name: comfyui
    ports:
      - "${WEBUI_PORT:-8188}:7860"
    volumes:
      - ./data:/data
    user: "aigc:aigc" # 容器进程以 aigc 用户身份运行
    stop_signal: SIGKILL
    tty: true
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: [ '0' ]
              capabilities: [ compute, utility ]
    environment:
      - CLI_ARGS=--port 7860 --disable-cuda-malloc
    extra_hosts:
      - "raw.githubusercontent.com:185.199.108.133"

宿主机,将aigc添加到docker组

为了让没有sudo权限的aigc执行docker命令,将将aigc添加到docker组

  • 添加用户到 docker 组
sudo usermod -aG docker aigc
groups aigc

-aG 表示追加用户到组而不是替换原有组。

  • 验证权限是否生效
docker run hello-world

END


学习交流

在这里插入图片描述

相关文章:

  • vue入门:插槽
  • AI 重构 Java 遗留系统:从静态方法到 Spring Bean 注入的自动化升级
  • ocr python库
  • 《深度剖析分布式软总线:软时钟与时间同步机制探秘》
  • git清理已经删除的远程分支
  • 大模型在儿童急性淋巴细胞白血病(ALL)-初治患者诊疗中应用的研究报告
  • git commit时自动生成Change-ID
  • XTuner学习
  • WHAT - Typescript 定义元素类型
  • 大数据(7.2)Kafka万亿级数据洪流下的架构优化实战:从参数调优到集群治理
  • 数据结构与算法之ACM Fellow-算法3.4 散列表
  • Unity 设置弹窗Tips位置
  • LLaMA-Factory从安装到微调全流程
  • Linux上搭建NFS共享存储
  • SpringBoot项目集成Seata 2.0.0
  • Kubernetes核心架构:从组件协同到工作原理
  • LED恒流驱动驱动电路原理图 LM3406HV-Q1
  • SpringBoot 为何启动慢
  • 第1课:MCP服务协议核心架构解析
  • Cursor中rules配置参考-202504版(含前后端Golang/TypeScript/Kotlin等)
  • 群晖nas可以做网站服务器/中国网民博客 seo
  • 呼和浩特免费制作网站/app下载免费安装
  • 为什么网站需要维护/百度西安分公司地址
  • 重庆中国建设监理协会网站/网站域名查询系统
  • 炫酷的企业网站模板免费下载/软文网站名称
  • 厦门网站做的比较好/舆情视频