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, PostgreSQL, and OpenSearch using Docker Compose. For optional services such as Kafka, CleanSpeak, and Prometheus, use the full configuration in the fusionauth-containers repository instead.

  1. Download the docker-compose.yml file:

    $ curl -o docker-compose.yml https://fusionauth.io/docs/docker-compose.yml
    
    Full docker-compose.yml example
    docker-compose.yml
    # FusionAuth with PostgreSQL and OpenSearch for local development.
    # Every ${NAME:-default} value can be overridden with an environment variable or a .env file.
    # For optional services such as Kafka, CleanSpeak, and Prometheus, see
    # https://github.com/FusionAuth/fusionauth-containers/blob/main/docker/fusionauth/docker-compose.yml
    
    services:
      db:
        image: postgres:16.0-bookworm
        environment:
          PGDATA: /var/lib/postgresql/data/pgdata
          POSTGRES_USER: ${POSTGRES_USER:-postgres}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
        healthcheck:
          test: [ "CMD-SHELL", "pg_isready -U postgres" ]
          interval: 5s
          timeout: 5s
          retries: 5
        restart: unless-stopped
        volumes:
          - db_data:/var/lib/postgresql/data
    
      fusionauth:
        image: fusionauth/fusionauth-app:1.69.4
        depends_on:
          db:
            condition: service_healthy
          search:
            condition: service_healthy
        environment:
          DATABASE_URL: jdbc:postgresql://db:5432/fusionauth
          DATABASE_ROOT_USERNAME: ${POSTGRES_USER:-postgres}
          DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
          DATABASE_USERNAME: ${DATABASE_USER:-fusionauth}
          DATABASE_PASSWORD: ${DATABASE_PASSWORD:-hkaLBM3RVnyYeYeqE3WI1w2e4Avpy0Wd5O3s3}
          FUSIONAUTH_APP_KICKSTART_FILE: ${FUSIONAUTH_APP_KICKSTART_FILE:-/usr/local/fusionauth/kickstart/kickstart.json}
          FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY:-512M}
          FUSIONAUTH_APP_RUNTIME_MODE: ${FUSIONAUTH_APP_RUNTIME_MODE:-development}
          FUSIONAUTH_APP_URL: http://fusionauth:9011
          SEARCH_SERVERS: http://search:9200
          SEARCH_TYPE: ${FUSIONAUTH_SEARCH_TYPE:-elasticsearch}
          FUSIONAUTH_APP_INSTALLATION_SOURCE: ${INSTALLATION_SOURCE:-fusionauth-docs}
        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:-./kickstart}:/usr/local/fusionauth/kickstart
          - ${FUSIONAUTH_LOCAL_PLUGIN_DIRECTORY:-./plugins}:/usr/local/fusionauth/plugins
    
      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:--Xms512m -Xmx512m}
        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
        volumes:
          - search_data:/usr/share/opensearch/data
    
    volumes:
      db_data:
      fusionauth_config:
      search_data:

    To change a setting such as a password or the memory limit, set the environment variable named in the file, or add it to a .env file next to docker-compose.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!

The Docker `latest` tag is not dynamic

If you use the latest tag in your Docker Compose configuration, you will not automatically update to the latest version of FusionAuth. If you use the latest tag, you must manually pull the latest image with docker pull fusionauth/fusionauth-app:latest or docker compose pull. Then, run docker compose up -d to recreate your container with the updated image. Use docker image prune to remove all unused images after updating.

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.