В предыдущей статьея уже рассказал, как мы используем Docker для развертывания локальной среды разработки, поднимая каждый необходимый сервис в отдельном контейнере.
В данной статье я опишу как правильно настраивать и поднимать Vagrant — виртуальную машину в которой можно установить Docker. Ранее мы использовали Vagrant только для того, чтобы иметь возможность запускать Docker на любой платформе, однако теперь — когда почти под каждую платформу существует Docker Toolbox, Vagrant потерял свою актуальность. В любом случае, первая часть статьи — инструкция по тому как правильно работать с Vagrant.
Во второй части статьи я вернусь к Docker и опишу процесс поднятия локальной базы данных в контейнере с использованием Docker Volumes.
Vagrant
Единственная причина, по которой мы пользуемся Vagrant — ради возможности создавать изолированную среду разработки, основанную на виртуальной машине со всеми необходимыми сервисами, которая должна будет воспроизвести реальную рабочую среду. Другими словами, лишь для того чтобы иметь возможность запустить Docker.
Эта среда может быть легко\просто и быстро установлена на любой машине ваших сотрудников. Для этого вам необходимо будет всего лишь установить Vagrantи VirtualBox (или другое похожее ПО) на локальную машину.
Чтобы запустить виртуальную машину, нам нужно создать файл под названием Vagrantfileв корневом каталоге нашего проекта.
Вот хороший пример файла Vagrantfile:
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure(2) do |config| config.vm.box = "ubuntu/trusty64" config.vm.network :forwarded_port, guest: 80, host: 8000 config.vm.synced_folder ".", "/project" # We are going to give VM 1/4 system memory & access to all cpu cores on the host config.vm.provider "virtualbox" do |vb| host = RbConfig::CONFIG['host_os'] if host =~ /darwin/ cpus = `sysctl -n hw.ncpu`.to_i mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024 / 4 elsif host =~ /linux/ cpus = `nproc`.to_i mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 / 4 else cpus = 2 mem = 1024 end vb.customize ["modifyvm", :id, "--memory", mem] vb.customize ["modifyvm", :id, "--cpus", cpus] end config.vm.provision "shell", inline: <<-SHELL # Install docker and docker compose sudo -i echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections curl -sSL https://get.docker.com/ | sh usermod -aG docker vagrant curl -L https://github.com/docker/compose/releases/download/1.5.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose SHELL end
Мы будем использовать этот файл для запуска нашей виртуальной машины, набирая на клавиатуре следующую команду:vagrant up --provision
Если вы увидите предупреждение о новой версии вашего первоначального бокса, просто делайте так:vagrant box update
Давайте рассмотрим детальней, что он делает:
— Он извлечет образ ubuntu/trusty64операционной системы из хранилища vagrant;
— Он направит
— Он закрепит ваш текущий каталог к каталогу ’/project’ внутри машины;
— Он даст 1/4 системной памяти & доступ ко всем ядрам центрального процессор из виртуальной машины;
— Он установит Docker и Docker-Compose внутри виртуальной машины.
Вот и все. Теперь вам нужно всего лишь зайти внутрь данной Виртуальной Машины путем набора на клавиатуре: vagrant ssh
Давайте проверим, все ли установлено должным образом:
docker --version docker-compose --version
Если нет — попробуйте установить вручную: Dockerи Docker-Compose.
Давайте посмотрим наш каталог проекта внутри Виртуальной Машины и установим переменную среду RUN_ENV to DEV:
cd /project export RUN_ENV=DEV
Теперь вы можете сделать локальное повторное развертывание элементарно (как было описано в предыдущей статье):
sh redeploy.sh
Итак, теперь можно пользоваться вашим локальным сервером по ссылке 127.0.0.1:8000.
Вы можете применить три разных команды для завершения работы с вашей Виртуальной Машиной:
vagrant suspend # - to freeze your VM with saved RAM vagrant halt # - to stop your VM but save all files vagrant destroy # - to fully delete your virtual machine!
Создание локальной базы данных в контейнере
По умолчанию мы основываемся на том, что вы используете Docker 1.9 и Docker-Compose 1.5.1 или более поздними версиями.
Была большая путаница с томами\разделами в Docker до версий 1.9. Но теперь Docker внедрил Volume как отдельную сущность на ряду с контейнерами и образами! Теперь вы можете создать раздел (volume) отдельно от контейнеров и образов. К разделам можно достучаться в любое время из любого количества смонтированных контейнеров. И не нужно беспокоиться о сохранности данных даже в случае удаления контейнера.
Это очень просто. Чтобы посмотреть список всех ваших локальных разделов, сделайте следующее:docker volume ls
Чтобы проверить раздел:docker volume inspect <volume_name>
Создать новый раздел:docker volume create --name=<volume_name>
А чтобы удалить раздел сделайте так:docker volume rm <volume_name>
Теперь вы можете удалить старые разделы, созданные ранее некоторыми контейнерами.
Создание локальной базы данных
Мы запустим контейнер Docker с PostgreSQL и закрепим его к уже созданному Docker Volume. Давайте создадим локальный раздел для нашей базы данных:docker volume create --name=local_postgres
Мы будем использовать временный файл docker-compose.database.yml file:
postgres: image: postgres:9.1 container_name: some-postgres volumes: - local_postgres:/var/lib/postgresql/data ports: - "5432:5432" environment: POSTGRES_PASSWORD: "$POSTGRES_PASSWORD" POSTGRES_USER: "$POSTGRES_USER"
И запустим контейнер с PostgreSQL:docker-compose -f docker-compose.database.yml up -d
Теперь у вас есть пустая база данных, работающая в контейнере и доступная на localhost:5432 (или другом хосте, если вы запускаете Docker на Mac).
Вы можете подключиться к этому контейнеру:docker exec -it some-postgres /bin/bash
Переключите на нужного пользователя:su postgres
Запустите PSQL:psql
И, например, создайте новую базу данных:CREATE DATABASE test;
Выйти из PSQL:\q
Вы легко можете удалить этот контейнер следующим образом:
docker-compose -f docker-compose.database.yml stop docker-compose -f docker-compose.database.yml rm -f
Все созданные данные будут сохранены в раздел local_postgres.
В следующий раз, когда вам будет нужна база данных, вы можете запустить новый контейнер, и тогда у вас сразу же будет создана ваша база данных test. Опять же, не нужно даже думать о том, как правильно установить PostgreSQL на вашу локальную машину. Все уже сделано в контейнере.
Сохранение базы в файл
Скажем, вы хотите сохранить данные из вашей локальной базы данных. Вам необходимо запустить простой контейнер с базой и смонтировать ваш локальный каталог с каким-то каталогом в контейнере. Затем вы заходите в контейнер и сохраняете данные как файл в этот вмонтированный каталог.
Давайте сделаем это:
postgres: image: postgres:9.1 container_name: some-postgres volumes: - local_postgres:/var/lib/postgresql/data - .:/data ports: - "5432:5432" environment: POSTGRES_PASSWORD: "$POSTGRES_PASSWORD" POSTGRES_USER: "$POSTGRES_USER"
В этом примере мы монтируем наш текущий каталог с каталогом /dataвнутри контейнера. Зайдите внутрь:
docker exec -it some-postgres /bin/bash su postgres
И выполним дамп:
pg_dump --host 'localhost' -U postgres test -f /data/test.out
Эта команда сохранит тестовую базу данных в файл test.out в вашем текущем каталоге. Теперь вы можете удалить этот контейнер.
Загрузка данных из файла
Воспользуйтесь той же техникой монтирования каталогов для загрузки данных из файла. Чтобы загрузить данные, если вы уже в контейнере postgresи /data/test.outсмонтированы, примените команду:psql --host 'localhost' --username postgres test < /data/test.out
Не забудьте перед этим создать базу данных test.
P.S.Пожалуйста, не стесняйтесь делиться своим опытом по организации процесса разработки в вашей команде и удачными методиками работы с Docker и Vagrant. Пишите в комментариях к статье или же на почтуили в фейсбук. Спасибо!