MAATRIX / Блог / Infisical в Docker Compose: готовый файл

Infisical в Docker Compose: готовый файл

MAATRIX

Секреты, разбросанные по .env-файлам на ноутбуках разработчиков, рано или поздно утекают — в git, в скриншот, в переписку. Если у вас команда больше одного человека и хотя бы пара окружений (dev/stage/prod), самодельный обмен паролями через мессенджер перестаёт масштабироваться. Infisical — открытый self-hosted менеджер секретов, который решает эту задачу: единое место для переменных окружения, версионирование, права доступа и аудит. Ниже — рабочий docker-compose.yml, который поднимает его на своём сервере за 15 минут.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Infisical и когда он нужен именно вам

Infisical — это open source платформа управления секретами (лицензия MIT для core-функций), которую можно развернуть у себя, а не платить за облачный SaaS. По смыслу она ближе к Doppler или HashiCorp Vault, но с более простым порогом входа: веб-интерфейс, CLI, SDK под основные языки и понятная модель проектов/окружений.

Задача, которую она закрывает: у вас есть DATABASE_URL, STRIPE_SECRET_KEY, JWT_SECRET и десяток похожих переменных, они разные в dev, staging и production, и их нужно раздавать команде без пересылки текстом. Infisical хранит их централизованно, шифрует, версионирует изменения и позволяет забирать их либо через infisical run -- npm start (подставляет переменные в процесс на лету), либо через SDK прямо из кода, либо экспортом в .env.

Когда это оправдано:

  • Команда от 3 человек и больше, секреты меняются чаще раза в месяц.
  • Несколько окружений с разными наборами ключей.
  • Нужен аудит: кто и когда менял или читал секрет.
  • Хочется вырезать секреты из CI-конфигов и git-репозиториев вообще.

Если у вас один проект и один разработчик — вероятно, .env в надёжном менеджере паролей вроде Vaultwarden закроет вопрос проще. Infisical имеет смысл ставить, когда секретами реально нужно управлять, а не просто хранить.

Готовый docker-compose.yml

Self-hosted Infisical в минимальной конфигурации — это backend-контейнер, PostgreSQL и Redis. Создайте на сервере директорию и положите туда файл:

mkdir -p /opt/infisical && cd /opt/infisical

docker-compose.yml:

services:
  db:
    image: postgres:15-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: infisical
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: infisical
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U infisical"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  backend:
    image: infisical/infisical:latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
      AUTH_SECRET: ${AUTH_SECRET}
      SITE_URL: ${SITE_URL}
      DB_CONNECTION_URI: postgresql://infisical:${POSTGRES_PASSWORD}@db:5432/infisical
      REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - backend_uploads:/app/uploads

volumes:
  db_data:
  redis_data:
  backend_uploads:

Обратите внимание: порт backend опубликован только на 127.0.0.1, наружу его отдаёт реверс-прокси с HTTPS — про это ниже. Проверьте на Docker Hub актуальный тег образа infisical/infisical на момент установки — проект развивается быстро, и фиксировать конкретную версию (например, infisical/infisical:v0.9x) безопаснее, чем держать latest на проде.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Переменные окружения и первый запуск

Рядом с docker-compose.yml создайте .env. Docker Compose не выполняет shell-команды внутри самого файла переменных, поэтому подставьте сгенерированные значения через cat с heredoc:

cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 24)
REDIS_PASSWORD=$(openssl rand -hex 24)
ENCRYPTION_KEY=$(openssl rand -hex 16)
AUTH_SECRET=$(openssl rand -hex 32)
SITE_URL=https://secrets.вашдомен.ru
EOF

ENCRYPTION_KEY — это ключ, которым шифруются секреты в базе. Потеряете его — потеряете доступ ко всем данным без возможности восстановления, поэтому сразу сохраните .env в отдельном защищённом месте (например, в том же Vaultwarden, отдельно от сервера). Права на файл:

chmod 600 .env

Запуск:

docker compose up -d
docker compose logs -f backend

Первый запуск создаёт схему в PostgreSQL — это может занять полминуты. После этого зайдите по SITE_URL, зарегистрируйте первого администратора (это единственный момент, когда регистрация открыта без приглашения — дальше в self-hosted версии по умолчанию можно ограничить её только по инвайтам через настройки организации).

HTTPS-доступ через Caddy

Публиковать 8080 напрямую наружу не стоит — секреты того стоят, чтобы закрыть их нормальным TLS и, желательно, дополнительным ограничением доступа по IP. Самый быстрый вариант — Caddy с автоматическим SSL:

secrets.вашдомен.ru {
    reverse_proxy 127.0.0.1:8080
    encode gzip

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options "DENY"
        X-Content-Type-Options "nosniff"
    }
}

Caddy сам получит сертификат Let's Encrypt при первом запросе. Если хотите дополнительно ограничить доступ к панели по списку IP офиса/VPN, добавьте блок @allowed remote_ip ... с проверкой и respond 403 для остальных — это разумно для внутреннего инструмента, который не должен быть доступен всему интернету.

