Docker для Create React App: контейнеризация и сборка

Быстрые ссылки
Определение требований
Dockerfile для CRA
Использование Docker-образа
Переход на NGINX
Преимущества подхода
Контейнеризация проектов с помощью Docker упрощает разработку и облегчает развертывание в облаке. Ниже показано, как упаковать сайт на React в Docker-контейнер.
Эта статья ориентирована на проекты, созданные с помощью
create-react-app(CRA). Если вы «ejected» свой CRA-конфиг или используете кастомный билд-процесс, скорректируйте команду npm run build под вашу сборку.
Docker-образы создаются через Dockerfile. В нём указывают базовый образ (например, веб-сервер), команды для установки пакетов, изменения конфигурации и копирования файлов приложения.
Определение требований
Create React App (CRA) включает встроенную систему разработки с горячей перезагрузкой, доступную через
npm run start— она удобна для быстрой разработки.
Для продакшена нужно собрать статические ресурсы командой npm run build. В результате в директории build появятся минимизированные HTML, CSS и JS-файлы — то, что следует разместить на веб-сервере.
Простейший подход — собрать локально (npm run build), а затем скопировать содержимое build в образ, основанный на веб-сервере. Но этот способ плохо масштабируется в CI: сборка вне контейнера нарушает инкапсуляцию. Предпочтительнее запускать весь процесса сборки внутри Docker — это делает сборку повторяемой и предсказуемой.
Важно: всё, что нужно для сборки (Node, npm, зависимости), должен содержать стадии сборки образа, чтобы CI мог полноценно воспроизводить сборку без внешних шагов.
Dockerfile для CRA
Ниже — минимальный многоступенчатый Dockerfile, который собирает приложение и копирует результат в лёгкий образ веб-сервера:
FROM node:latest AS build
WORKDIR /build
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci
COPY public/ public
COPY src/ src
RUN npm run build
FROM httpd:alpine
WORKDIR /var/www/html
COPY --from=build /build/build/ .Пояснения по стадиям и оптимизациям:
- Первая стадия
buildиспользует официальный Node.js-образ. Мы копируемpackage.jsonиpackage-lock.jsonи выполняемnpm ci— эта команда гарантирует установку зависимостей в соответствии с lock-файлом. - Папки
public/иsrc/копируются после установки зависимостей, потому что они меняются чаще. Это позволяет Docker-кэшу не пересобирать слои сnpm ci, если не изменилисьpackage.json/package-lock.json. - Затем запускается
npm run build, и CRA положит скомпилированные файлы в папкуbuild. - Вторая стадия использует лёгкий
httpd:alpine(Apache) и копирует содержимое изbuild-стадии в корневой каталог веб-сервера. Это делает итоговый образ компактным — Node и npm остаются только в промежуточной стадии.
Советы по Dockerfile
- Фиксируйте версии базовых образов (
node:18-alpineвместоnode:latest) для воспроизводимости. - Удаляйте ненужные файлы (тесты, большие ассеты) до копирования в финальный образ, если это возможно.
- При приватных npm-пакетах настройте аутентификацию в CI, не храните токены в Dockerfile.
Использование Docker-образа
Соберите образ командой:
docker build -t my-react-app:latest .Это соберёт образ и пометит его тегом my-react-app:latest. Контекст для Docker указывается как . — текущая директория, где лежит Dockerfile.
Первый билд может занять несколько минут; последующие будут быстрее за счёт кэширования слоёв.
Запустите контейнер так:
docker run -d -p 8080:80 my-react-app:latestФлаг -d запускает контейнер в фоне. Порт 8080 хоста проксируется на 80 внутри контейнера — откройте http://localhost:8080 чтобы увидеть приложение.

Переход на NGINX
Если вы предпочитаете NGINX, замените вторую стадию на nginx:alpine и скопируйте сборку в директорию NGINX:
FROM nginx:alpine
COPY --from=build /build/build/ /usr/share/nginx/htmlCRA генерирует полностью статический сайт, поэтому вы вольны выбрать любой статический веб-сервер: Apache, NGINX, Caddy и т.д. Важно только правильно указать папку, куда сервер ищет статические файлы.
Пример: docker-compose для локальной разработки и теста
Ниже — простой docker-compose.yml для сборки и запуска сервера (команда docker compose up --build соберёт и запустит):
version: '3.8'
services:
web:
build: .
image: my-react-app:latest
ports:
- "8080:80"Этот файл удобен для CI или для локального тестирования результата сборки.
Когда этот подход не подойдёт
- Если ваше приложение рендерится на сервере (SSR) или использует Node.js на продакшене для рендеринга — статическая сборка CRA не подходит.
- Если сборка требует секретов, которые нельзя передавать в образ — подумайте о переносе секретов в CI-секреты и использовании build args/скриптов с осторожностью.
- Если репозиторий содержит огромные ассеты, лучше хранить их отдельно (CDN, S3), а не в Docker-контейнерах.
Альтернативы и расширения
- Использовать специализированные сервисы статического хостинга (Netlify, Vercel) для автоматизированных деплоев без управления серверами.
- Для SSR/SSG — перейти на Next.js или Gatsby.
- Применять multistage + layer caching с кэшированием node_modules через отдельный слой для ещё более быстрых CI-сборок.
Чек-лист перед деплоем (быстрый)
- [ ] Фиксированы версии базовых образов (не
latest). - [ ] В
package-lock.jsonзахвачены все зависимости. - В CI настроено кэширование Docker слоёв, если возможно.
- Конфиденциальные данные не попадают в образ.
- Тесты проходят локально и в CI до сборки образа.
- Настроен мониторинг/логирование на проде.
Ключевые команды и сниппет (cheat sheet)
Сборка образа:
docker build -t my-react-app:latest .Запуск контейнера:
docker run -d -p 8080:80 my-react-app:latestСборка и запуск через compose:
docker compose up --buildУдаление ненужных образов/контейнеров:
docker system prune --volumesКритерии приёмки
- Собранный Docker-образ доступен в реестре (если используете remote registry).
- Контейнер при запуске отдаёт статические файлы на порту 80 и отвечает 200 на корневой маршрут.
- Размер финального образа соответствует ожиданиям (не содержит dev-зависимостей и исходников, только static build).
- CI-пайплайн автоматически собирает образ и помечает его тегом/шартом версии.
Безопасность и конфиденциальность
- Не храните секреты (API-ключи, пароли) в образах или в репозитории. Передавайте их через окружение в рантайме или через защищённые секреты CI/ораклы секретов.
- Обслуживайте сайт через HTTPS на уровне прокси/балансировщика (например, Traefik, NGINX + сертификаты).
- Подумайте о заголовках безопасности (Content-Security-Policy, X-Frame-Options, Strict-Transport-Security) на уровне сервера.
Короткий глоссарий (1 строка)
- CRA: Create React App — инструмент-стартер для приложений React.
- Multistage build: многоступенчатая сборка Docker, позволяющая уменьшить размер итогового образа.
- npm ci: установка зависимостей по lock-файлу для воспроизводимости сборки.
Итог
Контейнеризация Create React App через многоступенчатый Dockerfile обеспечивает воспроизводимую сборку внутри контейнера и компактный итоговый образ для деплоя. Это простой, гибкий подход, который хорошо интегрируется в CI/CD и оставляет свободу выбора веб-сервера — Apache, NGINX или другие.
Заметки:
- Для крупных проектов рассмотрите разделение на билд-сервис и артефакт-репозиторий (Docker registry, S3).
- Всегда тестируйте образ локально перед деплоем в продакшен.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента