Install with Docker

On this page

This page explains how to install FusionAuth using Docker.

For Kubernetes install instructions, see Install with Kubernetes.

For an advanced discussion of FusionAuth Docker image customization, see Customize Docker Images.

Prerequisites#

The instructions below require the following prerequisites:

  • Docker 23 or later
  • On macOS and Windows, one of the following container management tools:
    • OrbStack (to use Orbstack for docker compose commands after install, run docker context use orbstack)
    • Podman (in the commands below, replace docker with podman)
    • Docker desktop

Install#

Use the steps below to install FusionAuth using Docker Compose with the configuration files in the fusionauth-containers repository:

  1. Download the docker-compose.yml and .env files:

    $ curl -o docker-compose.yml https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/main/docker/fusionauth/docker-compose.yml
    
    Full docker-compose.yml example
    docker-compose.yml
    services:
      #
      # Required services (database and FusionAuth)
      #
    
      # Postgresql is the default database. You can swap this out for MySQL if you prefer.
      db:
        image: postgres:16.0-bookworm
        environment:
          PGDATA: /var/lib/postgresql/data/pgdata
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
        healthcheck:
          test: [ "CMD-SHELL", "pg_isready -U postgres" ]
          interval: 5s
          timeout: 5s
          retries: 5
        restart: unless-stopped
        volumes:
          - db_data:/var/lib/postgresql/data
    
      # This is the main FusionAuth application.
      fusionauth:
        image: fusionauth/fusionauth-app:latest
        depends_on:
          db:
            condition: service_healthy
          search:
            condition: service_healthy
        environment:
          DATABASE_URL: jdbc:postgresql://db:5432/fusionauth
          DATABASE_ROOT_USERNAME: ${POSTGRES_USER}
          DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
          DATABASE_USERNAME: ${DATABASE_USER}
          DATABASE_PASSWORD: ${DATABASE_PASSWORD}
          FUSIONAUTH_APP_KICKSTART_FILE: ${FUSIONAUTH_APP_KICKSTART_FILE}
          FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY}
          FUSIONAUTH_APP_RUNTIME_MODE: ${FUSIONAUTH_APP_RUNTIME_MODE}
          FUSIONAUTH_APP_URL: http://fusionauth:9011
          SEARCH_SERVERS: http://search:9200
          SEARCH_TYPE: ${FUSIONAUTH_SEARCH_TYPE}
          FUSIONAUTH_APP_INSTALLATION_SOURCE: fusionauth-containers
        healthcheck:
          test: curl --silent --fail http://localhost:9011/api/status -o /dev/null -w "%{http_code}"
          interval: 5s
          timeout: 5s
          retries: 5
        restart: unless-stopped
        ports:
          - 9011:9011
        volumes:
          - fusionauth_config:/usr/local/fusionauth/config
          - ${FUSIONAUTH_LOCAL_KICKSTART_DIRECTORY}:/usr/local/fusionauth/kickstart
          - ${FUSIONAUTH_LOCAL_PLUGIN_DIRECTORY}:/usr/local/fusionauth/plugins
    
      # Open Search isn't technically required, but the `fusionauth` service currently depends on it, so we start it here.
      # You can change the search engine backend to `database` in the `.env` file if you would prefer to use that.
      # Then you can remove the search dependency above and disable this service.
      search:
        image: opensearchproject/opensearch:2.11.0
        environment:
          cluster.name: fusionauth
          discovery.type: single-node
          node.name: search
          plugins.security.disabled: "true"
          bootstrap.memory_lock: "true"
          OPENSEARCH_JAVA_OPTS: ${OPENSEARCH_JAVA_OPTS}
        healthcheck:
          interval: 10s
          retries: 80
          test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:9200/
        restart: unless-stopped
        ulimits:
          memlock:
            soft: -1
            hard: -1
          nofile:
            soft: 65536
            hard: 65536
        ports:
          - 9200:9200 # REST API
          - 9600:9600 # Performance Analyzer
        volumes:
          - search_data:/usr/share/opensearch/data
    
      #
      # Optional services
      #
    
      # Caddy can be used as a proxy to FusionAuth.
      caddy:
        image: caddy
        profiles:
          - caddy
        depends_on:
          - fusionauth
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./Caddyfile:/etc/caddy/Caddyfile
          - caddy_data:/data
          - caddy_config:/config
    
      # Mailcatcher is a nice SMTP server that can be used for development and testing. You'll need to configure FusionAuth
      # to use Mailcatcher (or use a Kickstart file that points the SMTP configuration to localhost:1025).
      mailcatcher:
        image: sj26/mailcatcher
        profiles:
          - mailcatcher
        ports:
          - "1025:1025"
          - "1080:1080"
        healthcheck:
          interval: 10s
          retries: 80
          test: wget -q -O /dev/null http://mailcatcher:1080/
    
      # Zookeeper is needed for Kafka
      zookeeper:
        image: confluentinc/cp-zookeeper:latest
        profiles:
          - kafka
        environment:
          ZOOKEEPER_CLIENT_PORT: 2181
          ZOOKEEPER_TICK_TIME: 2000
        ports:
          - 2181:2181
    
      # Kafka can be used for Webhooks rather than HTTP. You'll need to configure FusionAuth to use Kafka (or use a
      # Kickstart file that enables Kafka).
      kafka:
        image: confluentinc/cp-kafka:latest
        profiles:
          - kafka
        depends_on:
          - zookeeper
        ports:
          - 9092:9092
        environment:
          KAFKA_BROKER_ID: 1
          KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
          KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
          KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    
      # Cleanspeak provides filtering of usernames and profile data to prevent profanity and other unwanted content. You'll
      # need a Cleanspeak license to enable this service.
      cleanspeak:
        image: cleanspeak/cleanspeak-app:latest
        profiles:
          - cleanspeak
        depends_on:
          db:
            condition: service_healthy
          search:
            condition: service_healthy
        environment:
          DATABASE_URL: jdbc:postgresql://db:5432/cleanspeak
          DATABASE_ROOT_USERNAME: ${POSTGRES_USER}
          DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
          DATABASE_USERNAME: ${DATABASE_USER}
          DATABASE_PASSWORD: ${DATABASE_PASSWORD}
          CLEANSPEAK_APP_MEMORY: ${CLEANSPEAK_APP_MEMORY}
          LICENSE_ID: ${CLEANSPEAK_LICENSE_ID}
          SEARCH_SERVERS: http://search:9200
        restart: unless-stopped
        ports:
          - 8001:8001
        volumes:
          - cs_config:/usr/local/cleanspeak/config
    
      # OpenTelemetry can be used to collect metrics from FusionAuth and push them to Prometheus or other systems. You might need
      # to configure OpenTelemetry by editing the opentelementy-collector-config.yml file.
      opentelemetry:
        image: otel/opentelemetry-collector
        profiles:
          - opentelemetry
        depends_on:
          - fusionauth
        ports:
          - 8889:8889
          - 4318:4318
        volumes:
          - ${OPENTELEMETRY_COLLECTOR_CONFIG_FILE}:/etc/opentelemetry/collector-config.yml
        command: [ "--config=/etc/opentelemetry/collector-config.yml" ]
    
      # Prometheus can be used to monitor FusionAuth and can be used with OpenTelemetry or directly. Depending on the way you want to
      # use Prometheus, you might need to change the PROMETHEUS_CONFIG_FILE variable to point to a different configuration file or
      # edit the configuration files as needed.
      prometheus:
        image: prom/prometheus
        profiles:
          - prometheus
        depends_on:
          - fusionauth
        ports:
          - 9090:9090
        volumes:
          - ${PROMETHEUS_CONFIG_FILE}:/etc/prometheus/prometheus.yml
          - ${PROMETHEUS_RULES_FILE}:/etc/prometheus/rules.yml
          - prometheus_data:/prometheus
    
      # Alertmanager can be used in conjunction with Prometheus to handle errors that are collected.
      alertmanager:
        image: prom/alertmanager:v0.28.1
        profiles:
          - alertmanager
        depends_on:
          - prometheus
        ports:
          - 9093:9093
        volumes:
          - ${ALERTMANAGER_CONFIG_FILE}:/etc/alertmanager/alertmanager-config.yml
    
    volumes:
      caddy_config:
      caddy_data:
      cs_config:
      db_data:
      fusionauth_config:
      prometheus_data:
      search_data:
    $ curl -o .env https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/main/docker/fusionauth/.env
    
    Full .env example
    .env
    ALERTMANAGER_CONFIG_FILE=./monitoring/alertmanager-config.yml
    CLEANSPEAK_APP_MEMORY=512M
    CLEANSPEAK_LICENSE_ID=insert-license-id-here
    DATABASE_USER=fusionauth
    DATABASE_PASSWORD=hkaLBM3RVnyYeYeqE3WI1w2e4Avpy0Wd5O3s3
    FUSIONAUTH_APP_KICKSTART_FILE=/usr/local/fusionauth/kickstart/kickstart.json
    FUSIONAUTH_APP_MEMORY=512M
    FUSIONAUTH_APP_RUNTIME_MODE=development
    FUSIONAUTH_LOCAL_KICKSTART_DIRECTORY=./kickstart
    FUSIONAUTH_LOCAL_PLUGIN_DIRECTORY=./plugins
    FUSIONAUTH_SEARCH_TYPE=elasticsearch
    OPENSEARCH_JAVA_OPTS="-Xms512m -Xmx512m"
    OPENTELEMETRY_COLLECTOR_CONFIG_FILE=./monitoring/opentelemetry-collector-config.yml
    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    PROMETHEUS_CONFIG_FILE=./monitoring/prometheus-config.yml
    PROMETHEUS_RULES_FILE=./monitoring/prometheus-rules.yml
  2. Start the FusionAuth docker container:

    $ docker compose up -d
    
  3. Wait until all networks, volumes, and containers show a green status of Healthy, Started, or Created. This may take a few minutes, depending on your network speed and cached dependencies.

  4. Visit http://localhost:9011 to access the Admin UI.

  5. Congratulations, you have a working instance of FusionAuth!

Architecture#

A typical FusionAuth install includes three services: fusionauth-app, a database, and a search service:

A diagram depicting three services in a docker container: a FusionAuth service, a database service, and a search service.

A diagram depicting three services in a docker container: a FusionAuth service, a database service, and a search service.

Next steps#

To set up login for an application, see our First Time Setup guide.