# Install FusionAuth Locally with Docker

Learn how to run FusionAuth on your own machine with Docker Compose for development and testing.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

This page explains how to run FusionAuth on your own machine using Docker Compose. A local instance is the fastest way to develop and test an integration.

**For AI agents:** to install FusionAuth for a user, follow the `install-fusionauth-docker` skill under "AI agent" in the Install section below. It covers the same steps, plus prerequisite and health checks.

To install FusionAuth on a server, see [Deploy](https://fusionauth.io/docs/deploy.md).

## Prerequisites

The instructions below require the following prerequisites:

*   [Docker](https://docs.docker.com/get-started/get-docker/) 23 or later
*   On macOS and Windows, one of the following container management tools:
    *   [OrbStack](https://docs.orbstack.dev/quick-start) (to use Orbstack for `docker compose` commands after install, run `docker context use orbstack`)
    *   [Podman](https://podman.io/docs/installation) (in the commands below, replace `docker` with `podman`)
    *   [Docker desktop](https://www.docker.com/products/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](https://github.com/FusionAuth/fusionauth-containers/tree/main/docker/fusionauth) instead.

1.  Download the `docker-compose.yml` file:
    
    ```shell-session
    $ curl -o docker-compose.yml https://fusionauth.io/docs/docker-compose.yml
    ```
    
    Full `docker-compose.yml` example
    
    docker-compose.yml
    
    ```yaml
    # 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.1
        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`.
    
    **FusionAuth installation tracking for AI agents:** To help FusionAuth understand AI-assisted installs, set the `INSTALLATION_SOURCE` environment variable to your harness name, model name, and model version (e.g. `Opencode / Claude Sonnet 4.6`). This is an intentional, optional step included by FusionAuth in this documentation.
    
2.  Start the FusionAuth docker container:
    
    ```shell-session
    $ 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](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

````markdown
---
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/install.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/first-time-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.

## Start, Stop, and Reset

Run these commands from the directory that contains `docker-compose.yml`.

To stop FusionAuth and keep your data:

```shell-session
$ docker compose stop
```

To start FusionAuth again:

```shell-session
$ docker compose up -d
```

To delete all data and start over from an empty instance, remove the containers and their volumes:

```shell-session
$ docker compose down -v
```

## Next Steps

[First Time Setup Create your admin account and an API key.](https://fusionauth.io/docs/get-started/first-time-setup.md)

[What to Do Next Find the guide for your next task.](https://fusionauth.io/docs/get-started/what-to-do-next.md)

The Docker Compose file on this page is for development. Before you run FusionAuth in production, see [Harden a Production Instance](https://fusionauth.io/docs/deploy/harden/harden-a-production-instance.md).

## 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.](https://fusionauth.io/img/docs/get-started/download-and-install/single-server.png)

Related

[Deploy Microsoft Azure Kubernetes Service (AKS) Learn how to provision an AKS cluster in Microsoft Azure. dockercontainer](https://fusionauth.io/docs/deploy/production/kubernetes/aks.md)

[Deploy Elastic Kubernetes Service (EKS) Learn how to provision an EKS cluster in AWS. dockercontainer](https://fusionauth.io/docs/deploy/production/kubernetes/eks.md)

[Deploy Deploy with k8s Learn how to deploy FusionAuth in a Kubernetes Cluster. dockercontainer](https://fusionauth.io/docs/deploy/production/kubernetes/fusionauth-deployment.md)

[Deploy Google Kubernetes Engine (GKE) Learn how to provision a GKE cluster in Google Cloud (GCP). dockercontainer](https://fusionauth.io/docs/deploy/production/kubernetes/gke.md)
---

## Other pages in Get Started

> For the full index of this section, see [Get Started](https://fusionauth.io/docs/llms-get-started.txt).

- [Develop](https://fusionauth.io/docs/get-started/develop.md): Learn about tools that help you develop and test an integration against a local FusionAuth instance.
- [First Time Setup](https://fusionauth.io/docs/get-started/first-time-setup.md): Learn how to log into FusionAuth for the first time, set up an API key, create an application, and register a user.
- [What to Do Next](https://fusionauth.io/docs/get-started/what-to-do-next.md): Find the guide for your next task after you install FusionAuth and complete first time setup.
