Создание локальной среды разработки: запуск полнофункционального приложения Next.js с PostgreSQL и Minio S3 с использованием Docker
Как разработчик, работающий над полнофункциональным приложением, вам необходима локальная среда разработки, максимально приближенная к производственной среде. Это позволит вам тестировать и отлаживать ваше приложение локально перед его развертыванием в рабочей среде.
Почти каждому полнофункциональному приложению необходима база данных и файловое хранилище, поэтому давайте создадим базовое полностековое приложение, которое сможет сохранять и извлекать данные из базы данных, а также загружать и скачивать файлы из файлового хранилища.
Вы можете запустить собственный сервер PostgreSQL и Minio S3 локально или даже использовать облачный сервис, такой как AWS RDS и S3. Но установка и настройка займут некоторое время. Использование docker-compose
позволит очень легко настроить локальную среду разработки для вашего полнофункционального приложения. После локального тестирования все, что вам нужно для переключения в производственную среду, — это изменить переменные среды.
Кроме того, вы можете протестировать свое приложение комплексно (например, с помощью Cypress) в локальной среде, максимально приближенной к производственной среде. Наличие предварительно настроенного файла docker-compose
упростит настройку конвейера CI/CD, такого как GitHub Actions или GitLab CI.
Получив файл docker-compose
, вы и ваша команда можете использовать его для настройки одной и той же локальной среды разработки на любом компьютере за несколько минут с помощью всего лишь одной команды. В целом, это сэкономит вам много времени и облегчит вашу жизнь.
В этой статье мы рассмотрим, как создать локальную среду разработки для полнофункционального приложения Next.js с Prisma ORM, подключенной к PostgreSQL в качестве базы данных и Minio S3 в качестве хранилища файлов с помощью Docker-Compose
.
Полный исходный код этого руководства можно найти на GitHub.
Когда вы будете готовы развернуть свое приложение в рабочей среде, вы можете использовать базу данных любого типа:
- Supabase
- Vercel Postgres
- AWS RDS
- Google Cloud SQL
- Azure Database для PostgreSQL
- Heroku Postgres
- DigitalOcean Managed Databases
- ScaleGrid
- ...
То же самое касается и файлового хранилища, вам нужно совместимое с протоколом S3:
- АВС С3
- Google Cloud Storage (проверял, работает)
- Wasabi (один из самых дешевых вариантов)
- Backblaze B2
- DigitalOcean Spaces
- ...
Предварительные условия
Чтобы следовать этому руководству, на вашем компьютере должны быть установлены Docker и Docker-Compose. Инструкции по установке Docker и Docker-Compose вы можете найти на официальном сайте Docker.
Когда я впервые столкнулся с задачей настройки локальной среды разработки для Next.js, Prisma и PostgreSQL, я попытался использовать учебник T3 Docker, но он у меня не сработал. Тем не менее, я использую его в качестве отправной точки для этого урока.
Создание локальной среды разработки
1. Создайте приложение Next.js
Начнем с создания приложения Next.js. В этом руководстве мы будем использовать стек T3 (TypeScript, TailwindCSS и Prisma ORM), чтобы пропустить установку и настройку всех зависимостей, которые выходят за рамки этой статьи. Более подробную информацию о стеке Т3 вы можете найти.
Запустите следующую команду, чтобы создать новый Next.js:
npm create t3-app@latest
После запуска команды вам будет задано несколько вопросов:
___ ___ ___ __ _____ ___ _____ ____ __ ___ ___
/ __| _ \ __| / \_ _| __| |_ _|__ / / \ | _ \ _ \
| (__| / _| / /\ \| | | _| | | |_ \ / /\ \| _/ _/
\___|_|_\___|_/‾‾\_\_| |___| |_| |___/ /_/‾‾\_\_| |_|
◇ What will your project be called?
│ local-nextjs-postgres-s3
│
◇ Will you be using TypeScript or JavaScript?
│ TypeScript
│
◇ Will you be using Tailwind CSS for styling?
│ Yes
│
◇ Would you like to use tRPC?
│ No
│
◇ What authentication provider would you like to use?
│ None
│
◇ What database ORM would you like to use?
│ Prisma
│
◇ EXPERIMENTAL Would you like to use Next.js App Router?
│ No
│
◇ Should we initialize a Git repository and stage the changes?
│ Yes
│
◇ Should we run 'npm install' for you?
│ Yes
│
◇ What import alias would you like to use?
│ ~/
2. Настройте Next.js для работы с Docker
Согласно документации Next.js.
Next.js может автоматически создавать отдельную папку, в которую копируются только необходимые файлы для производственного развертывания, включая выбранные файлы в node_modules
.
Чтобы уменьшить размер изображения, нам нужно добавить output: "standalone"
файл next.config.js
.
Файл next.config.js
должен выглядеть следующим образом:
const config = {
reactStrictMode: true,
output: "standalone",
// ...
};
3. Добавьте файл .dockerignore
Я предпочитаю иметь отдельную папку для файлов Docker, поэтому я создал папку compose
в корне проекта. Нам нужно добавить .dockerignore
файл в эту папку, чтобы исключить ненужные файлы из образа Docker. Файл .dockerignore
должен выглядеть так:
.env
Dockerfile
.dockerignore
.next
.git
.gitignore
node_modules
npm-debug.log
README.md
4. Настройте Prisma для работы с Docker
В prisma/schema.prisma
файле нам нужно:
- Измените поставщика с
sqlite
наpostgresql
: - Добавляем
binaryTargets
в блок генератора. Это позволит нам использовать CLI Prisma внутри контейнера Docker. Вам нужноbinaryTargets
соответствовать вашей ОС и архитектуре. Например, для M1 Mac я использую"linux-musl-arm64-openssl-3.0.x"
. Для поддержки других ОС и архитектур необходимо добавить их вbinaryTargets
массив. ПодробнееоbinaryTargets
в документации Prisma.
Я хочу использовать один и тот же schema.prisma
файл для локальной разработки на машинах с разными ОС и архитектурами, а также для конвейеров CI/CD в GitHub Actions. В моем случае prisma/schema.prisma
файл выглядит так:
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x", "linux-musl-openssl-3.0.x", "rhel-openssl-1.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
5. Создайте Dockerfile для приложения Next.js
Внутри папки compose
создайте файл web.Dockerfile
со следующим содержимым:
FROM node:18-alpine
RUN mkdir app
COPY ../prisma ./app
COPY ../package.json ../package-lock.json ./app
WORKDIR /app
RUN npm ci
CMD ["npm", "run", "dev"]
Мы будем использовать node:18-alpine
изображение в качестве базового изображения. Это легкий образ, содержащий Node.js 18 и npm. Мы скопируем /prisma
папку package.json
и package-lock.json
файлы в /app
папку и запустим npm ci
установку зависимостей.
Использование «чистой установки» (npm ci
) вместо «установки» (npm i
) является хорошей практикой для образов Docker. Это гарантирует, что зависимости будут установлены из package-lock.json
файла, а не из кеша node_modules
. Это быстрее, чем «установка», что особенно важно для конвейеров CI/CD, где вы хотите максимально сократить время сборки.
6. Создайте файл компоновки Docker
Файл Docker Compose используется для определения и запуска многоконтейнерных приложений Docker с помощью одной команды docker-compose up
.
Здесь мы не будем вдаваться в подробности файлов docker-compose
. В общем, наш файл docker-compose
создает 3 службы: web (приложение Next.js, созданное с помощью нашего Dockerfile), db (база данных PostgreSQL) и minio (хранилище файлов Minio S3). Не забудьте добавить тома для базы данных и служб хранения файлов. В противном случае данные будут потеряны при остановке контейнеров.
Обычно не рекомендуется хранить переменные среды в файле docker-compose
. Однако в данном конкретном сценарии, в образовательных целях и учитывая, что мы используем его исключительно для локальной разработки и тестирования, это выглядит приемлемым. Если вы не хотите хранить секреты в файле docker-compose
, вам следует использовать файл .env
и использовать ${VARIABLE_NAME}
синтаксис для ссылки на переменные. Подробнее о переменных среды в файлах docker-compose
. Справочник по файлам Docker Compose.
Внутри папки compose
создайте файл docker-compose.yml
со следующим содержимым:
version: "3.9"
name: nextjs-postgres-s3minio
services:
web:
container_name: nextjs
build:
context: ../
dockerfile: compose/web.Dockerfile
args:
NEXT_PUBLIC_CLIENTVAR: "clientvar"
ports:
- 3000:3000
volumes:
- ../:/app
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/myapp-db?schema=public
- S3_ENDPOINT=minio
- S3_PORT=9000
- S3_ACCESS_KEY=minio
- S3_SECRET_KEY=miniosecret
- S3_BUCKET_NAME=s3bucket
depends_on:
- db
- minio
db:
image: postgres:15.3
container_name: postgres
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: myapp-db
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped
minio:
container_name: s3minio
image: bitnami/minio:latest
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_storage:/data
volumes:
postgres-data:
minio_storage:
Запустите приложение
В зависимости от того, где у вас находится файл docker-compose
и какие параметры вы хотите использовать.
Вам необходимо запустить следующую команду:
# If you have docker files in the root of the project
docker-compose up
# In our case, we have dockerfile and docker-compose file in the `compose` folder, so we need to run:
docker-compose -f compose/docker-compose.yml up
# --- Optional ---
# For running the application with secrets ${VARIABLE_NAME} stored in the .env file, we would need to run:
docker-compose -f compose/docker-compose.yml --env-file .env up
# If you want to run the application in the background, you can use the -d flag:
docker-compose -f compose/docker-compose.yml up -d
Он запустит сборку приложения Next.js и запустит его на порту 3000
. Он также загрузит образы докеров PostgreSQL и Minio S3 и запустит их на портах 5432
и 9000
соответственно.
После сборки приложения и загрузки изображений вы увидите следующий вывод:
Вы можете получить доступ к приложению по адресу http://localhost:3000, базе данных PostgreSQL по адресу http://localhost:5432 (логин: postgres, пароль: postgres) и Minio S3 по адресу http://localhost:9000 (логин: minio, пароль: miniosecret).
Учетные данные для базы данных и хранилища файлов хранятся в файле docker-compose
. Вы можете изменить их, если хотите.
Заключение
В этой статье мы рассмотрели, как создать локальную среду разработки для полнофункционального приложения Next.js с Prisma ORM, подключенной к PostgreSQL в качестве базы данных, и Minio S3 в качестве хранилища файлов с помощью Docker-Compose.