You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中无法以gitlab-runner用户运行supervisorctl命令求助

解决以gitlab-runner用户运行supervisorctl的权限问题

问题背景

我有如下Dockerfile:

FROM 2.dkr.ecr.us-east-1.amazonaws.com/pa-amazonlinux:latest
# FROM amazonlinux:2

# install core packages
RUN yum update -y && \
    amazon-linux-extras install -y python3.8 postgresql14 nginx1 epel && \
    yum install -y gcc git openldap-devel openssl-devel crontabs python38-devel mariadb-devel supervisor which tar python2-requests

# install extra packages
RUN yum install -y libpq-devel libaio

ENV PATH "$PATH:~/.local/bin"
#RUN useradd -ms /bin/bash gitlab-runner
#RUN usermod -aG wheel gitlab-runner

WORKDIR /app/pa
# copy over our source code
COPY . /app/pa/

# copy over configuration
COPY nginx.conf /etc/nginx/


# create directories used by the app
RUN mkdir /var/log/pa && \
    mkdir /var/www && \
    mkdir /var/www/pa
RUN mkdir /virtualenvs

RUN chown -R gitlab-runner:gitlab-runner /var/log/pa
RUN chown -R gitlab-runner:gitlab-runner /var/www
RUN chown -R gitlab-runner:gitlab-runner /var/www/pa
RUN chown -R gitlab-runner:gitlab-runner /virtualenvs

# setup virtual environment for the app
RUN python3.8 -m venv /virtualenvs/pa && \
    source /virtualenvs/pa/bin/activate && \
    pip install -r requirements/base.txt

RUN ldconfig

RUN chmod u+x docker_entrypoint.sh

RUN echo "NETWORKING=yes" > /etc/sysconfig/network

对应的docker_entrypoint.sh:

NAME="maestro_ecs"
echo "$ENVIRONMENT"
DJANGODIR=/app/platform_analytics
service=ecs
echo "Starting $NAME as `whoami`"
tag_filter="ma-ecs-"$ENVIRONMENT

# Get the list of runners with the specified tag
page=1
per_page=100


printenv | grep -v "no_proxy" >> /etc/environment

cd $DJANGODIR
# awslogs installation

echo -e "log_group_name = /ecs/ma-$ENVIRONMENT" >> awslogs.conf
echo "Setting up awslogs"
echo -e "Amazon Linux AMI\n$(cat /etc/issue)" > /etc/issue
curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/AgentDependencies.tar.gz -O
tar xvf AgentDependencies.tar.gz -C /tmp/
python ./awslogs-agent-setup.py --region us-east-1 --dependency-path /tmp/AgentDependencies -c awslogs.conf -n

echo "Setting up virtual environment"
source /virtualenvs/platform_analytics/bin/activate
python manage.py collectstatic --noinput

echo "starting gitlab-runner installation"
yum install wget -y
yum install jq -y

echo "starting wget installation"
wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
chmod +x /usr/local/bin/gitlab-runner

echo "unregister all active runners"
gitlab-runner unregister --all-runners

# below line of code will remove any previous zombie runners registered by dead containers
offline_runners=$(curl -s --header "PRIVATE-TOKEN:${gitlab_runner_api_access_token}" "${GitlabRunnerUrl}api/v4/runners?tag_list=${tag_filter}&page=${page}&per_page=${per_page}" | jq -r '.[] | .id')
# Iterate over each offline runner and remove it
for runner_id in $offline_runners; do
  echo "Removing runner ID: ${runner_id}"
  curl -s --header "PRIVATE-TOKEN:${gitlab_runner_api_access_token}" --request DELETE "${GitlabRunnerUrl}api/v4/runners/${runner_id}"
