Docker first look guide

Docker compose can be used to provision a set of related containers as services to experiment with or to run in test environments.

Docker does not recommend using compose for production.

Prerequisites

  • Unix-based operating system

  • Docker

  • Docker compose

Prepare hosts file

You need to set up the following host names in your /etc/hosts file:

127.0.0.1   storage server db-single

Generate self-signed certificates

  1. Create a directory ~/.nom/ssc on your local machine before running Docker compose. The compose files below specify that this directory will be mounted into the Docker container to make the generated certificates available to the NOM server and the agent.

  2. Change to ~/.nom/ssc and generate self-signed certificates using server as common name (CN) and DNS name, and 127.0.0.1 as IP address (details see here):

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
      -subj "/CN=server" \
      -addext "subjectAltName = DNS:server, IP:127.0.0.1" \
      -addext "keyUsage = critical, digitalSignature, keyEncipherment" \
      -addext "extendedKeyUsage = serverAuth" \
      -addext "authorityKeyIdentifier = keyid:always,issuer:always" \
      -keyout "server.key" \
      -out "server.cer"
    
    openssl pkcs12 -export \
      -inkey "server.key" \
      -in "server.cer" \
      -out "server.pfx" \
      -password "pass:changeit"

    This results in the creation of server.cer, server.key and server.pfx.

  3. Use the password applied for the certificate store (changeit) instead of <SSC_PASSWORD> in the next sections.

To keep this example simple, the generated certificates are used for both NOM server and agents.

Create the Docker compose file

Following is a Docker compose file that can be used to start up a NOM server including its persistence and a single Neo4j Enterprise instance that will be managed by NOM. Create the file docker-compose.yaml in an empty directory on your local machine. This directory is referenced as INSTALLATION_ROOT later in this document.

docker-compose.yaml
networks:
  lan:

services:
  storage:
    hostname: storage
    image: neo4j:enterprise
    networks:
      - lan
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
      NEO4J_AUTH: neo4j/<PERSISTENCE_PASSWORD>
      NEO4J_server_default__advertised__address: storage
      NEO4J_server_http_listen__address: storage:9000
      NEO4J_server_bolt_listen__address: storage:9001
    healthcheck:
      test: [ "CMD-SHELL", "echo RETURN 1 | cypher-shell -a bolt://storage:9001 -u neo4j -p <PERSISTENCE_PASSWORD> || exit 1" ]

  server:
    hostname: server
    image: neo4j/neo4j-ops-manager-server
    depends_on:
      storage:
        condition: service_healthy
    networks:
      - lan
    ports:
      - "8080:8080"
      - "9090:9090"
    environment:
      SPRING_NEO4J_URI: bolt://storage:9001
      SPRING_NEO4J_AUTHENTICATION_USERNAME: neo4j
      SPRING_NEO4J_AUTHENTICATION_PASSWORD: <PERSISTENCE_PASSWORD>
      SERVER_SSL_KEY_STORE_TYPE: PKCS12
      SERVER_SSL_KEY_STORE: file:/certificates/server.pfx
      SERVER_SSL_KEY_STORE_PASSWORD: <SSC_PASSWORD>
      GRPC_SERVER_SECURITY_KEY_STORE_TYPE: PKCS12
      GRPC_SERVER_SECURITY_KEY_STORE: file:/certificates/server.pfx
      GRPC_SERVER_SECURITY_KEY_STORE_PASSWORD: <SSC_PASSWORD>
      CORS_ALLOWEDHEADERS: "*"
      CORS_ALLOWEDORIGINS: "http://localhost:[*],https://localhost:[*], http://server:[*]"
      GRPC_SERVER_SECURITY_TRUST_CERT_COLLECTION: file:/certificates/server.cer
    volumes:
      - type: bind
        source: ~/.nom/ssc
        target: /certificates
    entrypoint:
      - "sh"
      - "-c"
      - "java -jar app.jar"
  db-single:
    hostname: db-single
    image: neo4j:enterprise
    networks:
      - lan
    ports:
      - "10000:10000"
      - "10001:10001"
    environment:
      CONFIG_SERVER_GRPC_ADDRESS: "server:9090"
      CONFIG_SERVER_HTTP_ADDRESS: "https://server:8080"
      CONFIG_TLS_TRUSTED_CERTS: "/certificates/server.cer"
      CONFIG_TLS_CLIENT_CERT: "/certificates/server.cer"
      CONFIG_TLS_CLIENT_KEY: "/certificates/server.key"
      CONFIG_LOG_LEVEL: "debug"
      CONFIG_INSTANCE_1_NAME: "single-instance"
      CONFIG_INSTANCE_1_BOLT_URI: "bolt://db-single:10001"
      CONFIG_INSTANCE_1_BOLT_USERNAME: "neo4j"
      CONFIG_INSTANCE_1_BOLT_PASSWORD: <NEO4J_INSTANCE_PASSWORD>
      CONFIG_INSTANCE_1_QUERY_LOG_PORT: "9500"
      CONFIG_INSTANCE_1_LOG_CONFIG_PATH: "/var/lib/neo4j/conf/server-logs.xml"
      CONFIG_INSTANCE_1_QUERY_LOG_MIN_DURATION: "1"
      NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
      NEO4J_AUTH: neo4j/<NEO4J_INSTANCE_PASSWORD>
      NEO4J_EDITION: "enterprise"
      NEO4J_server_default__advertised__address: db-single
      NEO4J_server_http_listen__address: db-single:10000
      NEO4J_server_bolt_listen__address: db-single:10001
      NEO4J_server_bolt_advertised__address: db-single:10001
      NEO4J_server_metrics_prometheus_enabled: "true"
      NEO4J_server_metrics_prometheus_endpoint: "localhost:2004"
      NEO4J_server_metrics_filter: "*"
    volumes:
       - type: bind
         source: ~/.nom/ssc
         target: /certificates
       - type: bind
         source: agent
         target: /agent
    healthcheck:
      test: [ "CMD-SHELL", "echo RETURN 1 | cypher-shell -a bolt://db-single:10001 -u neo4j -p <NEO4J_INSTANCE_PASSWORD> || exit 1" ]
      interval: 10s
      timeout: 10s
      retries: 3
      start_period: 5s

