Несколько статичных сайтов на одном хосте, используя nginx и Docker

Понадобилось мне захостить несколько статичных (и не только) сайтов на одной машине, решил использовать для этого Docker и nginx.

Итак, начнём. Первое что нам понадобится, это собственно сам сервер. У меня для этих целей был припасён маленький инстанс в DigitalOcean за 5 баксов в месяц. На него можно поставить любую операционку, которая поддерживает Docker, в моём случае выбор пал на CoreOS, так как она легковестная, в ней есть Docker в стандартной поставке и нет ничего лишнего.

Итак, имеется сервер с доступом по ssh, поехали. Для начала определимся как мы всё организуем. Я предлагаю такую схему: nginx запущен в docker контейнере, к которому примонтирована папка со статическими сайтами из хост-машины а также конфигурационный файл nginx.conf, в котором мы и будем настраивать наши статические сайтики. Такая организация позволит не пересобирать контейнер и даже не перезапускать его в случае обновления контента сайтов (что было бы довольно геморно). Для того что-бы изменить какие-то настройки сайта (что крайне редко) или добавить новый сайт, нужно будет всего-то навсего перезапустить контейнер, опять же без его повторной сборки.

Итак, создадим папку на сервере, где будем хранить контент сайтов:

  $ mkdir ~/www

И сделаем простой сайт для теста нашей конфигурации:

  $ mkdir ~/www/test.com
  $ echo "<h1>test</h1>" > ~/www/test.com/index.html

Вот так просто! Осталось только настроить nginx и запустить контейнер. Я взял дефолтный nginx.conf, который идёт с контейнером, добавил туда свои сайты и разместил его в домашней директории, выглядит он приблизительно так:

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  ...
  # Пропущенны дефолтные настройки
  ...
  # Вот тут начинаются мои сайты:
  server {
    listen 80;
    server_name test.com;
    root /usr/share/nginx/html/test.com;
  }

  server {
    listen 80;
    server_name domain2.com;
    root /usr/share/nginx/html/domain2.com;
  }

  server {
    listen 80;
    server_name domain3.com;
    root /usr/share/nginx/html/domain3.com;
  }

  # А это пример настройки уже не статического сайта,
  # а динамического приложения, запущенного на порту 8080
  server {
    listen 80;
    server_name dinamicsite.com;
    location / {
      proxy_pass         http://<server_ip>:8080;
      proxy_set_header   X-Real-IP $remote_addr;
      proxy_set_header   Host      $http_host;
    }
  }

  include /etc/nginx/conf.d/*.conf;
}

Осталось запустить контейнер с nginx, подразумевается что Docker уже установлен в системе (в случае с CoreOS это действительно так, иначе вам прийдется установить его самостоятельно, это очень просто, тут хорошо описан процесс для разных операционных систем https://docs.docker.com/installation/)

Будем использовать официальный image от nginx с docker-хаба вот так:

  $ docker run --name nginx-0 \
               -p 80:80 -d \
               -v /home/core/www:/usr/share/nginx/html:ro \
               -v /home/core/nginx.conf:/etc/nginx/nginx.conf:ro \
               --restart=always nginx

Разберём по пунктам что мы здесь наворотили:

  1. --name nginx-0 задаём имя для контейнера, чтоб потом можно было удобно им управлять (останавливать, перезапускать).
  2. -d говорим докеру, что контейнер должен быть демонизирован.
  3. -p 80:80 nginx запущен на 80 порту внутри контейнера, пробрасываем этот порт наружу.
  4. -v /home/core/www:/usr/share/nginx/html:ro монтируем папку с сайтами (~/www) к папке из которой nginx будет сервить контент.
  5. -v /home/core/nginx.conf:/etc/nginx/nginx.conf:ro монтируем наш конфиг в контейнер.
  6. --restart=always говорим докеру чтоб он перезапустил контейнер в случае если тот внезапно упадёт (мало ли что может случиться).
  7. nginx имя имейджа в докер-хабе, он будет выкачан и запущен. Вот собственно и всё, ходим по сайтам и наслаждаемся результатом!

PS: Напоследок хотелось бы поделиться мыслью как этим зоопарком сайтов можно удобно управлять, я делаю это с помощью rsync, создал у себя на рабочем компьютере папку sites, в которой лежат директории с названиями сайтов (test.com, domain2.com…) и написал простенький скрипт, который деплоит сайт на сервер:

  $ cat sync.sh
  echo "Syncing" $1"..."
  rsync -r sites/$1 core@myserver_ip:~/www/
  echo "Done."

Использование проще простого:

  ./sync.sh test.com

Удачи!

Tags: nginx docker