---
title: "FusionAuth com Docker Compose e hospedagem em um clique"
description: "O FusionAuth é gestão de identidade e acesso de clientes: login, SSO, MFA e login social para seus apps. Auto-hospede a alternativa ao Auth0 em um clique."
---

[← Todos os templates](https://pethost.dev/pt/templates/) · [Senhas e login](https://pethost.dev/pt/templates/security/)

# Faça deploy de FusionAuth em um clique

Gerenciamento de identidade e acesso de clientes: login, cadastro, login único e MFA para seus apps

Uma alternativa auto-hospedada para Auth0, Okta e Amazon Cognito.

[Fazer deploy no Pethost](https://console.pethost.dev/?template=fusionauth)

## O que é FusionAuth?

O FusionAuth é um servidor de gerenciamento de identidade e acesso de clientes (CIAM): seus apps web, mobile e de API entregam a ele o login, o cadastro e o gerenciamento de usuários. Ele suporta OAuth 2.0, OpenID Connect e SAML 2.0, então a maioria dos frameworks se conecta a ele com as bibliotecas padrão deles, e ele tem bibliotecas de cliente próprias para JavaScript, Python, Java, Go, PHP, .NET, Ruby e mais. As páginas de login hospedadas dele fazem o login das pessoas com senha, link mágico ou uma conta social como Google, Apple ou Facebook, adicionam autenticação de dois fatores com um app autenticador e podem ganhar um tema com a cara do seu app.

O FusionAuth é feito pela FusionAuth, Inc., de Denver, e o plano Community dele é gratuito, sem limite de usuários; os planos pagos adicionam recursos como códigos por e-mail e SMS, detecção de senhas vazadas, formulários de cadastro personalizados e SCIM. Ele não é de código aberto: você o roda sob a licença do FusionAuth. Tudo fica em uma só interface de administração e uma API REST: aplicações, tenants para bases de usuários separadas, funções, grupos, webhooks, configurações de JWT e lambdas que moldam os tokens.

Este template roda a imagem oficial do FusionAuth, versão 1.69.4, com um banco de dados Postgres 18 que o Novo projeto cria ao lado dele, ou um dos seus que você escolher, e busca usuários no Postgres, sem Elasticsearch. O FusionAuth inicia primeiro em uma porta que ninguém alcança, onde o administrador dele é criado com o e-mail e a senha que você digita, então o assistente de configuração dele nunca fica aberto a um estranho. Os e-mails dele saem pelo Resend, SendGrid ou Amazon SES, o que você escolher no Novo projeto, e nenhum sai até você definir um provedor no tenant.

## Hospedagem de FusionAuth no Pethost

1. Você entra no Pethost com uma passkey, GitHub ou Google. Ainda não tem máquina? Você escolhe um plano, e o link espera até ela ficar pronta.
2. Novo projeto abre em FusionAuth. Você preenche o que ele pede e clica em Criar projeto: **E-mail**, **Senha do administrador**.
3. O e-mail é opcional: para o app FusionAuth enviar e-mails, você escolhe **Resend**, **SendGrid** ou **Amazon SES** no Novo projeto e cola o que o provedor te dá.
4. Novo projeto também cria um banco de dados novo para FusionAuth e conecta os dois antes de o app iniciar pela primeira vez: **[Postgres](https://pethost.dev/pt/postgres/)** (512 MB). Ou você escolhe um dos seus bancos **Postgres**: o app FusionAuth ganha nele um usuário e um banco de dados próprios, que os outros apps de lá não conseguem ler, e todos os apps desse banco entram no mesmo backup e são restaurados juntos.
5. Em um ou dois minutos FusionAuth está no ar no próprio endereço com HTTPS. Os segredos são gerados ao acaso, e os dados vão para o backup noturno.
6. É um projeto como qualquer outro: você ou seu agente podem alterá-lo, fazer rollback ou restaurá-lo.

## Perguntas sobre FusionAuth

**O FusionAuth é gratuito?**

O plano Community do FusionAuth é gratuito para auto-hospedar, sem limite de usuários e com os recursos principais: OAuth 2.0, OpenID Connect e SAML, login social, MFA com app autenticador, temas e a API completa. Os planos pagos adicionam códigos por e-mail e SMS, detecção de senhas vazadas, formulários de cadastro personalizados, SCIM e detecção de ameaças. O FusionAuth é de uso gratuito, mas não é de código aberto.

**FusionAuth ou Auth0: qual devo usar?**

Os dois fazem o login de usuários por OAuth 2.0, OpenID Connect e SAML, com login social e MFA. O Auth0 é um serviço na nuvem cobrado por usuários ativos por mês; o plano Community do FusionAuth roda onde você o hospeda, gratuito para qualquer número de usuários, e os dados dele ficam no seu banco de dados.

**Como adiciono login ao meu app com o FusionAuth?**

Crie uma aplicação na interface de administração do FusionAuth e adicione o endereço de callback do seu app como URL de redirecionamento autorizada. Depois, o seu app manda os usuários para a página de login hospedada do FusionAuth com uma biblioteca OpenID Connect, usando o client ID e o segredo da aplicação, e recebe de volta os tokens deles.

**O FusionAuth suporta login social e passkeys?**

Sim. Em Identity Providers, a página de login ganha Google, Apple, Facebook, Twitter e qualquer provedor OpenID Connect ou SAML 2.0, já no plano Community. As passkeys (WebAuthn) precisam de um plano Licensed Community gratuito, registrado no portal de contas do FusionAuth.

**O FusionAuth consegue migrar usuários do Auth0 ou do Firebase?**

Sim. A User Import API dele aceita hashes de senha existentes, então os usuários mantêm as senhas, e o FusionAuth documenta migrações do Auth0, Amazon Cognito, Firebase, Keycloak e outros.

**De quanta memória e disco FusionAuth precisa?**

O FusionAuth roda em Java: cerca de 600–800 MB de memória em repouso, ao lado do seu Postgres de 512 MB, mais com muitos usuários e logins; o banco de dados dele cresce devagar, com os usuários e os registros de login deles. Novo projeto dá a cada banco de dados do app a memória que o template recomenda, a menos que você a mude: Postgres (512 MB). No Pethost, o plano Starter basta, com espaço para outros apps ao lado.

## Arquivo Docker Compose de FusionAuth

O template é este compose.yaml e as variáveis gravadas no .env do projeto quando ele é criado. O Pethost roda o arquivo exatamente como está escrito. A máquina grava ali como o app entra nos seus bancos de dados, ao conectá-los. Novo projeto grava ali as configurações de e-mail escolhidas nele, ou as deixa vazias quando o app não envia e-mail.

**Containers:** fusionauth (fusionauth/fusionauth-app:1.69.4).

**Bancos de dados, cada um como projeto próprio:** [Postgres](https://pethost.dev/pt/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)[Ver no GitHub](https://github.com/pethost-dev/templates/tree/main/fusionauth)

## [Mais em Senhas e login](https://pethost.dev/pt/templates/security/)

- [**Vaultwarden**Um servidor de gerenciamento de senhas para os apps do Bitwarden](https://pethost.dev/pt/templates/vaultwarden/)
- [**Authorizer**Login para os seus próprios apps, com OAuth 2 e OpenID Connect](https://pethost.dev/pt/templates/authorizer/)
- [**Password Pusher**Compartilhe senhas e segredos por links que expiram](https://pethost.dev/pt/templates/password-pusher/)
- [**authentik**Um provedor de identidade para login único nos seus apps: OpenID Connect, SAML, LDAP, MFA e passkeys](https://pethost.dev/pt/templates/authentik/)
- [**Keycloak**Gerenciamento de identidade e acesso de código aberto: login único para seus apps com OpenID Connect e SAML](https://pethost.dev/pt/templates/keycloak/)

Pethost · Stephan Gomer · NIP 1133096755

Pethost

- [Templates](https://pethost.dev/pt/templates/)
- [Sobre nós](https://pethost.dev/about/)
- [Docs](https://pethost.dev/docs/)
- [Blog](https://pethost.dev/pt/blog/)
- [API](https://pethost.dev/docs/api/)
- [CLI](https://pethost.dev/docs/cli/)
- [Plugin](https://github.com/pethost-dev/plugin)
- [Termos](https://pethost.dev/terms/)
- [Privacidade](https://pethost.dev/privacy/)
- [Reembolsos](https://pethost.dev/refunds/)
- [support@pethost.dev](mailto:support@pethost.dev)

Bancos de dados

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

Comparativos

- [Coolify vs Dokploy vs CapRover vs Dokku](https://pethost.dev/pt/blog/coolify-vs-dokploy-vs-caprover-vs-dokku/)
- [Coolify Cloud vs Dokploy Cloud](https://pethost.dev/pt/blog/coolify-cloud-vs-dokploy-cloud/)
- [Preços Railway vs Render vs Fly.io](https://pethost.dev/pt/blog/railway-vs-render-vs-fly-io-pricing/)
- [Hospedagem gerenciada de Docker Compose](https://pethost.dev/pt/blog/managed-docker-compose-hosting/)

Alternativas

- [Alternativas ao Railway](https://pethost.dev/pt/blog/railway-alternatives/)
- [Alternativas ao Heroku](https://pethost.dev/pt/blog/heroku-alternatives/)
- [Alternativas ao Dokploy](https://pethost.dev/pt/blog/dokploy-alternatives/)
- [Alternativas ao Coolify](https://pethost.dev/pt/blog/coolify-alternatives/)
- [Alternativas ao Render](https://pethost.dev/pt/blog/render-alternatives/)
- [Alternativas ao Sliplane](https://pethost.dev/pt/blog/sliplane-alternatives/)
