---
title: "FusionAuth Docker Compose und Hosting mit einem Klick"
description: "FusionAuth selbst hosten: Identitäts- und Zugriffsmanagement für Kunden mit Anmeldung, SSO, MFA und Social Login. Die Auth0-Alternative, mit einem Klick."
---

[← Alle Vorlagen](https://pethost.dev/de/templates/) · [Passwörter und Anmeldung](https://pethost.dev/de/templates/security/)

# FusionAuth mit einem Klick deployen

Identitäts- und Zugriffsmanagement für Kunden: Anmeldung, Registrierung, Single Sign-on und MFA für deine Apps

Eine selbst gehostete Alternative zu Auth0, Okta und Amazon Cognito.

[Auf Pethost deployen](https://console.pethost.dev/?template=fusionauth)

## Was ist FusionAuth?

FusionAuth ist ein Server für das Identitäts- und Zugriffsmanagement von Kunden (CIAM): Deine Web-, Mobil- und API-Apps überlassen ihm Anmeldung, Registrierung und Benutzerverwaltung. Er spricht OAuth 2.0, OpenID Connect und SAML 2.0, sodass sich die meisten Frameworks mit ihren Standardbibliotheken anbinden lassen, und bringt eigene Client-Bibliotheken für JavaScript, Python, Java, Go, PHP, .NET, Ruby und mehr mit. Die gehosteten Login-Seiten von FusionAuth melden Personen mit Passwort, Magic Link oder einem Konto bei einem Dienst wie Google, Apple oder Facebook an, ergänzen Zwei-Faktor-Authentifizierung mit einer Authenticator-App und lassen sich per Theme an das Aussehen deiner App anpassen.

FusionAuth kommt von FusionAuth, Inc. aus Denver, und sein Community-Tarif ist kostenlos, ohne Limit für Benutzer; kostenpflichtige Tarife bringen Funktionen wie Codes per E-Mail und SMS, die Erkennung kompromittierter Passwörter, eigene Registrierungsformulare und SCIM dazu. Open Source ist FusionAuth nicht: Du betreibst die Software unter der Lizenz von FusionAuth. Alles steckt in einer Admin-Oberfläche und einer REST-API: Anwendungen, Tenants für getrennte Benutzerbestände, Rollen, Gruppen, Webhooks, JWT-Einstellungen und Lambdas, die Tokens formen.

Diese Vorlage startet das offizielle Image von FusionAuth, Version 1.69.4, mit einer Postgres-18-Datenbank, die „Neues Projekt“ daneben erstellt, oder einer deiner Datenbanken, die du wählst, und sucht Benutzer in Postgres, ohne Elasticsearch. FusionAuth startet zuerst auf einem Port, den niemand erreicht, und legt dort seinen Administrator mit der E-Mail und dem Passwort an, die du eingibst, sodass sein Einrichtungsassistent nie für Fremde offensteht. E-Mails verschickt FusionAuth über Resend, SendGrid oder Amazon SES, je nachdem, welchen Anbieter du in „Neues Projekt“ wählst, und gar keine, solange du am Tenant keinen Anbieter einträgst.

## FusionAuth-Hosting auf Pethost

1. Du meldest dich bei Pethost an, mit Passkey, GitHub oder Google. Noch keine Maschine? Du wählst einen Tarif, und der Link wartet, bis sie bereit ist.
2. „Neues Projekt“ öffnet sich bei FusionAuth. Du füllst aus, was die App braucht, und klickst auf „Projekt erstellen“: **E-Mail**, **Admin-Passwort**.
3. E-Mail ist optional: Damit FusionAuth E-Mails sendet, wählst du in „Neues Projekt“ **Resend**, **SendGrid** oder **Amazon SES** und fügst ein, was der Anbieter dir gibt.
4. „Neues Projekt“ erstellt außerdem eine neue Datenbank für FusionAuth und verbindet sie vor dem ersten Start der App: **[Postgres](https://pethost.dev/de/postgres/)** (512 MB). Oder du wählst eine deiner **Postgres**-Datenbanken: FusionAuth bekommt darin einen eigenen Benutzer und eine eigene Datenbank, die die anderen Apps dort nicht lesen können, und alle Apps darin werden zusammen gesichert und wiederhergestellt.
5. In ein, zwei Minuten läuft FusionAuth unter eigener Adresse mit HTTPS. Die Secrets werden zufällig erzeugt, und die Daten sind im nächtlichen Backup.
6. Es ist ein Projekt wie jedes andere: Du oder dein Agent könnt es ändern, zurückrollen oder wiederherstellen.

## Fragen zu FusionAuth

**Ist FusionAuth kostenlos?**

Den Community-Tarif von FusionAuth kannst du kostenlos selbst hosten, ohne Limit für Benutzer und mit den Kernfunktionen: OAuth 2.0, OpenID Connect und SAML, Social Login, MFA per Authenticator-App, Themes und die vollständige API. Kostenpflichtige Tarife bringen Codes per E-Mail und SMS, die Erkennung kompromittierter Passwörter, eigene Registrierungsformulare, SCIM und Bedrohungserkennung dazu. FusionAuth ist kostenlos nutzbar, aber nicht Open Source.

**FusionAuth oder Auth0: Was soll ich nehmen?**

Beide melden Benutzer über OAuth 2.0, OpenID Connect und SAML an, mit Social Login und MFA. Auth0 ist ein Cloud-Dienst, dessen Preis sich nach den monatlich aktiven Benutzern richtet; der Community-Tarif von FusionAuth läuft dort, wo du ihn hostest, kostenlos für beliebig viele Benutzer, und die Daten bleiben in deiner Datenbank.

**Wie baue ich mit FusionAuth eine Anmeldung in meine App ein?**

Leg in der Admin-Oberfläche von FusionAuth eine Anwendung an und trag die Callback-Adresse deiner App als autorisierte Redirect-URL ein. Deine App schickt Benutzer dann mit einer OpenID-Connect-Bibliothek auf die gehostete Login-Seite von FusionAuth, mit der Client-ID und dem Client-Secret der Anwendung, und bekommt ihre Tokens zurück.

**Unterstützt FusionAuth Social Login und Passkeys?**

Ja. Unter „Identity Providers“ kommen schon im Community-Tarif Google, Apple, Facebook, Twitter und jeder Anbieter für OpenID Connect oder SAML 2.0 auf die Login-Seite. Passkeys (WebAuthn) brauchen einen kostenlosen Tarif Licensed Community, den du im Kontoportal von FusionAuth registrierst.

**Kann FusionAuth Benutzer aus Auth0 oder Firebase migrieren?**

Ja. Die User Import API nimmt bestehende Passwort-Hashes an, sodass Benutzer ihre Passwörter behalten, und FusionAuth dokumentiert Migrationen von Auth0, Amazon Cognito, Firebase, Keycloak und anderen.

**Wie viel RAM und Speicherplatz braucht FusionAuth?**

FusionAuth läuft auf Java: im Ruhezustand etwa 600–800 MB RAM neben seiner Postgres-Datenbank mit 512 MB, mehr bei vielen Benutzern und Anmeldungen; seine Datenbank wächst langsam, mit den Benutzern und den Einträgen zu ihren Anmeldungen. „Neues Projekt“ gibt jeder Datenbank der App den Arbeitsspeicher, den die Vorlage empfiehlt, wenn du ihn nicht änderst: Postgres (512 MB). Auf Pethost reicht dafür der Tarif Starter, mit Platz für weitere Apps daneben.

## FusionAuth: die Docker-Compose-Datei

Die Vorlage ist diese compose.yaml und die Variablen, die beim Erstellen in die .env des Projekts geschrieben werden. Pethost führt die Datei so aus, wie sie geschrieben ist. Wie sich die App bei ihren Datenbanken anmeldet, schreibt die Maschine dort hinein, wenn sie sie verbindet. Die E-Mail-Einstellungen schreibt „Neues Projekt“ so hinein, wie du sie dort wählst, oder lässt sie leer, wenn die App keine E-Mails sendet.

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

**Datenbanken, jede ein eigenes Projekt:** [Postgres](https://pethost.dev/de/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)[Auf GitHub ansehen](https://github.com/pethost-dev/templates/tree/main/fusionauth)

## [Mehr in Passwörter und Anmeldung](https://pethost.dev/de/templates/security/)

- [**Vaultwarden**Ein Passwortmanager-Server für die Bitwarden-Apps](https://pethost.dev/de/templates/vaultwarden/)
- [**Authorizer**Anmeldung für deine eigenen Apps, mit OAuth 2 und OpenID Connect](https://pethost.dev/de/templates/authorizer/)
- [**Password Pusher**Passwörter und Geheimnisse per Link teilen, der abläuft](https://pethost.dev/de/templates/password-pusher/)
- [**authentik**Ein Identity Provider für Single Sign-on bei deinen Apps: OpenID Connect, SAML, LDAP, MFA und Passkeys](https://pethost.dev/de/templates/authentik/)
- [**Keycloak**Open-Source-Identitäts- und Zugriffsmanagement: Single Sign-on für deine Apps mit OpenID Connect und SAML](https://pethost.dev/de/templates/keycloak/)

Pethost · Stephan Gomer · NIP 1133096755

Pethost

- [Vorlagen](https://pethost.dev/de/templates/)
- [Über uns](https://pethost.dev/about/)
- [Doku](https://pethost.dev/docs/)
- [Blog](https://pethost.dev/de/blog/)
- [API](https://pethost.dev/docs/api/)
- [CLI](https://pethost.dev/docs/cli/)
- [Plugin](https://github.com/pethost-dev/plugin)
- [AGB](https://pethost.dev/terms/)
- [Datenschutz](https://pethost.dev/privacy/)
- [Erstattung](https://pethost.dev/refunds/)
- [support@pethost.dev](mailto:support@pethost.dev)

Datenbanken

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

Vergleiche

- [Coolify vs Dokploy vs CapRover vs Dokku](https://pethost.dev/de/blog/coolify-vs-dokploy-vs-caprover-vs-dokku/)
- [Coolify Cloud vs Dokploy Cloud](https://pethost.dev/de/blog/coolify-cloud-vs-dokploy-cloud/)
- [Railway vs Render vs Fly.io Preise](https://pethost.dev/de/blog/railway-vs-render-vs-fly-io-pricing/)
- [Managed Hosting für Docker Compose](https://pethost.dev/de/blog/managed-docker-compose-hosting/)

Alternativen

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