Развертывание приложения Django с помощью Docker
Я пытаюсь развернуть свое приложение django с помощью docker. Но когда я запускаю свой скрипт, чтобы убедиться, что база данных (postgres) готова, я всегда получаю эту ошибку: chmod: /app/scripts/wait-for-it.sh: В разрешении отказано, а затем контейнер перестает работать.
Это мой файл 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"]
Это мой api-сервис в моем yml-файле :
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/scripts/wait-for-it.sh установлены разрешения на выполнение только вашим пользователем на вашем локальном компьютере (не в Docker), и поэтому, когда пользователь docker пытается запустить его, вы получаете сообщение об ошибке permission denied. Чтобы проверить эту теорию, вы можете попробовать следующее на своем локальном компьютере:
sudo chmod 777 /app/scripts/wait-for-it.sh
Это позволит установить права доступа для выполнения этого скрипта всеми пользователями. (Обратите внимание, что это не идеально и не должно оставаться постоянной настройкой, только в качестве теста.) Если вы по-прежнему получаете сообщение об ошибке с правами доступа, вы можете быть немного более жестким, установив разрешить все разрешения для всего каталога и всех файлов, содержащихся в:
sudo chmod -R 777 /app/
Но это ДЕЙСТВИТЕЛЬНО открыто и довольно небезопасно, поэтому я был бы осторожен, используя это, и обязательно верните разрешения на минимальный доступ, как только ваш контейнер docker заработает.
Может оказаться полезным создать пользователя внутри контейнера docker, а затем вы сможете изменить права доступа к своим папкам / файлам, чтобы разрешить этому пользователю выполнять скрипты только из них, что значительно подробнее безопаснее, чем оставлять все с полными разрешениями для всех. На этой странице содержится некоторая полезная информация о команде chmod, о том, как читать обозначения для предоставления разрешений и как вы можете предоставить определенные разрешения только определенному пользователю или группе пользователей.
Хотя ваша текущая ошибка, скорее всего, связана с проблемой с правами доступа, она, вероятно, не приведет к желаемому результату. Стандартный и простой способ удовлетворить ваши требования - использовать healthcheck и dependecy в вашем docker compose.
Вот минимальный пример, показывающий, как следует использовать эти ключевые слова:
services:
database:
image: postgres
restart: unless-stopped
healthcheck:
test: ["CMD", "pg_isready", "--dbname=app", "--username=app"]
interval: 5s
timeout: 2s
retries: 5
app:
image: app/app:1.0
restart: unless-stopped
depends_on:
database:
condition: service_healthy
Вы переключаетесь на app_user перед запуском chmod, и у этого пользователя, скорее всего, нет прав на запуск скрипта. Попробуйте запустить chmod +x перед
USER app_user