Docker中使用gosu的方法详解

 更新时间:2025年10月10日 10:56:53   作者:雲帝  
在Docker镜像中启动服务时,我们通常不希望以root身份运行主进程,sudogosu是一个非常轻量的工具,功能类似sudo,但不会产生额外进程,非常适合在Docker容器中用来切换用户,本文给大家介绍Docker中使用gosu的方法,感兴趣的朋友一起看看吧

Docker中使用gosu

为什么要用 gosu?

在 Docker 镜像中启动服务时,我们通常不希望以 root 身份运行主进程。

问题

  • 构建镜像时通常需要 root 权限;
  • 启动时希望进程使用普通用户运行;
  • 容器中使用 sudo 会产生额外的中间进程,导致信号转发不正常;
  • 最终可能出现僵尸进程、容器无法优雅退出等问题。

gosu 是一个非常轻量的工具,功能类似 sudo,但不会产生额外进程,非常适合在 Docker 容器中用来切换用户。

注意事项

  1. 创建专用普通用户,不要直接使用 root。
  2. 在 entrypoint 中使用 gosu 切换用户,不要用 sudo。
  3. 使用 exec 启动主进程,保证 PID=1 是应用本身。
  4. 正确接收 SIGTERM 信号,避免僵尸进程。
  5. 不要在 Docker 中滥用 sudo

sudo vs gosu:真实对比

使用 gosu

docker run --rm gosu/alpine gosu root ps aux

输出:

PID   USER     TIME  COMMAND
1     root     0:00  ps aux

  • ps 命令的 PID 是 1,容器内只有一个进程。
  • 这样当宿主机发送 SIGTERM 信号时,应用能直接接收到。

使用 sudo

docker run --rm ubuntu:trusty sudo ps aux

输出:

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0  46012  1772 ?        Rs   12:05   0:00 sudo ps aux
root          6  0.0  0.0  15568  1140 ?        R    12:05   0:00 ps aux

  • 容器内出现两个进程,PID=1 被 sudo 占用。
  • 应用进程的 PID 不为 1,无法直接接收信号。
  • 当执行 docker stop 时,信号发送给的是 sudo,而不是应用进程,可能导致应用残留为僵尸进程。

对比

项目gosusudo
进程数12
PID=1应用进程sudo
信号转发正常不正常
僵尸进程风险
适合容器使用

Dockerfile 安装 gosu

在 Dockerfile 中添加如下步骤即可:

FROM ubuntu:22.04
# 安装 gosu
RUN apt-get update && apt-get install -y gosu curl ca-certificates && rm -rf /var/lib/apt/lists/*
# 创建普通用户
RUN groupadd -r tempuser && useradd -r -g tempuser tempuser
# 拷贝入口脚本
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# 验证 gosu 是否工作
RUN gosu nobody true
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

entrypoint.sh 的写法

entrypoint.sh 是容器启动脚本。

#!/usr/bin/env bash
set -e
# 使用 gosu 切换用户身份
if [ "$1" = "start-app" ]; then
    echo "Running application as tempuser..."
    exec gosu tempuser /app/my_server
fi
# 如果有其他命令,直接执行
exec "$@"

注意:exec 会让当前 shell 被新进程取代,保证应用进程的 PID=1。

构建 & 运行容器

docker build -t myapp .
docker run --rm -p 8080:8080 myapp start-app

容器内:

  • /app/my_server 的 PID = 1
  • 收到 docker stop 的信号时,能正确退出
  • 不会残留 sudo 或 shell 僵尸进程

信号量与僵尸进程问题

容器启动时 PID=1 的进程非常特殊,它负责接收来自宿主机的信号(例如 SIGTERMSIGINT)。

  • 如果 PID=1 是 sudo,信号不会传给应用;
  • 如果 PID=1 是应用进程本身,就能优雅退出;
  • 使用 exec + gosu 可以保证 PID=1 是你的应用;
  • 避免使用 shell 包一层后 & 运行后台进程的错误做法。

常见问题

问题原因解决方法
容器退出时残留僵尸进程PID=1 不是应用进程使用 exec + gosu
docker stop 不生效信号被 sudo 拦截不使用 sudo,PID=1 改为应用
gosu 报权限错误二进制无执行权限chmod +x /usr/local/bin/gosu
切换用户失败用户不存在使用 useradd 创建对应用户

参考资料

到此这篇关于Docker中使用gosu的文章就介绍到这了,更多相关docker使用gosu内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Docker容器生命周期相关命令及实践详解

    Docker容器生命周期相关命令及实践详解

    Docker容器生命周期管理是Docker平台中的一项关键功能,它涉及对容器的创建、运行、监控以及销毁等各个阶段的操作,这篇文章主要介绍了Docker容器生命周期相关命令及实践详解的相关资料,需要的朋友可以参考下
    2025-11-11
  • docker bashrc文件的合理配置方案详解

    docker bashrc文件的合理配置方案详解

    本文给大家详细介绍docker bashrc文件的合理配置方案详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-10-10
  • win7环境下Docker快速构建及阿里云容器加速配置详解

    win7环境下Docker快速构建及阿里云容器加速配置详解

    这篇文章主要介绍了win7环境下Docker快速构建及阿里云容器加速配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 利用Dockerfile制作个人的镜像文件详细讲解

    利用Dockerfile制作个人的镜像文件详细讲解

    Docker是一个开源的应用容器引擎,Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本,本文将给大家详细介绍如何利用Dockerfile制作个人的镜像文件,感兴趣的同学可以借鉴参考
    2023-06-06
  • docker安装drone的实现示例

    docker安装drone的实现示例

    Drone是一款基于Docker的持续集成和持续部署平台,可以帮助开发者自动化构建、测试和部署应用程序,本文主要介绍了docker安装drone的实现示例,感兴趣的可以了解一下
    2023-12-12
  • 云原生Docker容器自定义DNS解析

    云原生Docker容器自定义DNS解析

    Docker没有为每个容器专门定制镜像,那么怎么自定义配置容器的DNS配置呢?这篇文章主要给大家介绍了关于云原生Docker容器自定义DNS的相关资料,需要的朋友可以参考下
    2023-02-02
  • Docker Compose最常用命令(直接复制用)

    Docker Compose最常用命令(直接复制用)

    Docker Compose是Docker官方提供的一个用于管理多个容器的工具,可以使用docker-compose.yml文件定义和运行多容器应用,这篇文章主要介绍了Docker Compose最常用命令的相关资料,需要的朋友可以参考下
    2025-11-11
  • docker部署nginx访问宿主机服务并使用缓存的操作方法

    docker部署nginx访问宿主机服务并使用缓存的操作方法

    这篇文章主要介绍了docker部署nginx访问宿主机服务并使用缓存的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,感兴趣的朋友一起看看吧
    2024-04-04
  • 2026年Docker常用命令及示例代码大全

    2026年Docker常用命令及示例代码大全

    本文详细介绍了Docker常用命令的使用方法,包括启动、关闭、重启Docker服务,查看Docker状态和版本,运行和管理容器,管理镜像,创建和删除容器,操作,查看和管理网络,及DockerCompose的使用,文中提供了大量示例,方便用户快速了解和掌握Docker的各项功能和命令
    2026-05-05
  • IDEA集成Docker实现一键部署全过程

    IDEA集成Docker实现一键部署全过程

    本文详细介绍了如何在IntelliJ IDEA中集成Docker并实现一键部署代码的步骤,包括安装Docker、配置服务器、IDEA配置、添加Dockerfile、运行配置以及一键部署
    2024-11-11

最新评论