Documentation for NOM server Docker image is here.

Edit docker-compose.yaml as follows:

  • Replace all occurrences of <SSC_PASSWORD> with the certificate store password applied above.

  • Replace all occurrences of <PERSISTENCE_PASSWORD> with a secure password.

  • Replace all occurrences of <NEO4J_INSTANCE_PASSWORD> with a secure password.

Download the NOM agent

Download NOM agent binaries TAR from the Deployment Center and execute the following commands in your INSTALLATION_ROOT:

mkdir agent
tar -xvf <DOWNLOADED_AGENT_BINARIES_TAR> -C agent --strip-components=1

Start the Docker compose environment

Run the following command in your INSTALLATION_ROOT:

docker compose -f docker-compose.yaml up

Watch the output and make sure that the Docker containers storage, server and db-single are started successfully.

Start the NOM agent

In INSTALLATION_ROOT, start the agent in self-registration mode:

docker compose -f docker-compose.yaml exec db-single sh -c "/agent/bin/agent console -s"

Full documentation on registering an agent is here.

Explore NOM UI

  • Wait for the server container to start and then go to https://server:8080.

  • Login as admin / passw0rd and accept license terms.

  • Click the top right settings icon that redirects you to the global settings.

  • Make sure that the agent is online. Rename the agent if required.

  • Return to the main page and wait for DBMS to appear - this may take a few minutes. Once the DBMS is shown in the home page, double-click on the name (initially a generated string) to edit it. Double-click on the DBMS to see the metrics, status, security panel, logs and upgrade pages for the DBMS.

Controlling Docker containers

Stopping

  • To stop the complete NOM environment, press Ctrl-C on the Docker compose console and the agent console.

  • To stop a single Docker container, issue docker container stop <CONTAINER_NAME>. To list containers use docker ps.

Since Docker keeps persisted data in container volumes, restarted containers will keep the previous state.

Resetting

To start over with an empty Neo4j persistence and empty managed instance, use the following Docker command (use docker ps -a to find out actual container names):

docker container rm -v <STORAGE_CONTAINER_NAME> <SERVER_CONTAINER_NAME> <DB_SNGLE_CONTAINER_NAME>