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

Docker部署Django应用时wait-for-it.sh脚本权限拒绝问题求助

Docker部署Django应用时wait-for-it.sh脚本权限拒绝问题求助

各位好,我现在在用Docker部署Django应用,但是执行检查PostgreSQL是否就绪的wait-for-it.sh脚本时,一直碰到权限拒绝的错误:chmod: /api/config/scripts/wait-for-it.sh: Permission denied,然后容器就直接停止运行了。

先贴一下我的相关配置文件:

Dockerfile内容

# Stage 1: Base build stage
FROM python:3.13-slim AS builder

# Create the app directory
RUN mkdir /api

# Set the working directory
WORKDIR /api

# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpcre3-dev \
libssl-dev \
python3-dev \
libpango1.0-dev \
libcairo2-dev \
libpq-dev \
bash \
fontconfig \
fonts-dejavu-core \
fonts-droid-fallback \
fonts-freefont-ttf \
fonts-liberation \
&& rm -rf /var/lib/apt/lists/*

# Install dependencies first for caching benefit
RUN pip install --upgrade pip
RUN mkdir /requirements
COPY ./requirements/. ./requirements/.

RUN set -e; \
pip3 install --upgrade pip && \
pip3 install uwsgi && \
pip3 install --default-timeout=100 --no-cache-dir -r ./requirements/stage.txt

# Stage 2: Production stage
FROM python:3.13-slim

RUN useradd -m -r -g www-data app_user && \
mkdir /api && \
chown -R app_user /api

# Copy the Python dependencies from the builder stage
COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/

# Set the working directory
WORKDIR /api

# Copy application code
COPY --chown=app_user:app_user . .
RUN chown -R app_user:www-data /api

# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN chown app_user:www-data ./config/uwsgi && \
mkdir -p /run/uwsgi && \
chown app_user:www-data /run/uwsgi

# Switch to non-root user
USER app_user

# Expose the application port
EXPOSE 8000

# Make entry file executable
RUN chmod +x /api/config/scripts/wait-for-it.sh

# Verify if postgress ready !
CMD ["/api/config/scripts/wait-for-it.sh"]

docker-compose.yml中api服务的配置

services:
  api:
    image: "${MY_API_IMAGE_FROM_ENV}"
    restart: always
    command: >
      sh -c "/api/config/scripts/wait-for-it.sh db:5432 && python /api/project/manage.py makemigrations && python /api/project/manage.py migrate && uwsgi --ini /api/config/uwsgi/uwsgi.stage.ini"
    volumes:
      - .:/api
      - uwsgi_socket:/run/uwsgi
      - /var/log/project:/api/logs
    environment:
      - DJANGO_SETTINGS_MODULE=project.settings.stage
      - POSTGRES_USER=${BACKEND_USER_DB}
      - POSTGRES_PASSWORD=${BACKEND_PASSWORD_DB}
      - POSTGRES_DB=${BACKEND_DB_NAME}
      - POSTGRES_PORT= ${BACKEND_PORT_DB}
    env_file:
      - .env
    depends_on:
      - db
    networks:
      - app_network
    container_name: api

我本来以为是用户权限的问题,所以特意创建了app_user,并尝试给它赋予脚本的执行权限,但还是碰到这个错误。有没有大佬能帮我看看问题出在哪?


针对这个问题的解决方案分析

我帮你梳理了几个可能的问题点和对应的解决办法:

  1. 权限修改时机错误
    你在Dockerfile里是先切换到app_user非root用户,再执行chmod +x给脚本加执行权限,但此时app_user可能没有修改文件权限的权限——哪怕文件的所有者是自己,修改权限也需要额外的权限(比如文件的写权限)。更稳妥的方式是在切换到非root用户之前,就以root身份给脚本加上执行权限,root用户拥有最高权限,肯定能修改成功。

修改Dockerfile的顺序:

# 先在root身份下给脚本加执行权限
RUN chmod +x /api/config/scripts/wait-for-it.sh

# 再切换到非root用户
USER app_user

# Expose the application port
EXPOSE 8000

# Verify if postgress ready !
CMD ["/api/config/scripts/wait-for-it.sh"]
  1. 本地挂载覆盖了容器内的文件权限
    你在docker-compose里配置了volumes: - .:/api,把本地代码目录直接挂载到容器的/api目录下,这会直接覆盖Dockerfile里复制进去的文件。如果本地的wait-for-it.sh本身没有执行权限(比如本地权限是644),那挂载到容器后,即使Dockerfile里加了权限,也会被本地的无权限文件覆盖。

对应解决办法:

  • 先在本地给脚本加上执行权限:chmod +x config/scripts/wait-for-it.sh,然后再启动容器。
  • 或者在docker-compose的command里,先临时给脚本加权限再执行:
    command: >
      sh -c "chmod +x /api/config/scripts/wait-for-it.sh && /api/config/scripts/wait-for-it.sh db:5432 && python /api/project/manage.py makemigrations && python /api/project/manage.py migrate && uwsgi --ini /api/config/uwsgi/uwsgi.stage.ini"
    
  1. 挂载目录的权限冲突
    因为本地目录挂载到容器后,容器内/api目录的权限会被本地目录的权限覆盖,app_user可能没有权限访问或修改挂载进来的wait-for-it.sh。可以先检查本地目录的权限,确保app_user对应的UID/GID能访问,不过优先解决前两个问题,大概率就能解决你的报错了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.09 03:03:15