MyTetra Share
Делитесь знаниями!
Виртуализация процесса разработки, часть 2: Docker и Vagrant
Время создания: 02.02.2018 13:52
Автор: Andrii Dvoiak
Текстовые метки: docker vagrant virtual
Раздел: Docker

В предыдущей статье я уже рассказал, как мы в Preply.com используем 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;
— Он направит 80-й порт изнутри на 8000-й снаружи;
— Он закрепит ваш текущий каталог к каталогу ’/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. Пишите в комментариях к статье или же на почту или в фейсбук. Спасибо!

 
MyTetra Share v.0.53
Яндекс индекс цитирования