> ~ biozz / Blog

Проект server

Один docker_compose.yml для всей инфраструктуры

Ivan Elfimov, 2020-02-24, 3m (526 words)

Идея

Когда я осознал мощь docker-compose, я сразу захотел сделать один большой docker_compose.yml для всего. В нём была бы конфигурация всего сервера, чтобы в любой момент можно было сделать на любой тачке docker-compose up и всё работает.

Первая попытка - наброски с Traefik

Параллельно с изучением Docker Compose, я узнал о Traefik. И сейчас понимаю, что это было слишком много для первой попытки. Слишком много настроек и нюансов. Я как обычно начал делать сразу настолько красиво, насколько возможно. docker_compose.yml разрастался, а результата не было. Да и проверить было негде, потому что локально всю специфику с https не протестировать, а вторую тачку для экспериментов было слишком лениво настраивать. В итоге несколько часов потрачено на изучение, а на выходе лишь наброски и ничего рабочего. Полный перегруз, нужно было взять паузу.

Вторая попытка - гибрид Caddy и Docker

После первой попытки пришлось вернуться к классике: всё установлено прямо в систему. Но теперь я лучше понимал как работать с контейнерами и решил сделать не совсем compose, а просто набор контейнеров. То есть все мои приложения и сайты запускались своими shell скриптами с docker run ... и проксировались через Caddy, чтобы не запариваться с сертификатами. Так сервер проработал ещё пару месяцев, пока я не решился на следующую попытку.

Третья попытка - финальная

Я понял, что мне в любом случае придётся где-то репетировать. Поэтому я всё-таки умудрился поднять всю инфраструктуру на Raspberry Pi, забив на https. Здесь же столкнулся с проблемами неподдерживаемых архитекутур некоторых приложений. Например mtg - прокси для телеграма - пришлось пересобрать под armhf. Также я вернулся к обычному nginx, так как параллельно пробовал Caddy v2, а он выглядел уже не таким привлекательным со слишком замороченным конфигом. Затем в один вечер я решился перенести всё это на “прод”. Большую часть перенёс с малинки, немного повозился с сертификатами и certbot и в итоге финальный docker-compose up -d и вся инфраструктура онлайн.

Как это выглядит

На сервере в домашней директории лежит папка server, в ней docker-compose.yml, README.md, .env и папки прикреплённых volumes. Все важные переменные конечно же вынесены в .env, потому что я хочу когда-нибудь свои наработки заоупенсорсить и не палить секреты.

Вот так выглядит раздел Drone CI:

  drone:
    image: drone/drone:1
    restart: always
    environment:
      - DRONE_AGENTS_ENABLED=true
      - DRONE_GITEA_CLIENT_ID=${DRONE_GITEA_CLIENT_ID}
      - DRONE_GITEA_CLIENT_SECRET=${DRONE_GITEA_CLIENT_SECRET}
      - DRONE_GITEA_SERVER=${GITEA_URL}
      - DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
      - DRONE_SERVER_HOST=${DRONE_SERVER_HOST}
      - DRONE_SERVER_PROTO=https
      - DRONE_OPEN=false
    volumes:
      - ./drone/server:/data

В идеале я хочу, чтобы нужно было только заполнить .env и потом docker-compose up.

Что в комплекте

Я пока ещё не готов открывать весь конфиг, но уже могу перечислить какие образы использую:

  • nginx:alpine - реверс прокси на некоторые из сервисов; те что проксируются помечены звездочкой
  • nextcloud:latest*
  • ghost:3-alpine* - блог жены на https://elfimova.site
  • gitea/gitea:latest*
  • drone/drone:1*
  • mariadb:10.5.1 - в основном для nextcloud, но планирую сделать общую для нескольких сервисов
  • drone/drone-runner-docker:1
  • nineseconds/mtg:stable
  • hwdsl2/ipsec-vpn-server

Нюансы

  • для проксирования хостовых сервисов через nginx в контейнере мне потребовалось задать extra_hosts (у меня это был NetData, хотя и его при желании можно настроить в контейнере)
extra_hosts:
  - host.docker.internal:172.17.0.1
  • всё ещё нужно возиться с фаерволом на хосте, я использую ufw
  • бэкапы делаю через rsync всей папки server на локальную тачку
  • в директориях volumes постоянно какие-то проблемы с разрешениями на файлы
  • нужна довольно мощная тачка (у меня это крутится на 2xAMD64 2GB 20GB) и практически всегда съедено 40% памяти

More posts in server series: