This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Deploy using Docker Compose

In this topic, you’ll learn how to use Docker Compose to get up and running with a stand-alone Anchore Enterprise deployment.

Before moving further with Anchore Enterprise, it is highly recommended to read the Overview sections to gain a deeper understanding of fundamentals, concepts, and proper usage.

Prerequisites and System Requirements

The following instructions assume you are using a system running Docker Engine v20.10 or later, have access to APT resources, and a version of Docker Compose that supports at least v2 of the Compose configuration format.

  • A stand-alone deployment requires at least 32GB of RAM and enough disk space available to support the largest container images or source repositories that you intend to analyze. It is recommended to consider three times the largest source repository or container image size. We suggest at least 40GB of disk space, the more the better.
  • To access Anchore Enterprise, you need a valid license.yaml file that has been issued to you by Anchore Customer Success. If you do not have a license yet, visit the Anchore Contact page to request one.
  • You need root or sudo access to the system where you will be running docker and deploying Anchore Enterprise, all commands in this document are run as root.

External Database Requirements


Get Started

Follow the steps below to get up and running!

Step 1: Authenticate with the Official Anchore Registry

You’ll need authenticated access to the anchore/enterprise and anchore/enterprise-ui repositories on Docker Hub to pull the images. The Anchore Account or Customer Success team will provide a Docker Hub PAT (Personal Access Token) for access to images. Log in with your Docker PAT to push and pull images from Docker Hub:

docker login -u <your_dockerhub_pat_user> -p <your_dockerhub_pat>

Step 2: Set Up the Deployment Directory

Create a dedicated project directory to store your configuration files, system license, and database variables. Subsequent steps assume you are working from this directory.

mkdir anchore-enterprise && cd anchore-enterprise

Step 3: Download the Deployment Files

Download the Docker Compose file and the Dockerfile database into your working directory, alongside the license file you received from Anchore. You may need to rename that file to license.yaml.

  1. Place your license.yaml file in the working directory:

    cp /path/to/your/license.yaml ./license.yaml
    
  2. Download the official Anchore Enterprise v6.0 Docker Compose configuration file:

    curl -sSfL https://docs.anchore.com/current/docs/deployment/docker_compose/docker-compose.yaml > docker-compose.yaml
    
  3. Download the Dockerfile used to build the v6.0-compatible Anchore database:

    curl -sSfL https://docs.anchore.com/current/docs/deployment/docker_compose/Dockerfile.anchore-db > Dockerfile.anchore-db
    

Step 4: Configure Secrets

Edit docker-compose.yaml to set the deployment secrets. Several of the variables ship commented out and must be uncommented and given a value, while others ship with a default. The secrets fall into two groups, configured in different services.

Database password — set this on the anchore-db service only:

VariableDescription
POSTGRES_PASSWORDThe password PostgreSQL initializes with. Set on the anchore-db service only. ANCHORE_DB_PASSWORD (below) must be set to this same value.

For example, the environment block of the anchore-db service looks like this:

# Inside docker-compose.yaml (anchore-db service)
environment:
  - POSTGRES_PASSWORD=mysecretpassword

Anchore Enterprise service secrets — set these on every Anchore Enterprise service, but not on the anchore-db service. Each value must be identical across all of those services:

VariableDescription
ANCHORE_ADMIN_PASSWORDStrong password for the Anchore Enterprise admin account.
ANCHORE_AUTH_SECRETShared authentication secret used for internal service communication.
ANCHORE_DB_PASSWORDDatabase password the Anchore Enterprise services use to connect to PostgreSQL. Must match POSTGRES_PASSWORD above.

For example, the environment block of each Anchore Enterprise service should look like this:

# Inside docker-compose.yaml (Anchore Enterprise services, not anchore-db)
environment:
  - ANCHORE_ADMIN_PASSWORD=<YourSecureAdminPasswordHere>
  - ANCHORE_AUTH_SECRET=<YourSecureAuthSecretHere>
  - ANCHORE_DB_PASSWORD=<YourSecureDBPasswordHere>

Step 5: Start the Deployment

Start your environment from the working directory. This builds the database image and starts Anchore Enterprise:

