doc_memo/docker/docker-nginx-w-certbot.md
2025-02-12 21:50:43 +03:00

134 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Веб-сервер Nginx с SSL-сертификатами Let's Encrypt в контейнерах Docker
Для удобного переноса сайтов или веб-приложений между серверами, а также для упрощения обновления и обслуживания
веб-сервера nginx, удобно держать его в контейнере Docker. В данной инструкции рассмотрено развертывание веб-сервера
Nginx с SSL-сертификатами Let's Encrypt в контейнерах Docker. В качестве примера используется контейнер Portainer --
отличный инструмент для управления Docker-контейнерами через веб-интерфейс.
Соглашения: пусть наш пользователь от имени которого мы работаем -- `web`. Таким образом, домашний каталог -- `/home/web`.
Каталог для хранения данных Docker-контейнеров (место куда монтируют тома контейнера) -- `/home/web/docker-data`.
И так, для начала создадим каталог для хранения данных Portainer (можно опустить если вам не нужен Portainer):
```bash
mkdir -p /home/web/docker-data/portainer
```
## Nginx в контейнере Docker
Теперь создадим каталог для хранения конфигурационных файлов Nginx. Сам Nginx будет сидеть в контейнере, но
конфигурационные файлы, которые он будет использовать, находятся на хосте в каталоге `/home/web/docker-data/nginx/conf.d`:
```bash
mkdir -p /home/web/docker-data/nginx/conf.d
```
Теперь создадим файл конфигурации Nginx, который будет использоваться для проксирования запросов к контейнеру Portainer:
```bash
nano /home/web/docker-data/nginx/conf.d/portainer.conf
```
Вставьте в файл следующее содержимое:
```nginx configuration
server {
listen 80;
server_name portainer.you.domain.name;
location / {
proxy_pass http://portainer:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Что происходит в этом файле конфигурации:
- `listen 80;` -- слушаем порт 80 (обычный HTTP-трафик);
- `server_name portainer.you.domain.name;` -- имя хоста, по которому будет доступен Portainer (замените `you.domain.name`
на ваш домен);
- `proxy_pass http://portainer:9000;` -- проксируем запросы в контейнер Portainer, который будет доступен по хосту (имени
контейнера `portainer`) и порту 9000;
- `proxy_set_header Host $host;` -- передаем заголовок `Host` в запросе;
- `proxy_set_header X-Real-IP $remote_addr;` -- передаем заголовок `X-Real-IP` в запросе;
- `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;` -- передаем заголовок `X-Forwarded-For` в запросе;
Сохраните файл и выйдите из редактора (`Ctrl + X`, затем `Y` для подтверждения).
Теперь создадим файл `docker-compose.yml` для развертывания контейнеров Nginx и Portainer:
```bash
nano /home/web/docker-data/docker-compose.yml
```
Вставьте в файл следующее содержимое:
```yaml
version: '3'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
# Гасим порт 9000, чтобы он не светил на хост, а был доступен только во внутри-контейнерной сети
# ports:
# - "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/web/docker-data/portainer:/data
restart: always
networks:
- web
# Можно закомментировать строку выше и раскомментировать строки ниже если зачем-то нужен закрепленный IP-адрес
# web:
# ipv4_address: 172.20.0.10
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- /home/web/docker-data/nginx/conf.d:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt
restart: always
networks:
- web
networks:
web:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24 # Подсеть для пользовательской сети
```
Что у нас настроено в этом `docker-compose.yml`:
- `portainer` (у вас его может и не быть, или быть какой-то другой сервис, который вы будете производить):
- `image: portainer/portainer-ce:latest` -- используем образ Portainer Community Edition;
- `container_name: portainer` -- имя контейнера `portainer`;
- `volumes: ...` -- монтируем файлы или тома изнутри контейнера Portainer на хост. В данном случае монтируем: сокет --
чтобы изнутри контейнера Portainer можно было управлять Docker, в котором сам же и работает (вот так хитро) и каталог
`/home/web/docker-data/portainer` -- чтобы сохранять данные Portainer между перезапусками;
- `restart: always` -- автоматически перезапускаем контейнер при его остановке;
- `networks: ...` -- подключаем контейнер к пользовательской (внутри-контейнерной) сети `web`.
- `nginx`:
- `image: nginx:latest` -- используем образ Nginx;
- `container_name: nginx` -- имя контейнера `nginx`;
- `ports: ...` -- пробрасываем порты 80 и 443 на хост;
- `volumes: ...` -- монтируем каталог с конфигурационными файлами Nginx и каталог с SSL-сертификатами Let's Encrypt;
- `restart: always` -- автоматически перезапускаем контейнер при его остановке;
- `networks: ...` -- подключаем контейнер к пользовательской (внутри-контейнерной) сети `web`.
- `networks: ...`:
- `web`:
- `driver: bridge` -- используем драйвер сети `bridge` (по умолчанию);
- `ipam: ...` -- настраиваем IP-адреса для контейнеров внутри сети `web`. В данном случае используем подсеть
Сохраняем файл `docker-compose.yml` и выходим из редактора (`Ctrl + X`, затем `Y` для подтверждения).
Теперь развернем контейнеры Nginx и Portainer:
```bash
cd /home/web/docker-data
docker-compose up -d
```
После того как контейнеры запустятся, можно зайти в веб-интерфейс Portainer по адресу `http://portainer.you.domain.name`.
## Let's Encrypt в контейнере Docker