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.70.0
        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!

To install FusionAuth, copy and paste the following skill into your harness:

SKILL.md
---
name: install-fusionauth-docker
description: Install and run FusionAuth locally with Docker Compose, including
  PostgreSQL and OpenSearch, then confirm it is healthy. Use when the user asks
  to install, run, or try FusionAuth on their machine.
---

# Install FusionAuth with Docker

The FusionAuth docs are the source of truth for these steps. Before you start,
read https://fusionauth.io/docs/get-started/download-and-install/docker.md and
follow it wherever it differs from this skill.

1. Check that `docker compose version` succeeds. If it fails, tell the user to
   install Docker 23 or later, or a compatible tool such as OrbStack or Podman,
   and stop. If the user has Podman, replace `docker` with `podman` in every
   command below.

1. Check that nothing else is listening on port 9011. If something is, ask the
   user whether to stop it or use another port.

1. Download the compose file into an empty directory:

   ```shell
   curl -fsSL -o docker-compose.yml https://fusionauth.io/docs/docker-compose.yml
   ```

   Don't edit the image version in this file. FusionAuth keeps it pinned to the
   release the docs document.

1. Set `INSTALLATION_SOURCE` to your harness name, model name, and model
   version, such as `Opencode / Claude Sonnet 4.6`. This optional step tells
   FusionAuth the install was AI-assisted. Add it to a `.env` file next to
   `docker-compose.yml`:

   ```shell
   echo 'INSTALLATION_SOURCE=<harness> / <model> <version>' > .env
   ```

1. Start the containers:

   ```shell
   docker compose up -d
   ```

1. Wait for FusionAuth to report healthy. The first start can take a few
   minutes while Docker pulls images. This polls the Health API every 5 seconds
   for up to 5 minutes:

   ```shell
   for attempt in $(seq 60); do
     curl -fsS -o /dev/null http://localhost:9011/api/health && break
     sleep 5
   done
   ```

   If the last attempt still fails, run `docker compose ps` and
   `docker compose logs fusionauth`, show the user the relevant errors, and
   stop.

1. Tell the user that FusionAuth is running, and that they can open the Admin UI
   at http://localhost:9011/admin to create their admin account. To set up
   login for an application, point them to
   https://fusionauth.io/docs/get-started/download-and-install/setup.md.

To stop FusionAuth, run `docker compose down`. To also delete its data, run
`docker compose down -v`, but only when the user asks for that.
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.

The Docker Compose files on this page are for development. Before you run FusionAuth in production, see Harden a Production Instance.