docker compose up -d
[+] up 14/14
 ✔ Network anchore-6000_default               Created                      0.4s
 ✔ Container anchore-6000-anchore-db-1        Healthy                      43.5s
 ✔ Container anchore-6000-ui-redis-1          Healthy                      43.6s
 ✔ Container anchore-6000-queue-1             Healthy                      37.3s
 ✔ Container anchore-6000-catalog-1           Healthy                      43.4s
 ✔ Container anchore-6000-reports_worker-1    Started                      43.3s
 ✔ Container anchore-6000-analyzer-1          Started                      42.8s
 ✔ Container anchore-6000-notifications-1     Started                      43.3s
 ✔ Container anchore-6000-component-catalog-1 Started                      43.3s
 ✔ Container anchore-6000-reports-1           Started                      42.8s
 ✔ Container anchore-6000-api-1               Healthy                      53.6s
 ✔ Container anchore-6000-data-syncer-1       Healthy                      48.4s
 ✔ Container anchore-6000-policy-engine-1     Started                      48.7s
 ✔ Container anchore-6000-ui-1                Started                      54.0s

Step 6: Install AnchoreCTL

anchorectl is the native CLI utility used to manage and orchestrate Anchore Enterprise.

In this step, we’ll install the lightweight Anchore Enterprise client tool, quickly test it using the version operation, and set up a few environment variables to allow it to interact with your deployment using the admin password you set during configuration.

Download and Install the Binary

Run the curl command below to download anchorectl and install it into your /usr/local/bin directory, which should be in your $PATH:

curl -sSfL https://anchorectl-releases.anchore.io/anchorectl/install.sh \
  | sh -s -- -b /usr/local/bin v6.0.0

Verify AnchoreCTL Installation

Run the following command to validate the version of anchorectl:

anchorectl version
Application:        anchorectl
Version:            6.0.0
SyftVersion:        v1.43.0
BuildDate:          2026-06-12T00:00:00Z
GitCommit:          f7604438b45f7161c11145999897d4ae3efcb0c8
GitDescription:     v6.0.0
Platform:           linux/amd64
GoVersion:          go1.23.0
Compiler:           gc

Expose Environment Variables

Configure your shell session to connect to your local Docker Compose runtime by exporting the appropriate access credentials:

export ANCHORECTL_URL="http://localhost:8228"
export ANCHORECTL_USERNAME="admin"
export ANCHORECTL_PASSWORD="<YOUR_ADMIN_PASSWORD>"

To persist these settings for future terminal sessions, append these lines to your shell profile (~/.bashrc or ~/.zshrc).

Step 7: Verify Service Availability

After a few minutes (depending on system speed) Anchore Enterprise and Anchore UI services should be up and running, ready to use. You can verify the containers are running with docker compose, as shown in the following example.

docker compose ps
NAME                               IMAGE                                                 COMMAND                  SERVICE             CREATED         STATUS                   PORTS
anchore-6000-analyzer-1            docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   analyzer            2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-anchore-db-1          anchore-6000-anchore-db                               "docker-entrypoint.s…"   anchore-db          2 minutes ago   Up 2 minutes (healthy)   5432/tcp
anchore-6000-api-1                 docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   api                 2 minutes ago   Up 2 minutes (healthy)   0.0.0.0:8228->8228/tcp, [::]:8228->8228/tcp
anchore-6000-catalog-1             docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   catalog             2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-component-catalog-1   docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   component-catalog   2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-data-syncer-1         docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   data-syncer         2 minutes ago   Up 2 minutes (healthy)   0.0.0.0:8778->8228/tcp, [::]:8778->8228/tcp
anchore-6000-notifications-1       docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   notifications       2 minutes ago   Up 2 minutes (healthy)   0.0.0.0:8668->8228/tcp, [::]:8668->8228/tcp
anchore-6000-policy-engine-1       docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   policy-engine       2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-queue-1               docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   queue               2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-reports-1             docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   reports             2 minutes ago   Up 2 minutes (healthy)   0.0.0.0:8558->8228/tcp, [::]:8558->8228/tcp
anchore-6000-reports_worker-1      docker.io/anchore/enterprise-dev:v6.0.0-rc16          "/docker-entrypoint.…"   reports_worker      2 minutes ago   Up 2 minutes (healthy)   8228/tcp
anchore-6000-ui-1                  docker.io/anchore/anchore-on-prem-ui-dev:v6.0.0-rc4   "/docker-entrypoint.…"   ui                  2 minutes ago   Up 2 minutes (healthy)   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp
anchore-6000-ui-redis-1            docker.io/library/redis:7.4.6                         "docker-entrypoint.s…"   ui-redis            2 minutes ago   Up 2 minutes (healthy)   6379/tcp

