How to change the default admin password and add a user using docker image

Hi there,

I apologize for the newbiest of newbie comments but I have been trying to get authentication / authorization working with the event store docker image and just can’t seem to get to a solution.

What i want to achieve

My current es is completely open to the world which is fine for my dev box but I want to move it to a staging server. From what I have read the default user is:
-user: Admin
-password: changeit

The problem I am having is that the users tab is disabled when I log into the web UI and it doesnt force any password / user name entry.

I have also tried to install the es cli but that didn’t work either. Below is a copy of my docker compose for event store.

services:
eventstore.db:
build:
context: .
dockerfile: Dockerfile.eventstore
image: eventstore/eventstore:21.10.0-buster-slim
environment:
- EVENTSTORE_CLUSTER_SIZE=1
- EVENTSTORE_RUN_PROJECTIONS=All
- EVENTSTORE_START_STANDARD_PROJECTIONS=true
- EVENTSTORE_EXT_TCP_PORT=1113
- EVENTSTORE_HTTP_PORT=2113
- EVENTSTORE_INSECURE=false
- EVENTSTORE_ENABLE_EXTERNAL_TCP=true
- EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true
- EVENTSTORE_ADMIN_ON=true
- EVENTSTORE_DISABLE_FIRST_LEVEL_HTTP_AUTHORIZATION=false
- EVENTSTORE_AUTHENTICATION_TYPE=internal
- EVENTSTORE_ENABLE_ADMIN_ON=true
- EVENTSTORE_LOG_LEVEL=Debug
ports:
- ‘1113:1113’
- ‘2113:2113’
volumes:
- type: volume
source: eventstore-volume-data
target: /c/data/eventstore/data
- type: volume
source: eventstore-volume-logs
target: /c/data/eventstore/logs

Can someone please point me in the right direction? It’s rough spending so much time trying to do something that likely only takes a minute when done properly…

can you share the log in /c/data/eventstore/logs
around the time of starting up the node ?

