Skip to content

Deploy using Docker/Podman

This guide provides the necessary steps to deploy a "battery-included" Neo instance, using Docker or Podman that includes:

  • an official PostgreSQL instance, version 16.10-alpine3.21
  • version 3.1.1 of Neo
  • version 3.1.1 of Neo UI

For testing purposes, a local SAMBA service is also included.

Prerequisites

Before deploying the NetApp Connector (Neo) using Podman Compose, ensure that you have the following prerequisites in place:

Docker
Podman
  • Sufficient system resources to run the NetApp Core Connector. Refer to the Sizing Guide in the Deployment section for recommended specifications.
  • cifs-utils package needs to be deployed on the Linux host.
  • SELinux contexts might require adjustements based on your specific Linux host security profile.

WARNING

The main difference between docker and podman is linked to podman requiring a sudo prefix to start as a privileged container which is not required by docker because the daemon is already running all containers in a privileged mode.

Deployment Guide

Create a directory called "neo-test" in a directory of your choice to host the configuration files below.

Environment variables

First, we need to set up the following .env file to configure the database.

## NetApp Neo Settings (Required)

## NetApp Neo Database Settings (required)
DBT=postgres                    ## Database type: postgres or mysql
DBB=5432                        ## Database binding port: postgres is 5432 and mysql is 3306
DBU=postgres                    ## Database username
DBP=neodbsecret                 ## Database password
DBH=neodb                       ## Dababase host: if using included postgres then value is neodb
DBN=neoconnectortest            ## Database name

##
DATABASE_URL=${DBT}://${DBU}:${DBP}@${DBH}:${DBB}/${DBN}      # <== Needs to be changed! 
## or for MySQL:
#DATABASE_URL=mysql://user:password@localhost:3306/neoconnectortest

## (Un)comment if using or not the included postgres database
POSTGRES_USER=${DBU}
POSTGRES_PASSWORD=${DBP}
POSTGRES_DB=${DBN}

TIP

The usage of Docker/Podman Secrets is another path to explore addressing the challenge of credentials stored locally on a hard drive.

Compose Container file

Download the latest neo-containerfile.yml or copy its content from:

yml
services:

  ## (Un)comment if using or not the included postgres database
  neodb:
    image: docker.io/library/postgres:16.10-alpine3.21
    container_name: neodb
    env_file:
      - .env
    ports:
      - 5432:5432
    networks:
      - netapp-neo
    volumes:
      - neodb:/var/lib/postgresql/data
    restart: unless-stopped

  neo:
    image: ghcr.io/netapp/netapp-copilot-connector:3.2.0 
    container_name: neo
    # deploy: # Uncomment this section to enable GPU support
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: 1 # Adjust count based on your GPU availability
    #           capabilities: [gpu]
    cap_add:
      - SYS_ADMIN
      - DAC_READ_SEARCH
      - DAC_OVERRIDE
    security_opt:
      - apparmor:unconfined
    ports:
      - "8081:8080"
    networks:
      - netapp-neo      
    env_file:
      - .env
    environment:
      - PORT=8080
      - PYTHONUNBUFFERED=1
    restart: unless-stopped

  neoui:
    image: ghcr.io/beezy-dev/neo-ui-framework:3.1.0
    container_name: neoui
    ports:
      - "8080:80"
    environment:
      - NEO_API=http://neo:8080   # ← add this
    networks:
      - netapp-neo
    restart: unless-stopped

  ## (Un)comment if using or not the included SMB/CIFS service
  # neosmb:
  #   image: docker.io/dockurr/samba
  #   container_name: neosmb
  #   environment:
  #     NAME: "data"
  #     USER: "smb"
  #     PASS: "smb"
  #     UID: 1000
  #     GID: 1000
  #   ports:
  #     - 445:445
  #   networks:
  #     - netapp-neo      
  #   volumes:
  #     - neosmb:/storage
  #   restart: unless-stopped

networks:
  netapp-neo:
    driver: bridge

## (Un)comment if using or not the included postgres database or/and SMB/CIFS service
volumes:
  neodb:
    driver: local
  neosmb:
    driver: local

Start the containers

docker compose -f neo-all-in.yml up --build -d
docker ps