You can then run a command to get the status of the Anchore Enterprise services:

anchorectl system status
 ✔ Status system
┌───────────────────┬────────────────────┬───────────────────────────────┬──────┬────────────────┬────────────┬──────────────┐
│ SERVICE           │ HOST ID            │ URL                           │ UP   │ STATUS MESSAGE │ DB VERSION │ CODE VERSION │
├───────────────────┼────────────────────┼───────────────────────────────┼──────┼────────────────┼────────────┼──────────────┤
│ simplequeue       │ anchore-quickstart │ http://queue:8228             │ true │ available      │ 6000       │ 6.0.0       │
│ data_syncer       │ anchore-quickstart │ http://data-syncer:8228       │ true │ available      │ 6000       │ 6.0.0       │
│ reports_worker    │ anchore-quickstart │ http://reports_worker:8228    │ true │ available      │ 6000       │ 6.0.0       │
│ notifications     │ anchore-quickstart │ http://notifications:8228     │ true │ available      │ 6000       │ 6.0.0       │
│ reports           │ anchore-quickstart │ http://reports:8228           │ true │ available      │ 6000       │ 6.0.0       │
│ analyzer          │ anchore-quickstart │ http://analyzer:8228          │ true │ available      │ 6000       │ 6.0.0       │
│ component_catalog │ anchore-quickstart │ http://component-catalog:8228 │ true │ available      │ 6000       │ 6.0.0       │
│ catalog           │ anchore-quickstart │ http://catalog:8228           │ true │ available      │ 6000       │ 6.0.0       │
│ apiext            │ anchore-quickstart │ http://api:8228               │ true │ available      │ 6000       │ 6.0.0       │
│ policy_engine     │ anchore-quickstart │ http://policy-engine:8228     │ true │ available      │ 6000       │ 6.0.0       │
└───────────────────┴────────────────────┴───────────────────────────────┴──────┴────────────────┴────────────┴──────────────┘

You can check the status of your feed sync using AnchoreCTL:

anchorectl feed list
 ✔ List feed                                                                                                                                                                                                                                   
┌────────────────────────────────┬──────────────────────────────────────┬─────────┬─────────────────────────┬──────────────┐
│ FEED                           │ GROUP                                │ ENABLED │ DATA SERVICE BUILD TIME │ RECORD COUNT │
├────────────────────────────────┼──────────────────────────────────────┼─────────┼─────────────────────────┼──────────────┤
│ ClamAV Malware Database        │ clamav_db                            │ true    │ 2026-06-12T18:40:15Z    │ 1            │
│ Vulnerabilities                │ alpine:3.10                          │ true    │ 2026-06-12T13:12:49Z    │ 2363         │
│ Vulnerabilities                │ alpine:3.11                          │ true    │ 2026-06-12T13:12:49Z    │ 2701         │
│ Vulnerabilities                │ alpine:3.12                          │ true    │ 2026-06-12T13:12:49Z    │ 3235         │
│ …                              │ … (additional feed groups omitted) │ …       │ …                       │ …            │
│ Vulnerability Match Exclusions │ anchore:exclusions                   │ true    │ 2026-06-12T18:42:24Z    │ 27568        │
│ STIG Profiles                  │ apache-tomcat-9                      │ true    │ 2026-04-30T06:55:55Z    │ 1            │
│ STIG Profiles                  │ nginx                                │ true    │ 2026-04-30T06:55:55Z    │ 1            │
│ STIG Profiles                  │ rhel8                                │ true    │ 2026-04-30T06:55:55Z    │ 1            │
│ STIG Profiles                  │ rhel9                                │ true    │ 2026-04-30T06:55:55Z    │ 1            │
│ STIG Profiles                  │ ubuntu2204                           │ true    │ 2026-04-30T06:55:55Z    │ 1            │
│ STIG Profiles                  │ ubuntu2404                           │ true    │ 2026-04-30T06:55:55Z    │ 1            │
└────────────────────────────────┴──────────────────────────────────────┴─────────┴─────────────────────────┴──────────────┘

