Создание образа разработки с помощью Nodejs и производство без NodeJS (только с предварительно скомпилированными файлами)
У меня есть приложение на Django, которое использует TailwindCSS для стилизации (используя пакет django-tailwind). Я разрабатываю локально с помощью docker compose и планирую развернуть его, используя то же самое.
Итак, у меня есть следующие требования
- Для разработки: Мне нужно запустить команду
python manage.py tailwind start
илиnpm run dev
, чтобы наблюдатель postcss перестраивал статические файлы при разработке приложения (для этого требуется NodeJS) - Для производства: Я компилирую файлы CSS во время сборки и не нуждаюсь в дополнительных затратах на NodeJS.
Я всегда могу создать два файла Dockerfile для разработки и производства, но я не хочу этого делать без крайней необходимости.
Как я могу сделать это в одном файле настроек. Это текущий файл настроек, который у меня есть
ARG BUILD_TYPE=production
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS base-builder
# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Set environment variables to optimize UV
ENV UV_COMPILE_BYTECODE=1
ENV UV_SYSTEM_PYTHON=1
WORKDIR /app
# Install the requirements
COPY uv.lock .
COPY pyproject.toml .
# Update the package list and install Node.js
RUN apt-get update && \
apt-get install -y nodejs npm && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
FROM base-builder AS production-builder
RUN echo "Running the Production build image!"
ENV UV_NO_DEV=1
FROM base-builder AS development-builder
RUN echo "Running the Development build image!"
ENV UV_NO_DEV=0
FROM ${BUILD_TYPE}-builder AS builder
# Install dependencies
RUN uv sync --locked
# Copy the codebase
COPY ./src .
# Build the theme
RUN cd theme/static_src && \
npm install && \
npm run build && \
rm -rf node_modules
FROM python:3.13-slim-bookworm
WORKDIR /app
RUN apt-get update && apt-get upgrade -y && apt-get clean
COPY --from=builder /app/.venv/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/
COPY --from=builder /app/ /app/
COPY ./docker/entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT [ "./entrypoint.sh" ]
Скрипт точки входа
#!/bin/sh
# Apply database migrations
echo "Applying database migrations..."
python manage.py migrate
# Collect static files
echo "Collecting static files..."
python manage.py collectstatic --noinput
# Create the superuser
echo "Creating superuser..."
python manage.py createsuperuser --noinput
# Start the application
echo "Starting application..."
exec "$@"
Многоступенчатая сборка, которая у вас есть, - правильный подход. Она позволяет Docker создавать несколько контейнеров за один запуск. Однако вы можете сохранить / опубликовать только последний контейнер, если не укажете, где остановиться:
https://docs.docker.com/build/building/multi-stage/#stop-at-a-specific-build-stage
Это означает, что, хотя у вас есть только один файл dockerfile, вам придется запускать его несколько раз, чтобы получить несколько выходных данных.