Менял недавно виртуальный сервер, и пришлось настраивать все заново. Я предпочитаю, чтобы сайт был доступен по https и сертификаты letsencrypt получались и продлевались автоматически. Этого можно добиться, если использовать два образа docker nginx-proxy и nginx-proxy-companion.
Это руководство как настроить сайт на docker, с прокси, которое автоматически получает SSL сертификаты. Используется виртуальный сервер CentOS 7.
Я предполагаю, что сервер уже куплен, настроен, вход на него осуществляется по ключу, установлен fail2ban и т.д.
Для начала нужно установить docker.
- Сначала нужно установить зависимости
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- Подключить репозиторий
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- Потом установить докер community edition
$ sudo yum install docker-ce docker-ce-cli containerd.io
- Добавить docker в автозагрузку и запустить
$ sudo systemctl enable docker $ sudo systemctl start docker
- Добавить пользователя в группу docker, для того, чтобы получить возможность запускать docker без sudo
$ usermod -aG docker user
Следующий шаг — установить docker-compose. Утилиту можно установить несколькими путями, но я предпочитаю устанавливать через pip менеджер и virtualenv, чтобы не засорять систему лишними пакетами.
- Установить pip
$ sudo yum install python-pip
- Установить virtualenv
$ pip install virtualenv
- Дальше нужно создать папку с проектом и инициализировать ее. Папка со всем нужным для управления пакетами будет называться ve.
$ mkdir docker $ cd docker $ virtualenv ve
- Чтобы начать пользоваться виртуальным окружением нужно выполнить следующую команду в папке с проектом.
$ source ve/bin/activate
- Можно устанавливать docker-compose.
pip install docker-compose
Для того, чтобы контейнеры видели друг друга, создадим сеть. По умолчанию используется драйвер bridge.
$ docker network create network
Дальше нужно настроить docker-compose, proxy будет лежать в папке proxy, тестовый сайт в папке test. Для примера я использую доменное имя example.com
$ mkdir proxy $ mkdir test $ touch proxy/docker-compose.yml $ touch test/docker-compose.yml
Содержимое proxy/docker-compose.yml
version: '3' networks: default: external: name: network services: nginx-proxy: container_name: nginx-proxy image: jwilder/nginx-proxy ports: - 80:80 - 443:443 volumes: - certs:/etc/nginx/certs - vhost.d:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro nginx-proxy-letsencrypt: container_name: nginx-proxy-letsencrypt image: jrcs/letsencrypt-nginx-proxy-companion volumes: - certs:/etc/nginx/certs - vhost.d:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/var/run/docker.sock:ro environment: - NGINX_PROXY_CONTAINER=nginx-proxy volumes: certs: vhost.d: html:
Переменная окружения NGINX_PROXY_CONTAINER нужна, чтобы letsencrypt контейнер увидел proxy контейнер. Папки /etc/nginx/certs /etc/nginx/vhost.d и /usr/share/nginx/html должны совместно использоваться и тем и другим контейнером. Для корректной работы letsencrypt контейнера приложение должно быть доступно и по 80 и по 443 порту.
Содержимое test/docker-compose.yml
version: '3' networks: default: external: name: network services: nginx: container_name: nginx image: nginx:latest environment: - VIRTUAL_HOST=example.com - LETSENCRYPT_HOST=example.com - LETSENCRYPT_EMAIL=admin@example.com
Здесь переменные окружения нужны, чтобы прокси корректно обрабатывал запрос к серверу, и запросил сертификат на правильное доменное имя.
Осталось только запустить docker-compose
$ cd proxy $ docker-compose up -d $ cd ../test $ docker-compose up -d
Комментарии (16)
Gwynn
26.03.2019 21:24Уже несколько лет использую acme.sh. Просто, удобно и не надо тянуть еще под дистрибутива левых зависимостей с офф.клиентом. Умеет делать подтверждения через AcmeDNS (поддерживает кучу ДНС провайдеров), автопродление (через крон) и т.п.
kmansoft
26.03.2019 22:01И ещё acme.sh поддерживает ECDSA сертификаты уже сейчас в отличие от certbot (там обещают в середине этого года).
Наверное реальной надобности в этом сейчас нет, но мне понравилось, прикольно.
porn
26.03.2019 22:26Ещё можно использовать что-то из этого: hub.docker.com/u/certbot
У меня, например, получение сертификатов свелось к такой команде:
Показатьdocker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" -v "/var/log/letsencrypt:/var/log/letsencrypt" -v "/etc/certbot/.secrets:/.secrets:ro" certbot/dns-digitalocean certonly --agree-tos --register-unsafely-without-email --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory --dns-digitalocean --dns-digitalocean-credentials /.secrets/digitalocean.ini --dns-digitalocean-propagation-seconds 30 -d "example.com" -d "*.example.com"
kmansoft
27.03.2019 07:03
aol-nnov
26.03.2019 22:43
keydon2
27.03.2019 09:28А зачем тут вообще докер?
also_east Автор
27.03.2019 19:04У меня на работе несколько программистов работает. Под каждый их проект делать отдельную виртуальную машину расточительство. Там может быть проект с nodejs, а рядом php скрипты. Эта штука хорошо работает, просто при создании контейнера под проект пару переменных указал — и все, клиент может посмотреть что в итоге получилось.
Jokerzp
27.03.2019 11:29А в чем преимущества такого подхода, если сравнивать с классическим Certbot?
also_east Автор
27.03.2019 11:44Преимуществ несколько.
nginx-proxy контейнер перенаправляет трафик в зависимости от того, к какому хосту обратился клиент. Т.е. по порту, допустим, 443, будет доступно несколько контейнеров.
nginx-proxy-companion автоматически получает или продлевает сертификат.
Вся настройка, в итоге, сводится к добавлению переменных VIRTUAL_HOST, LETSENCRYPT_HOST и LETSENCRYPT_EMAIL в docker контейнер.
kovalr
27.03.2019 19:11Nginx with automatic let's encrypt (docker image)
github.com/umputun/nginx-lealso_east Автор
27.03.2019 19:13Возможно, просто когда я столкнулся с проблемой, нагуглил именно это решение.
aol-nnov
Или просто начать использовать, например, traefik вместо этой этажерки. (Да, сам начинал с jwilder, но было это почти два года назад) :)
also_east Автор
Спасибо, почитал про traefik. Когда представится возможность, попробую и с ним поэкспериментировать.
stilet69
В чем преимущество traefik перед nginx?
aol-nnov
Кто сказал nginx? Может, статью, всё-таки, осилить, а потом перечитать мой комментарий в свете полученной из статьи информации?
Поясняю: traefik (один за всё, описанное в статье отвечает. однако имеет намного более широкие возможности по кофигурированию) тут противопоставляется подобию ingress controller-а из желудей и пластилина — тому, что в статье (в среднем, три контейнера: генератор конфигов, acme client и уже потом nginx)