As soon as you see RecordCount values set for all vulnerability groups, the system is fully populated and ready to present vulnerability results. Note that data syncs are incremental, so the next time you start up Anchore Enterprise it will be ready immediately. The AnchoreCTL includes a useful utility that will block until the feeds have completed a successful sync:

anchorectl system wait
 ✔ API available                                                                                        system
 ✔ Services available                        [10 up]                                                    system
 ✔ Vulnerabilities feed ready                                                                           system

Step 8: Verify Functionality and Start Using Anchore Enterprise

Add an image to confirm that analysis works end to end. The --wait flag blocks until analysis completes:

anchorectl image add docker.io/library/alpine:latest --wait
 ✔ Added Image       docker.io/library/alpine:latest
 ✔ Analyzed Image    docker.io/library/alpine:latest
Image:
  status:           analyzed (active)
  tag:              docker.io/library/alpine:latest
  digest:           sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870

Once the image reaches the analyzed state, your deployment is working.

Next, confirm the Anchore Enterprise GUI is reachable before opening it in a browser:

curl -sSf -o /dev/null http://localhost:3000/ && echo "Anchore Enterprise GUI is reachable"
Anchore Enterprise GUI is reachable

If the command prints the success message, point your browser at the Anchore Enterprise GUI at http://localhost:3000/ and log in with the username admin and the ANCHORE_ADMIN_PASSWORD you set in Step 4. If it instead reports a connection error, wait a few moments for the ui service to finish starting and try again.

To put your deployment to work, follow the end-to-end workflows in the documentation:

Next Steps

Now that you have Anchore Enterprise running, you can begin to learn more about Anchore capabilities, architecture, concepts, and more.


Optional Add-ons

Enable Prometheus Monitoring

  1. Uncomment the following section at the bottom of the docker-compose.yaml file:

    #  # Uncomment this section to add a prometheus instance to gather metrics. This is mostly for quickstart to demonstrate prometheus metrics exported
    #  prometheus:
    #    image: docker.io/prom/prometheus:latest
    #    depends_on:
    #      - api
    #    volumes:
    #      - ./anchore-prometheus.yml:/etc/prometheus/prometheus.yml:z
    #    logging:
    #      driver: "json-file"
    #      options:
    #        max-size: 100m
    #    ports:
    #      - "9090:9090"
    #
    
  2. For each service entry in the docker-compose.yaml file, enable metrics in the API by changing:

    ANCHORE_ENABLE_METRICS=false
    

    to

    ANCHORE_ENABLE_METRICS=true
    
  3. Download the example Prometheus configuration into the same directory as the docker-compose.yaml file, with the name anchore-prometheus.yml:

    curl https://docs.anchore.com/current/docs/deployment/anchore-prometheus.yml > anchore-prometheus.yml
    docker compose up -d
    

    Result: You should see a new container started, and can access Prometheus via your browser at http://localhost:9090.

Enable Swagger UI

  1. Uncomment the swagger-ui-nginx and swagger-ui services at the bottom of the docker-compose.yaml file (the section is labelled with a “Uncomment this section to run a swagger UI service” comment).

  2. Download the nginx configuration into the same directory as the docker-compose.yaml file, with the name anchore-swaggerui-nginx.conf:

    curl https://docs.anchore.com/current/docs/deployment/anchore-swaggerui-nginx.conf > anchore-swaggerui-nginx.conf
    docker compose up -d
    

    Result: You should see a new container started, and can access Swagger UI via your browser at http://localhost:8080.

1 - Deploy Air-Gapped using Docker Compose

Anchore Enterprise can run in an air-gapped environment with no outbound internet access. The only air-gapped-specific work is getting the container images onto the air-gapped network: you pull and build them on an internet-connected system, then move them across. Once the images are in place, deployment follows the standard Docker Compose procedure.

Prerequisites

  • Low side (internet-facing) — the Docker static binary, used only to pull, build, and save images.
  • High side (air-gapped) — Docker Engine/CE and a Docker Compose that supports at least v2 of the Compose configuration format, used to run Anchore Enterprise.

Detailed sizing and other requirements are in Requirements.