done
chown -R gitlab-runner:gitlab-runner /etc
useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
usermod -aG root gitlab-runner
mkdir /opt/gitlab
/usr/local/bin/gitlab-runner install --user gitlab-runner --working-directory=/opt/gitlab
/usr/local/bin/gitlab-runner start
/usr/local/bin/gitlab-runner register \
                --non-interactive \
                --url ${GitlabRunnerUrl} \
                --registration-token ${GitlabRunnerTokenForService} \
                --executor shell \
                --name ${GitlabRunnerName} \
                --docker-pull-policy always \
                --locked=false \
                --run-untagged=false \
                --docker-privileged=true \
                --limit 1 \
                --tag-list ${GitlabRunnerName}
/usr/local/bin/gitlab-runner restart
chown gitlab-runner /opt/gitlab
chmod -R 777 /opt/gitlab
chmod -R 777 /app/


echo "Starting supervisord"
# this is running as background process
supervisord &

echo "Starting nginx as foreground"
nginx
#
echo "Forever nginx"

希望以gitlab-runner用户运行supervisorctl等命令时遭遇权限拒绝,尝试以该用户安装supervisor需要root权限,但部署阶段无法获取root权限,需要解决办法。


解决方案

1. 镜像构建阶段完成用户创建与权限配置

Docker构建阶段默认以root身份运行,可在此完成supervisor安装和权限配置,无需部署阶段处理:
修改Dockerfile,恢复gitlab-runner用户创建代码,并添加supervisor相关目录的权限调整:

ENV PATH "$PATH:~/.local/bin"
# 创建gitlab-runner用户并加入wheel组
RUN useradd -ms /bin/bash gitlab-runner
RUN usermod -aG wheel gitlab-runner

WORKDIR /app/pa
COPY . /app/pa/
COPY nginx.conf /etc/nginx/

# 创建并配置supervisor所需目录权限
RUN mkdir -p /var/log/supervisor /etc/supervisor.d /opt/gitlab/supervisor
RUN chown -R gitlab-runner:gitlab-runner /var/log/supervisor /etc/supervisor.d /opt/gitlab/supervisor

# 创建应用目录并调整权限
RUN mkdir /var/log/pa /var/www /var/www/pa /virtualenvs
RUN chown -R gitlab-runner:gitlab-runner /var/log/pa /var/www /virtualenvs

2. 修改supervisor核心配置

编辑/etc/supervisord.conf(可在Dockerfile中替换或修改),确保所有路径和权限适配gitlab-runner用户:

[unix_http_server]
file=/opt/gitlab/supervisor/supervisord.sock  # 放在gitlab-runner有权限的目录
chmod=0760
chown=gitlab-runner:gitlab-runner

[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/opt/gitlab/supervisor/supervisord.pid
user=gitlab-runner  # 指定运行用户
nodaemon=false

[supervisorctl]
serverurl=unix:///opt/gitlab/supervisor/supervisord.sock  # 匹配socket路径

3. 调整entrypoint脚本,以gitlab-runner启动supervisord

删除entrypoint中重复创建gitlab-runner用户的代码(已在构建阶段完成),修改supervisord启动命令,切换到gitlab-runner用户:

# 替换原supervisord启动代码
echo "Starting supervisord as gitlab-runner"
su gitlab-runner -c "supervisord &"

若需更安全的用户切换,可在Dockerfile中安装gosu,然后用gosu启动:

# Dockerfile中添加
RUN yum install -y gosu
# entrypoint中替换为
echo "Starting supervisord as gitlab-runner"
gosu gitlab-runner supervisord &

4. 配置supervisorctl访问权限

gitlab-runner用户可直接运行supervisorctl,若需指定socket路径,使用:

supervisorctl -s unix:///opt/gitlab/supervisor/supervisord.sock status

5. 清理entrypoint冗余代码

删除entrypoint中以下冗余代码(已在构建阶段完成):

chown -R gitlab-runner:gitlab-runner /etc
useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
usermod -aG root gitlab-runner

内容的提问来源于stack exchange,提问作者Mahak Malik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:08:11