I’m looking for something like
{"@t":"2024-08-06T12:43:43.8165828+02:00","@mt":"\r\nMODIFIED OPTIONS:\r\n

it contains the applied configuration.

I don’t seem to have anything in that folder… I’m using the default image provided by event store. What do I need to do to configure logging?

PS C:\Users\gilbe\neuraledge\inference-pool> docker exec -it 11d061b24a8b ls -l /c/data/eventstore/logs
total 0

OK so I went through the process of setting up ssl as per the instructions here:developers.eventstore.com/server/v5/security.html#setting-up-ssl-for-docker|

This didnt work, the openssl command provided doesn’t actually output any csr file, just a pem.

I then found this documentation:

Which mentions you can’t setup a secure connection on a single node and I need to setup a cluster with certificates.

This did work, based on the below docker compose I am able to get a three cluster node running.

## Inference Pool Docker Compose
#
# Event Store Cluster
# https://developers.eventstore.com/server/v24.6/installation.html#use-docker-compose
# Sets up a 3 node cluster with certficates 
#
#
# Nest JS API
# The api of the application. Runs on port 3000
#
# Client (Vite / React)
#  

services:
  # Setup service for generating certificates
  setup:
    image: eventstore/es-gencert-cli:1.0.2
    entrypoint: bash
    user: "1000:1000"
    command: >
      -c "mkdir -p ./certs && cd /certs && es-gencert-cli create-ca && es-gencert-cli create-node -out ./node1 -ip-addresses 127.0.0.1,172.30.240.11 -dns-names localhost && es-gencert-cli create-node -out ./node2 -ip-addresses 127.0.0.1,172.30.240.12 -dns-names localhost && es-gencert-cli create-node -out ./node3 -ip-addresses 127.0.0.1,172.30.240.13 -dns-names localhost && find . -type f -print0 | xargs -0 chmod 666"
    container_name: setup
    volumes:
      - ./certs:/certs

  # Node 1 for Event Store Cluster
  node1.eventstore: &template
    image: eventstore/eventstore:24.2.0-jammy
    container_name: node1.eventstore
    env_file:
      - vars.env
    environment:
      - EVENTSTORE_INT_IP=172.30.240.11
      - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2111
      - EVENTSTORE_GOSSIP_SEED=172.30.240.12:2113,172.30.240.13:2113
      - EVENTSTORE_TRUSTED_ROOT_CERTIFICATES_PATH=/certs/ca
      - EVENTSTORE_CERTIFICATE_FILE=/certs/node1/node.crt
      - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/certs/node1/node.key
    healthcheck:
      test: [ "CMD-SHELL", "curl --fail --insecure https://node1.eventstore:2113/health/live || exit 1" ]
      interval: 5s
      timeout: 5s
      retries: 24
    ports:
      - 2111:2113
    volumes:
      - ./certs:/certs
      - node1-data:/var/lib/eventstore # Data volume for node1
      - node1-logs:/var/log/eventstore # Logs volume for node1
    depends_on:
      - setup
    restart: always
    networks:
      clusternetwork:
        ipv4_address: 172.30.240.11

  # Node 2 for Event Store Cluster
  node2.eventstore:
    <<: *template
    container_name: node2.eventstore
    environment:
      - EVENTSTORE_INT_IP=172.30.240.12
      - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2112
      - EVENTSTORE_GOSSIP_SEED=172.30.240.11:2113,172.30.240.13:2113
      - EVENTSTORE_TRUSTED_ROOT_CERTIFICATES_PATH=/certs/ca
      - EVENTSTORE_CERTIFICATE_FILE=/certs/node2/node.crt
      - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/certs/node2/node.key
    healthcheck:
      test: [ "CMD-SHELL", "curl --fail --insecure https://node2.eventstore:2113/health/live || exit 1" ]
      interval: 5s
      timeout: 5s
      retries: 24
    ports:
      - 2112:2113
    volumes:
      - ./certs:/certs
      - node2-data:/var/lib/eventstore # Data volume for node2
      - node2-logs:/var/log/eventstore # Logs volume for node2
    networks:
      clusternetwork:
        ipv4_address: 172.30.240.12

  # Node 3 for Event Store Cluster
  node3.eventstore:
    <<: *template
    container_name: node3.eventstore
    environment:
      - EVENTSTORE_INT_IP=172.30.240.13
      - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2113
      - EVENTSTORE_GOSSIP_SEED=172.30.240.11:2113,172.30.240.12:2113
      - EVENTSTORE_TRUSTED_ROOT_CERTIFICATES_PATH=/certs/ca
      - EVENTSTORE_CERTIFICATE_FILE=/certs/node3/node.crt
      - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/certs/node3/node.key
    healthcheck:
      test: [ "CMD-SHELL", "curl --fail --insecure https://node3.eventstore:2113/health/live || exit 1" ]
      interval: 5s
      timeout: 5s
      retries: 24
    ports:
      - 2113:2113
    volumes:
      - ./certs:/certs
      - node3-data:/var/lib/eventstore # Data volume for node3
      - node3-logs:/var/log/eventstore # Logs volume for node3
    networks:
      clusternetwork:
        ipv4_address: 172.30.240.13

  # NestJS Application
  nestjs-app:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - node1.eventstore
      - node2.eventstore
      - node3.eventstore
    environment:
      - EVENTSTORE_DB_URL=esdb://admin:[email protected]:2111,node2.eventstore:2112,node3.eventstore:2113?tls=true&tlsVerifyCert=false

  # Client Application
  client:
    build:
      context: ./client
    ports:
      - '5173:5173'
    environment:
      - VITE_API_URL=http://localhost:5173 # Adjust this based on your API URL
    networks:
      clusternetwork:
        ipv4_address: 172.30.240.15

networks:
  clusternetwork:
    name: eventstoredb.local
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.240.0/24

volumes:
  eventstore-volume-data:
  eventstore-volume-logs:
  node1-data: # Volume for node1 data
  node1-logs: # Volume for node1 logs
  node2-data: # Volume for node2 data
  node2-logs: # Volume for node2 logs
  node3-data: # Volume for node3 data
  node3-logs:

Now I can hit the endpoints via https from post man once the container is started, i can login, i can create users in the UI (Great!) using the default password.

A get request to a node works great outside the container:
https://admin:[email protected]:2112/streams/$all

Now my problem is the connection from my API to the cluster. Below is the connection string im using and believe may be the problem:

EVENTSTORE_DB_URL=esdb://admin:[email protected]:2111,node2.eventstore:2112,node3.eventstore:2113?tls=true&tlsVerifyCert=false

When I call event store from the API the following error is returned:

| Error: Failed to discover after 10 attempts.
nestjs-app-1      |     at discoverEndpoint (/app/node_modules/@eventstore/db-client/dist/Client/discovery.js:45:11)
nestjs-app-1      |     at runNextTicks (node:internal/process/task_queues:60:5)
nestjs-app-1      |     at process.processTimers (node:internal/timers:516:9)                                                                     
nestjs-app-1      |     at async Client.resolveUri (/app/node_modules/@eventstore/db-client/dist/Client/index.js:270:43)
nestjs-app-1      |     at async Client.createChannel (/app/node_modules/@eventstore/db-client/dist/Client/index.js:244:25)                       
nestjs-app-1      |     at async Client.createGRPCClient (/app/node_modules/@eventstore/db-client/dist/Client/index.js:200:37)
nestjs-app-1      |     at async /app/node_modules/@eventstore/db-client/dist/Client/index.js:145:28                                              
nestjs-app-1      |     at async ReadStream.initialize (/app/node_modules/@eventstore/db-client/dist/streams/utils/ReadStream.js:25:18)

UPDATE

I am able to curl the endpoints from my api container after I put them on the same network as event store but the connection still fails when trying to initialize the event store client. Still feel like i have something wrong with my connection string:

  - EVENTSTORE_DB_URL=esdb://admin:[email protected]:2113,node2.eventstore:2113,node3.eventstore:2113?tls=true&tlsVerifyCert=false
  • Connection #0 to host node1.eventstore left intact

curl -vvv --insecure -u admin:changeit https://node1.eventstore:2113/streams/%24all

  • Trying 172.30.240.11:2113…
  • Connected to node1.eventstore (172.30.240.11) port 2113 (#0)
  • ALPN: offers h2,http/1.1
  • TLSv1.3 (OUT), TLS handshake, Client hello (1):
  • TLSv1.3 (IN), TLS handshake, Server hello (2):
  • TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
  • TLSv1.3 (IN), TLS handshake, Request CERT (13):
  • TLSv1.3 (IN), TLS handshake, Certificate (11):
  • TLSv1.3 (IN), TLS handshake, CERT verify (15):
  • TLSv1.3 (IN), TLS handshake, Finished (20):
  • TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
  • TLSv1.3 (OUT), TLS handshake, Certificate (11):
  • TLSv1.3 (OUT), TLS handshake, Finished (20):
  • SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
  • ALPN: server accepted h2
  • Server certificate:
  • subject: CN=eventstoredb-node
  • start date: Aug 27 12:42:06 2024 GMT
  • expire date: Aug 27 12:42:06 2025 GMT
  • issuer: C=UK; O=Event Store Ltd; CN=EventStoreDB CA 12abb2ada28a7e205a05fc9acb86e6d7
  • SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
  • using HTTP/2
  • Server auth using Basic with user ‘admin’
  • h2h3 [:method: GET]
  • h2h3 [:path: /streams/%24all]
  • h2h3 [:scheme: https]
  • h2h3 [:authority: node1.eventstore:2113]
  • h2h3 [authorization: Basic YWRtaW46Y2hhbmdlaXQ=]
  • h2h3 [user-agent: curl/7.88.1]
  • h2h3 [accept: /]
  • Using Stream ID: 1 (easy handle 0x5632f4f30ce0)

GET /streams/%24all HTTP/2
Host: node1.eventstore:2113
authorization: Basic YWRtaW46Y2hhbmdlaXQ=
user-agent: curl/7.88.1
accept: /

  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • old SSL session ID is stale, removing
    < HTTP/2 200
    < content-type: application/vnd.eventstore.streamdesc+json; charset=utf-8
    < date: Tue, 27 Aug 2024 20:33:57 GMT
    < server: Kestrel
    < access-control-allow-headers: Content-Type, X-Requested-With, X-Forwarded-Host, X-Forwarded-Prefix, X-PINGOTHER, Authorization, ES-LongPoll, ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequireMaster, ES-RequireLeader, ES-HardDelete, ES-ResolveLinkTos
    < access-control-allow-methods: POST, DELETE, GET, GET, OPTIONS
    < access-control-allow-origin: *
    < access-control-expose-headers: Location, ES-Position, ES-CurrentVersion
    < cache-control: max-age=0, no-cache, must-revalidate
    < etag: “17262;-1813972384”
    < vary: Accept
    < content-length: 12902
    <
    {
    “title”: “All events”,
    “id”: “https://127.0.0.1:2111/streams/%24all”,
    “updated”: “2024-08-27T14:18:09.1943868Z”,

Apparently, it’s the docs for the v5 server version.

The easiest way to run a secure cluster in Docker locally is using Docker Compose as described int he documentation Installation | EventStoreDB Documentation