Expected output:
CONTAINER ID  IMAGE                                          COMMAND     CREATED        STATUS        PORTS                   NAMES
d8bbf02435fb  docker.io/library/postgres:16.10-alpine3.21    postgres    7 seconds ago  Up 8 seconds  0.0.0.0:5432->5432/tcp  neodb
1aefb8db34e8  ghcr.io/netapp/netapp-copilot-connector:3.1.1              6 seconds ago  Up 7 seconds  0.0.0.0:8081->8080/tcp  neo
792aa53a0689  ghcr.io/beezy-dev/neo-ui-framework:3.1.0                   5 seconds ago  Up 6 seconds  0.0.0.0:8080->80/tcp    neoui
670ec2f91cdf  docker.io/dockurr/samba:latest                             4 seconds ago  Up 4 seconds  0.0.0.0:445->445/tcp    neosmb

Recover logs:
docker compose -f neo-all-in.yml logs
sudo podman compose -f neo-all-in.yml up --build -d
sudo podman ps

Expected output:
CONTAINER ID  IMAGE                                          COMMAND     CREATED        STATUS        PORTS                   NAMES
d8bbf02435fb  docker.io/library/postgres:16.10-alpine3.21    postgres    7 seconds ago  Up 8 seconds  0.0.0.0:5432->5432/tcp  neodb
1aefb8db34e8  ghcr.io/netapp/netapp-copilot-connector:3.1.1              6 seconds ago  Up 7 seconds  0.0.0.0:8081->8080/tcp  neo
792aa53a0689  ghcr.io/beezy-dev/neo-ui-framework:3.1.0                   5 seconds ago  Up 6 seconds  0.0.0.0:8080->80/tcp    neoui
670ec2f91cdf  docker.io/dockurr/samba:latest                             4 seconds ago  Up 4 seconds  0.0.0.0:445->445/tcp    neosmb

Recover logs:
sudo podman compose -f neo-all-in.yml logs

You should see logs indicating that the NetApp Neo Core container has started successfully as follows:

log
neo  | 2025-12-03 19:46:43.882 | INFO     | app.main:lifespan:146 - Starting up application...
neo  | 2025-12-03 19:46:43.882 | INFO     | app.main:lifespan:150 - 🔧 Setup mode: Skipping license validation and Graph initialization
neo  | 2025-12-03 19:46:43.882 | INFO     | app.main:lifespan:151 - 📋 Complete setup via /api/v1/setup endpoints to enable full functionality
neo  | INFO:     Application startup complete.
neo  | INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

Configure

via GUI

Neo Console is available at http://your.ip:8080 or http://myhost.mydomain.tld:8080 and will welcome you with the following screen:

image

Go to Settings and select the tab Neo Core to start the configuration image

Once a valid license key is entered and saved, the page will refresh to show the following status: image

At this stage, the M365 Copilot Graph or other settings can be configured now or later. Once the desired configuration is complete, click "Setup Complete".
This will trigger a restart of Neo's container with the configured settings: image

Once Neo has restarted, the page will reload with the status "Complete", and a button "Admin Credentials" will appear to recover the temporary credentials: image

Credentials image Updating credentials image

IMPORTANT

This temporary password will not be accessible again once you have logged in with the credentials. Make sure to either save it in your password m(anager or change it in the Users page.

image

via API

Neo can also be configured via the API, available at http://your.ip:8081/docs or http://myhost.mydomain.tld:8081/docs.

Troubleshooting

postgres

Check if the DB was created using both methods to verify the DB and networking at the same time:

BASH
docker exec -it neodb psql -h localhost -U postgres -l
BASH
sudo podman exec -it neodb psql -h localhost -U postgres -l

or if you have psql utils deployed:

BASH
psql -U postgres -h 192.168.122.245 -p 5432 postgres -l

Expected output:

List of databases
        Name        |  Owner   | Encoding | Locale Provider |  Collate   |   Ctype    | ICU Locale | ICU Rules |   Access privileges
--------------------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
 netappconnectorrom | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |            |           |
 postgres           | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |            |           |
 template0          | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |            |           | =c/postgres          +
                    |          |          |                 |            |            |            |           | postgres=CTc/postgres
 template1          | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |            |           | =c/postgres          +
                    |          |          |                 |            |            |            |           | postgres=CTc/postgres
(4 rows)

Neo

Check the logs and share these with the team for any potential issues you might encounter:

BASH
docker logs -f neo
BASH
sudo podman logs -f neo

Neo UI

Check the logs and share these with the team for any potential issues you might encounter:

BASH
docker logs -f neoui
BASH
sudo podman logs -f neoui

Check the web console in the Browser for additional error messages.

Samba (optional)

Check the logs and share these with the team for any potential issues you might encounter:

BASH
docker logs -f neosmb
BASH
sudo podman logs -f neosmb

Next steps

This concludes the steps to deploy the NetApp Neo Core using Docker/Podman Compose. For more advanced configurations and management options, please refer to the Management section of the documentation.