Prepare the Images (low side)

  1. Download the current Docker Compose file and the database Dockerfile:

    curl -sSfL https://docs.anchore.com/current/docs/deployment/docker_compose/docker-compose.yaml > docker-compose.yaml
    curl -sSfL https://docs.anchore.com/current/docs/deployment/docker_compose/Dockerfile.anchore-db > Dockerfile.anchore-db
    
  2. Pull the Anchore Enterprise images:

    docker pull docker.io/anchore/enterprise:v6.0.0
    docker pull docker.io/anchore/enterprise-ui:v6.0.0
    docker pull docker.io/redis:7.4.6
    
  3. Build the database image from Dockerfile.anchore-db. This Dockerfile produces the PostgreSQL 17 image with pg_cron that Anchore Enterprise requires; see External Database Requirements for details.

    docker build -f Dockerfile.anchore-db -t anchore:db .
    

Move the Images to the High Side

Choose one of the following. A private container registry is the recommended path; use a local image tarball only if no registry is available on the air-gapped network.

  1. Re-tag the images for your private registry, replacing <registry> with your registry domain (for example, core.harbor.domain):

    docker tag docker.io/anchore/enterprise:v6.0.0 \
      <registry>/anchore/enterprise:v6.0.0
    docker tag docker.io/anchore/enterprise-ui:v6.0.0 \
      <registry>/anchore/enterprise-ui:v6.0.0
    docker tag docker.io/redis:7.4.6 <registry>/redis:7.4.6
    docker tag anchore:db <registry>/anchore:db
    
  2. If the registry is only reachable from the high side, save the tagged images and transfer them across (along with docker-compose.yaml, Dockerfile.anchore-db, and your license.yaml), then load them on the high side:

    # Low side
    docker save -o anchore-airgap-images.tar \
      <registry>/anchore/enterprise:v6.0.0 \
      <registry>/anchore/enterprise-ui:v6.0.0 \
      <registry>/redis:7.4.6 \
      <registry>/anchore:db
    
    # High side
    docker load -i anchore-airgap-images.tar
    
  3. Push the images to your private registry from a system that can reach it:

    docker push <registry>/anchore/enterprise:v6.0.0
    docker push <registry>/anchore/enterprise-ui:v6.0.0
    docker push <registry>/redis:7.4.6
    docker push <registry>/anchore:db
    

Option 2: Local Image Tarball

  1. Save the images to a single archive:

    docker save -o anchore-airgap-images.tar \
      docker.io/anchore/enterprise:v6.0.0 \
      docker.io/anchore/enterprise-ui:v6.0.0 \
      docker.io/redis:7.4.6 \
      anchore:db
    
  2. Transfer the archive — along with docker-compose.yaml, Dockerfile.anchore-db, and your license.yaml — to the high side, then load it:

    docker load -i anchore-airgap-images.tar
    docker images
    

Deploy on the High Side

Besides the images, the air-gapped host needs your docker-compose.yaml and license.yaml in the working directory. You downloaded the Compose file on the low side in Prepare the Images; if you have not already copied it and the license across with the images, do so now. The database is deployed from the pre-built anchore:db image you moved, so there is nothing to build here. Configure the deployment as described in Step 4: Configure Secrets, with two additional air-gapped-specific changes:

Point every image: line at your air-gapped images instead of Docker Hub. Use your private-registry tags for Option 1, or the local names you loaded for Option 2. The enterprise image is referenced by many services (api, catalog, analyzer, policy-engine, and others), so update every instance. The anchore-db service builds its image from the Dockerfile by default, so replace its build: section with a reference to the anchore:db image you built and moved earlier.

For example, the api service ships referencing Docker Hub, and anchore-db builds its image locally:

  api:
    image: docker.io/anchore/enterprise:v6.0.0
  anchore-db:
    build:
      context: .
      dockerfile: Dockerfile.anchore-db

Using a private registry (Option 1), change them to your registry tags:

  api:
    image: <registry>/anchore/enterprise:v6.0.0
  anchore-db:
    image: <registry>/anchore:db

Using local images loaded from the tarball (Option 2), reference the local image names instead:

  api:
    image: anchore/enterprise:v6.0.0
  anchore-db:
    image: anchore:db

Configure the deployment for air-gapped feed handling. Because the deployment cannot reach the Anchore Data Service, you must disable the Data Syncer’s automatic feed sync and then download and import feed bundles manually with AnchoreCTL. Both steps are described in Air-Gapped Feed Configuration.

Once the edits are complete, start the stack as described in Step 5: Start the Deployment.