С помощью команды git clone
можно с легкостью загрузить рабочий код на компьютер. Однако создание и запуск локальной базы данных может оказаться серьезной проблемой. Часто нужно устанавливать одну из версий определенной платформы базы данных, а затем либо найти файлы snapshot и запустить сценарий, либо найти программиста, который ими ранее занимался. Все это достаточно сложно.
Контейнеры разработчика (dev containers) и Visual Studio Code позволяют упростить весь этот процесс и получить локальный доступ к базе данных, в том числе с помощью git clone
.
Docker для настройки и хранения dev environments представляется чрезвычайно мощной концепцией. Это следующая эволюция «инфраструктуры как кода». По сути, Docker представляет собой «среду разработки как код» (dev environment as code). Определяющий среду код перемещается вместе с репозиторием, обновляется и меняется по мере роста проекта. Это означает, что среды разработки всегда синхронизируются и никогда не устаревают.
Рассмотрим, как можно настроить и инициализировать серверную базу данных в контейнере Docker так, чтобы новый разработчик в команде, выполнив git clone
репозитория, сразу приступил к работе. Это избавляет от необходимости настраивать локальную базу данных.
Здесь можно найти код приведенного в статье примера.
Необходимые компоненты:
· Docker;
· расширение Remote Containers для VSCode;
· терминал с запущенной оболочкой Bash;
· WSL (рекомендуется при работе в Windows, но не обязателен).
Первоначальная настройка
Начнем с пустого каталога. Открываем терминал.
mkdir database-docker-dev-env; \
cd database-docker-dev-env; \
code .
В пустом каталоге откроется VS Code. В нижнем левом углу будет указана рабочая среда. Эта функция позволит контролировать, где вы находитесь в данный момент. Сейчас мы остаемся на хосте, но не в среде Docker, а в WSL.
Мы получили пустую папку — полностью чистый лист. Dev-контейнеры можно настраивать и автоматически, нажав F1 для доступа в меню. Но сейчас мы будем использовать индивидуальную ручную настройку.
Это решение потребует два контейнера Docker.
- Среда разработчика будет выполняться в одном контейнере со всеми обычными dev-зависимостями, такими как dotnet, vim и др.
- В другом будет сервер базы данных. В этом примере запустим Postgres.
Для настройки взаимодействия используем Docker Compose. Чтобы определить папки и необходимые файлы, скопируйте и вставьте в терминал приведенный ниже код.
mkdir docker; \
cd docker; \
mkdir database; \
mkdir dev-env; \
touch docker-compose.yaml; \
cd dev-env; \
touch Dockerfile; \
cd ..; \
cd database; \
touch database.env;
Папки должны выглядеть подобным образом:
Настройка Docker
Сначала выполним все настройки Docker.
Контейнер среды разработки
Начнем с создания контейнера dev environment. Он будет основан на предоставляемом Microsoft стандартном контейнере C# с некоторыми дополнениями, которые позволят использовать Entity Framework Core в контейнере.
# [Choice] .NET version: 6.0, 5.0, 3.1, 6.0-bullseye, 5.0-bullseye, 3.1-bullseye, 6.0-focal, 5.0-focal, 3.1-focal
ARG VARIANT="6.0-focal"FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT}
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends vim
RUN dotnet tool install -g dotnet-ef
ENV PATH $PATH:/root/.dotnet/tools
Представленный Dockerfile:
- наследует .NET Core 6 из базового образа;
- устанавливает Vim (не обязательно);
- устанавливает инструменты командной строки Entity Framework Core;
- добавляет инструменты CLI в переменную
path
.
В данном случае этого достаточно для создания проекта Entity Framework и взаимодействия с сервером базы данных с помощью инструментов командной строки.
Контейнер базы данных
Используем образ Postgres Docker как есть, поэтому не нужно писать отдельный Dockerfile для контейнера базы данных. Потребуется некоторая настройка, поэтому перейдите в database.env
и добавьте следующую конфигурацию:
POSTGRES_USER=docker_user
POSTGRES_PASSWORD=password
POSTGRES_DB=blog_database
Docker Compose
Настройка Docker завершается увязыванием всех этих компонентов с файлом Compose. Выглядеть это должно подобным образом:
version: '3'
services:
database:
container_name: postgres
image: "postgres"
env_file:
- database/database.env
volumes:
- blog-database-data:/var/lib/postgresql/data/
dev-env:
container_name: dev-env
build:
context: ./dev-env
volumes:
- "..:/workspace"
stdin_open: true # docker run -i
tty: true # docker run -t
volumes:
blog-database-data: null
На самом деле это просто развертывание контейнера Postgres и передача переменных env
. Сохраняем данные базы в томе под названием blog-database-data
.
Для контейнера dev-env
это означает развертывание на основе настроенного ранее образа.
Проверка
На этом этапе проверим работоспособность. Вводим с клавиатуры:
cd .. \
docker compose up
Для начала убедимся, что в контейнерах Docker не возникло никаких проблем. Загляните в контейнер dev-env
.
docker exec -it dev-env /bin/bash
Находясь в контейнере можно убедиться, что dotnet
и dotnet-ef
установлены правильно:
Выйдите с помощью exit
из контейнера developer environment и загляните в Postgres.
docker exec -it postgres /bin/bash
Также убедитесь, что Postgres установлен и доступен.
Теперь можно выполнить exit
для контейнеров Postgres и удалить их с помощью:
docker compose down
Контейнеры Dev в VSCode
Далее настроим VS Code. Возвращаемся в терминал и вставляем (в корневую папку проекта) код:
mkdir .devcontainer; \
cd .devcontainer; \
touch devcontainer.json;
В .devcontainer.json
вставим:
{
"name": "C# (.NET)",
"dockerComposeFile": [
"../docker/docker-compose.yaml"
],
"service": "dev-env",
"workspaceFolder": "/workspace",
"settings": {},
"extensions": [
"ms-dotnettools.csharp",
"shardulm94.trailing-spaces",
"mikestead.dotenv",
],
}
Это все, что нужно для настройки Docker. Теперь нажмите F1 в VSCode и выберите “rebuild and reopen in container”.
В первый раз это займет некоторое время, но в последующие все происходит намного быстрее. После завершения загрузки в нижней части окна VSCode будет показано, что мы находимся в среде Docker.
Теперь при запуске терминала в VSCode видно, что он открылся в ранее настроенном контейнере среды.
Все, что касается Docker, готово. Осталось рассмотреть пример использования Entity Framework Core.
Пример Entity Framework
Создадим небольшой пример с Entity Framework и рассмотрим его взаимодействие с экземпляром Postgres. Используем терминал в VSCode, чтобы добавить новый проект .NET и установить пакеты, необходимые для entity framework.
dotnet new classlib --name Blog.Database; \
cd Blog.Database; \
dotnet add package Microsoft.EntityFrameworkCore; \
dotnet add package Microsoft.EntityFrameworkCore.Design; \
dotnet add package Microsoft.EntityFrameworkCore.Analyzers; \
dotnet add package Microsoft.EntityFrameworkCore.Relational; \
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL; \
touch BlogDbContext.cs; \
touch BlogPost.cs; \
rm Class1.cs;
Создадим очень простой пример базы данных Code First, вставив следующий код в BlogDbContext.cs
.
using Blog.Database.Entities;
using Microsoft.EntityFrameworkCore;
namespace Blog.Database;
public class AppDbContext : DbContext
{
public DbSet<BlogPost> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseNpgsql("Host=postgres;Database=blog_database;Username=docker_user;Password=password");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<BlogPost>().HasData(
new BlogPost() { Id = 1, Title = "Doing Docker" },
new BlogPost() { Id = 2, Title = "Angular with Docker" },
new BlogPost() { Id = 3, Title = "Addicted to Docker - send help" }
);
}
}
И в BlogPost.cs
:
namespace Blog.Database.Entities;
public class BlogPost
{
public int Id { get; set; }
public string Title { get; set; } = default!;
}
Теперь введите следующее в терминале VS Code:
dotnet-ef migrations add initial; \
dotnet-ef database update;
Тестовые данные будут отправлены в базу данных Postgres, которая работает в другом контейнере Docker. Это можно проверить.
Обратите внимание, в среде Docker существует ограничение — получить доступ к другим контейнерам Docker не получится. Это возможно только на хосте, поэтому нужно использовать другой, неиспользуемый в VSCode терминал. В терминале VSCode вы увидите, что Docker недоступен.
Вернитесь в свой терминал (не тот, что в VSCode!).
docker exec -it postgres /bin/bash
Вы попадете в контейнер Docker, где работает Postgres. Введите следующее:
psql --host=database --username=docker_user --dbname=blog_database
При появлении запроса введите пароль (подсказка — это будет password
).
Обратите внимание, что информация совпадает с установленными ранее данными в database.env
. Далее проверяем и убеждаемся, что таблицы созданы:
\d
Также можно показать перемещение тестовых данных:
select * from "Posts";
Подведем итоги.
Любой желающий может просто извлечь этот репозиторий, развернуть его и начать использовать приложение, не задумываясь о настройке базы данных.
В примере использован Postgres, но те же принципы применимы в большей или меньшей степени и к любой другой платформе баз данных, которую можно запускать в контейнере Docker.
Читайте также:
- Инструменты DevOps: интерфейс Docketeer для Docker Desktop
- Как успешно реализовать проверку состояния контейнера в Docker Compose
- Мир Docker и Kubernetes в аналогиях с жизнью разработчика
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Andy Watt: Entity Framework Dev Environment in Docker