---
title: "FusionAuth: Docker Compose и хостинг в один клик"
description: "Self-hosted FusionAuth — управление идентификацией и доступом клиентов: вход, SSO, MFA и вход через соцсети. Альтернатива Auth0 в один клик."
---

[← Все шаблоны](https://pethost.dev/ru/templates/) · [Пароли и вход](https://pethost.dev/ru/templates/security/)

# Задеплойте FusionAuth в один клик

Управление идентификацией и доступом клиентов: вход, регистрация, единый вход и MFA для ваших приложений

Альтернатива Auth0, Okta и Amazon Cognito на вашей машине.

[Задеплоить на Pethost](https://console.pethost.dev/?template=fusionauth)

## Что такое FusionAuth?

FusionAuth — сервер управления идентификацией и доступом клиентов (CIAM): ваши веб-, мобильные и API-приложения поручают ему вход, регистрацию и управление пользователями. Он поддерживает OAuth 2.0, OpenID Connect и SAML 2.0, поэтому большинство фреймворков подключаются к нему своими стандартными библиотеками, а еще у него есть собственные клиентские библиотеки для JavaScript, Python, Java, Go, PHP, .NET, Ruby и других языков. Его готовые страницы входа впускают людей по паролю, по ссылке для входа (magic link) или через аккаунт в соцсети или сервисе вроде Google, Apple или Facebook, добавляют двухфакторную аутентификацию через приложение-аутентификатор и оформляются темами под ваше приложение.

FusionAuth делает компания FusionAuth, Inc. из Денвера, и его тариф Community бесплатный, без ограничений на число пользователей; платные тарифы добавляют такие функции, как коды по почте и SMS, проверка паролей на утечки, свои формы регистрации и SCIM. Код у него не открытый: вы запускаете его по лицензии FusionAuth. Все находится в одном интерфейсе администратора и REST API: приложения, тенанты для раздельных пулов пользователей, роли, группы, вебхуки, настройки JWT и лямбды, которые формируют токены.

Этот шаблон запускает официальный образ FusionAuth версии 1.69.4 с базой данных Postgres 18, которую «Новый проект» создает рядом, или одной из ваших, которую вы выберете, и ищет пользователей в Postgres, без Elasticsearch. Сначала FusionAuth запускается на порту, до которого никто не может достучаться, и там его администратор создается из почты и пароля, которые вы ввели, поэтому мастер настройки никогда не открыт посторонним. Почту FusionAuth отправляет через Resend, SendGrid или Amazon SES — какой сервис вы выберете в окне «Новый проект», а пока вы не зададите сервис в тенанте, не отправляет вовсе.

## Хостинг FusionAuth на Pethost

1. Вы входите в Pethost — с passkey, через GitHub или Google. Машины еще нет? Вы выбираете тариф, и ссылка ждет, пока машина не будет готова.
2. Окно «Новый проект» открывается на приложении FusionAuth. Вы заполняете то, что оно просит, и нажимаете «Создать проект»: **Электронная почта**, **Пароль администратора**.
3. Отправка почты необязательна: чтобы приложение FusionAuth отправляло письма, вы выбираете в окне «Новый проект» **Resend**, **SendGrid** или **Amazon SES** и вставляете то, что выдает провайдер.
4. Окно «Новый проект» также создает для приложения FusionAuth новую базу данных и подключает ее до первого запуска приложения: **[Postgres](https://pethost.dev/ru/postgres/)** (512 MB). Или вы выбираете одну из своих баз **Postgres**: приложение FusionAuth получает в ней отдельного пользователя и отдельную базу данных, которые другие приложения там не могут прочитать, а все приложения этой базы попадают в один бэкап и восстанавливаются вместе.
5. Через минуту-две FusionAuth работает по своему адресу с HTTPS. Секреты создаются случайно, а данные попадают в ночной бэкап.
6. Это проект как любой другой: вы или ваш агент можете его изменить, откатить или восстановить.

## Вопросы про FusionAuth

**FusionAuth бесплатный?**

Тариф Community у FusionAuth бесплатен, если вы запускаете его сами: без ограничений на число пользователей и с основными функциями — OAuth 2.0, OpenID Connect и SAML, вход через соцсети, MFA через приложение-аутентификатор, темы оформления и полный API. Платные тарифы добавляют коды по почте и SMS, проверку паролей на утечки, свои формы регистрации, SCIM и обнаружение угроз. FusionAuth можно использовать бесплатно, но его код не открыт.

**FusionAuth или Auth0: что выбрать?**

Оба впускают пользователей по OAuth 2.0, OpenID Connect и SAML, со входом через соцсети и MFA. Auth0 — облачный сервис, цена которого зависит от числа активных пользователей в месяц; тариф Community у FusionAuth работает там, где вы его разместите, бесплатно для любого числа пользователей, а его данные остаются в вашей базе данных.

**Как добавить вход в свое приложение с FusionAuth?**

Создайте приложение в интерфейсе администратора FusionAuth и добавьте адрес обратного вызова (callback) вашего приложения как разрешенный URL перенаправления. Затем ваше приложение отправляет пользователей на готовую страницу входа FusionAuth через библиотеку OpenID Connect, с client ID и секретом этого приложения, и получает обратно их токены.

**Поддерживает ли FusionAuth вход через соцсети и passkey?**

Да. Раздел «Identity Providers» уже в тарифе Community добавляет на страницу входа Google, Apple, Facebook, Twitter и любого поставщика OpenID Connect или SAML 2.0. Для passkey (WebAuthn) нужен бесплатный тариф Licensed Community, который регистрируется в личном кабинете на сайте FusionAuth.

**Может ли FusionAuth перенести пользователей из Auth0 или Firebase?**

Да. Его User Import API принимает существующие хеши паролей, так что пользователи сохраняют свои пароли, а FusionAuth описывает в документации миграцию из Auth0, Amazon Cognito, Firebase, Keycloak и других систем.

**Сколько памяти и диска нужно FusionAuth?**

FusionAuth работает на Java: в простое около 600–800 MB памяти рядом с его базой Postgres на 512 MB, больше — при множестве пользователей и входов; его база данных растет медленно, вместе с пользователями и записями об их входах. Окно «Новый проект» дает каждой базе данных приложения столько памяти, сколько рекомендует шаблон, если вы это не измените: Postgres (512 MB). На Pethost ему хватит тарифа Starter, и рядом останется место для других приложений.

## FusionAuth: файл Docker Compose

Шаблон — это этот compose.yaml и переменные, которые пишутся в .env проекта при его создании. Pethost запускает файл так, как он написан. Машина пишет туда, как приложение входит в свои базы данных, когда подключает их. Окно «Новый проект» пишет туда выбранные в нем настройки почты или оставляет их пустыми, если приложение не отправляет писем.

**Контейнеры:** fusionauth (fusionauth/fusionauth-app:1.69.4).

**Базы данных, каждая — отдельный проект:** [Postgres](https://pethost.dev/ru/postgres/) (512 MB).

```
services:
  fusionauth:
    image: fusionauth/fusionauth-app:1.69.4
    restart: unless-stopped
    environment:
      # FusionAuth reads DATABASE_URL as a JDBC URL, so it is made here from the part's parts.
      DATABASE_URL: jdbc:postgresql://${DATABASE_HOST:?reload New project to link a Postgres database, or send link_databases with env_prefix DATABASE}:${DATABASE_PORT:?reload New project to link a Postgres database, or send link_databases with env_prefix DATABASE}/${DATABASE_NAME:?reload New project to link a Postgres database, or send link_databases with env_prefix DATABASE}
      DATABASE_USERNAME: ${DATABASE_USER:?reload New project to link a Postgres database, or send link_databases with env_prefix DATABASE}
      DATABASE_PASSWORD: ${DATABASE_PASSWORD:?reload New project to link a Postgres database, or send link_databases with env_prefix DATABASE}
      # Silent mode makes the schema in the linked database, which the app's user owns, and
      # applies a new release's migrations at its start; production mode never shows the
      # migration screen to a visitor.
      FUSIONAUTH_APP_SILENT_MODE: "true"
      FUSIONAUTH_APP_RUNTIME_MODE: production
      # Users are searched in Postgres, with no Elasticsearch or OpenSearch beside it.
      SEARCH_TYPE: database
      FUSIONAUTH_APP_MEMORY: 512M
      # 20 connections at most, FusionAuth's default, within the 47 of the Postgres part.
      DATABASE_MAXIMUM_POOL_SIZE: "20"
      URL: ${URL}
      ADMIN_EMAIL: ${ADMIN_EMAIL}
      ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      SETUP_API_KEY: ${SETUP_API_KEY}
      # The mail provider picked in New project, by STARTTLS on its port; with none, FusionAuth
      # sends no mail until one is set on the tenant.
      SMTP_HOST: ${SMTP_HOST}
      SMTP_PORT: ${SMTP_PORT}
      SMTP_USER: ${SMTP_USER}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_FROM: ${SMTP_FROM}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME}
    # A new FusionAuth shows its setup wizard to whoever opens it first, also in the seconds
    # before Kickstart has run, and counts the setup as done only when Kickstart made the
    # administrator. So FusionAuth runs first on port 9019, which nobody reaches, and only then on
    # port 9011, the page's. On a new database, Kickstart makes the set-up's API key and the
    # administrator, with a stand-in email and password, and gives the default tenant the
    # project's address as its issuer; the API then gives the administrator the email and
    # password of the fields, and the tenant the mail provider, since Kickstart takes a quote or
    # a backslash out of what it is given. The set-up's key is deleted last: while it answers,
    # the set-up is unfinished, and once it is refused and the setup wizard sends a visitor to
    # sign in, FusionAuth is set up.
    command:
      - bash
      - -c
      - |
        set -e
        cd /usr/local/fusionauth
        json() { printf '%s' "$$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'; }
        # The set-up's API key, and the ids of it and of the administrator, all from SETUP_API_KEY.
        key=$$SETUP_API_KEY
        key_id=$${key:0:8}-$${key:8:4}-$${key:12:4}-$${key:16:4}-$${key:20:12}
        admin_id=$${key:32:8}-$${key:40:4}-$${key:44:4}-$${key:48:4}-$${key:52:12}

        # Kickstart runs only on a FusionAuth with no API key and no user yet.
        cat > /tmp/kickstart.json <<KICKSTART
        {
          "apiKeys": [{"id": "$$key_id", "key": "$$key", "keyManager": true, "description": "The template's set-up"}],
          "requests": [
            {"method": "PATCH", "url": "/api/tenant/#{FUSIONAUTH_TENANT_ID}", "body": {"tenant": {"issuer": "$$URL"}}},
            {
              "method": "POST",
              "url": "/api/user/registration/$$admin_id",
              "body": {
                "user": {"email": "setup@example.com", "password": "$$key"},
                "registration": {"applicationId": "#{FUSIONAUTH_APPLICATION_ID}", "roles": ["admin"]}
              }
            }
          ]
        }
        KICKSTART
        FUSIONAUTH_APP_HTTP_PORT=9019 FUSIONAUTH_APP_KICKSTART_FILE=/tmp/kickstart.json fusionauth-app/bin/start.sh &
        first=$$!
        stop_first() {
          kill $$first
          wait $$first 2> /dev/null || true
        }
        api() {
          method=$$1
          path=$$2
          shift 2
          curl -sS -o /tmp/api.json -w '%{http_code}' -X "$$method" -H "Authorization: $$key" \
            -H 'Content-Type: application/json' "$$@" "http://127.0.0.1:9019$$path" 2> /dev/null || true
        }
        refused() {
          echo "FusionAuth refused $$1: $$(cat /tmp/api.json)" >&2
          stop_first
          exit 1
        }

        # Silent mode migrates the database first; a database that does not answer stops the
        # start after 5 minutes, and the next start tries again.
        for wait in $$(seq 300); do
          kill -0 $$first 2> /dev/null || { echo "FusionAuth stopped at its first start." >&2; exit 1; }
          admin=$$(api GET "/api/user/$$admin_id")
          [ "$$admin" = 200 ] && break
          wizard=$$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:9019/admin/setup-wizard || true)
          [ "$$admin" = 401 ] && [ "$$wizard" = 302 ] && break
          sleep 1
        done
        if [ "$$admin" != 200 ] && [ "$$wizard" != 302 ]; then
          echo "FusionAuth did not answer on its first start within 5 minutes." >&2
          stop_first
          exit 1
        fi

        if [ "$$admin" = 200 ]; then
          echo "setting FusionAuth up on a port nobody reaches"
          tenant=$$(grep -o '"tenantId":"[^"]*"' /tmp/api.json | head -n 1 | cut -d '"' -f 4)
          if [ "$${#ADMIN_PASSWORD}" -lt 8 ]; then
            echo "The admin password has fewer than 8 characters, which FusionAuth refuses: give one of 8 or more in ADMIN_PASSWORD of the project's .env, then deploy again." >&2
            stop_first
            exit 1
          fi
          [ "$$(api PATCH "/api/user/$$admin_id" \
            -d "{\"user\": {\"email\": \"$$(json "$$ADMIN_EMAIL")\", \"password\": \"$$(json "$$ADMIN_PASSWORD")\"}}")" = 200 ] \
            || refused "the administrator's email and password"
          if [ -n "$$SMTP_HOST" ]; then
            [ "$$(api PATCH "/api/tenant/$$tenant" -d "{\"tenant\": {\"emailConfiguration\": {\"host\": \"$$(json "$$SMTP_HOST")\",
              \"port\": $$SMTP_PORT, \"security\": \"TLS\", \"username\": \"$$(json "$$SMTP_USER")\", \"password\": \"$$(json "$$SMTP_PASSWORD")\",
              \"defaultFromEmail\": \"$$(json "$$SMTP_FROM")\", \"defaultFromName\": \"$$(json "$$SMTP_FROM_NAME")\"}}}")" = 200 ] \
              || refused "the mail provider"
          fi
          # The set-up's API key can do anything, and nothing needs it any more.
          [ "$$(api DELETE "/api/api-key/$$key_id")" = 200 ] || refused "to delete the set-up's API key"
          echo "FusionAuth is set up, with the administrator $$ADMIN_EMAIL"
        fi
        stop_first
        rm /tmp/kickstart.json

        exec fusionauth-app/bin/start.sh
    healthcheck:
      test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://127.0.0.1:9011/api/status"]
      interval: 10s
      timeout: 5s
      retries: 30
      start_period: 300s
```

[compose.yaml](https://pethost.dev/templates/fusionauth/compose.yaml)[Открыть на GitHub](https://github.com/pethost-dev/templates/tree/main/fusionauth)

## [Еще в категории «Пароли и вход»](https://pethost.dev/ru/templates/security/)

- [**Vaultwarden**Сервер менеджера паролей для приложений Bitwarden](https://pethost.dev/ru/templates/vaultwarden/)
- [**Authorizer**Вход в ваши собственные приложения, с OAuth 2 и OpenID Connect](https://pethost.dev/ru/templates/authorizer/)
- [**Password Pusher**Пароли и секреты по ссылкам, которые истекают](https://pethost.dev/ru/templates/password-pusher/)
- [**authentik**Провайдер идентификации для единого входа в ваши приложения: OpenID Connect, SAML, LDAP, MFA и passkey](https://pethost.dev/ru/templates/authentik/)
- [**Keycloak**Управление идентификацией и доступом с открытым кодом: единый вход в ваши приложения по OpenID Connect и SAML](https://pethost.dev/ru/templates/keycloak/)

Pethost · Stephan Gomer · NIP 1133096755

Pethost

- [Шаблоны](https://pethost.dev/ru/templates/)
- [О нас](https://pethost.dev/about/)
- [Документация](https://pethost.dev/docs/)
- [Блог](https://pethost.dev/ru/blog/)
- [API](https://pethost.dev/docs/api/)
- [CLI](https://pethost.dev/docs/cli/)
- [Плагин](https://github.com/pethost-dev/plugin)
- [Условия](https://pethost.dev/terms/)
- [Конфиденциальность](https://pethost.dev/privacy/)
- [Возвраты](https://pethost.dev/refunds/)
- [support@pethost.dev](mailto:support@pethost.dev)

Базы данных

- [Postgres](https://pethost.dev/ru/postgres/)

Сравнения

- [Coolify vs Dokploy vs CapRover vs Dokku](https://pethost.dev/ru/blog/coolify-vs-dokploy-vs-caprover-vs-dokku/)
- [Coolify Cloud vs Dokploy Cloud](https://pethost.dev/ru/blog/coolify-cloud-vs-dokploy-cloud/)
- [Цены Railway, Render и Fly.io](https://pethost.dev/ru/blog/railway-vs-render-vs-fly-io-pricing/)
- [Управляемый хостинг Docker Compose](https://pethost.dev/ru/blog/managed-docker-compose-hosting/)

Альтернативы

- [Альтернативы Railway](https://pethost.dev/ru/blog/railway-alternatives/)
- [Альтернативы Heroku](https://pethost.dev/ru/blog/heroku-alternatives/)
- [Альтернативы Dokploy](https://pethost.dev/ru/blog/dokploy-alternatives/)
- [Альтернативы Coolify](https://pethost.dev/ru/blog/coolify-alternatives/)
- [Альтернативы Render](https://pethost.dev/ru/blog/render-alternatives/)
- [Альтернативы Sliplane](https://pethost.dev/ru/blog/sliplane-alternatives/)