Если у вас уже есть Traefik или nginx перед другими сервисами на этом сервере — логика та же: терминация TLS снаружи, проксирование на 127.0.0.1:8080 внутри.

Подключение проекта: CLI и SDK

После установки создайте организацию и проект в веб-интерфейсе, заведите окружения (dev, staging, production создаются по умолчанию) и добавьте секреты вручную или импортом существующего .env.

Установка CLI на сервере разработки или в CI:

curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash
sudo apt-get install -y infisical

Авторизация и привязка проекта:

infisical login --domain=https://secrets.вашдомен.ru
infisical init

Запуск приложения с подстановкой секретов в переменные окружения процесса — без единого .env на диске:

infisical run --env=production -- node server.js

Для CI (GitHub Actions, GitLab CI) секреты забираются через machine identity (Universal Auth) — сервисный клиент с client_id/client_secret, которому выданы права только на нужный проект и окружение, без привязки к личному аккаунту:

infisical login --method=universal-auth \
  --client-id=$INFISICAL_CLIENT_ID \
  --client-secret=$INFISICAL_CLIENT_SECRET \
  --domain=https://secrets.вашдомен.ru

Для кода есть официальные SDK — Node.js, Python, Go, Java, Ruby, .NET. Пример на Node:

import { InfisicalSDK } from "@infisical/sdk";

const client = new InfisicalSDK({ siteUrl: "https://secrets.вашдомен.ru" });
await client.auth().universalAuth.login({
  clientId: process.env.INFISICAL_CLIENT_ID,
  clientSecret: process.env.INFISICAL_CLIENT_SECRET,
});

const secret = await client.secrets().getSecret({
  environment: "production",
  projectId: "<project-id>",
  secretName: "STRIPE_SECRET_KEY",
});

Так секреты вообще не попадают в файловую систему контейнера — только в память процесса на момент запроса.

Бэкап, обновление и безопасность

Все данные Infisical живут в PostgreSQL — именно её нужно бэкапить регулярно, том Redis можно не сохранять (это кэш и очереди, при потере пересоздастся):

docker compose exec -T db pg_dump -U infisical infisical | gzip > infisical_$(date +%F).sql.gz

Вынесите эту команду в cron и сразу отправляйте архив за пределы сервера — общие принципы разобраны в статье про бэкап Docker-томов. Отдельно сохраните ENCRYPTION_KEY и AUTH_SECRET — без них дамп бесполезен, восстановить зашифрованные секреты не получится.

Обновление образа:

docker compose pull backend
docker compose up -d backend

Перед обновлением на новую мажорную версию сделайте свежий дамп базы — Infisical развивается быстро, миграции схемы случаются, и откат проще из бэкапа, чем вручную.

Что касается безопасности самого сервера — общие принципы из статьи про безопасность Docker применимы и здесь: не публикуйте порты БД и Redis наружу (в файле выше они и так не проброшены на хост), включите файрвол, ограничивающий 8080 только для локального прокси, и не запускайте контейнеры от root без необходимости. Если сценарий шире, чем просто переменные окружения — например, нужна ротация динамических учётных данных к базам или интеграция с PKI, — присмотритесь к HashiCorp Vault: он мощнее, но и сложнее в эксплуатации. Для 90% команд, которым нужно именно управление секретами приложений, Infisical проще и покрывает задачу с меньшим порогом входа.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько ресурсов сервера нужно под Infisical?

Для команды до 20-30 человек и пары десятков проектов достаточно 1-2 vCPU и 2 ГБ RAM — основную нагрузку даёт PostgreSQL при активной записи секретов, это не тяжёлый по CPU сервис. Под рост стоит закладывать запас, ориентируясь на реальную нагрузку в мониторинге, а не на цифры "с потолка".

Можно ли использовать SQLite вместо PostgreSQL?

Нет, self-hosted Infisical требует PostgreSQL — это не опция, а обязательная зависимость архитектуры.

Что будет, если потерять ENCRYPTION_KEY?

Все секреты в базе останутся зашифрованными без возможности расшифровки — это by design, ключ нигде не хранится на сервере Infisical в открытом виде. Храните его в отдельном защищённом месте отдельно от дампов базы.

Нужен ли отдельный сервер под Infisical или можно на том же, где приложение?

Для прод-нагрузки логичнее выделить отдельный небольшой сервер под секреты — это ограничивает поверхность атаки: компрометация сервера приложения не даёт автоматического доступа к хранилищу секретов.

Чем Infisical отличается от Docker secrets?

Docker secrets — механизм передачи секретов внутрь контейнеров Swarm без центрального UI, версионирования и прав доступа по ролям. Infisical — полноценная платформа управления поверх этого: UI, аудит, окружения, SDK. Их можно использовать вместе: Infisical как источник правды, Docker secrets — как способ доставки в конкретный контейнер.

Есть ли бесплатный тариф у облачной версии, если не хочетсяself-hosted?

Да, у Infisical есть облачный SaaS с бесплатным тарифом для небольших команд, но тогда секреты хранятся не на вашей инфраструктуре — для многих компаний с требованиями по данным это неприемлемо, отсюда и интерес к self-hosted варианту из этой статьи.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →