version: '2.1'

services:
  server:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: server
    # Explicitly add entries to /etc/hosts for the hosts which are connected
    # to more than two networks. These explicit entries should be added at the
    # beginning of the /etc/hosts file enforcing that the connections by hostname
    # are established with the IP addresses belonging to the storknet network.
    # Before this change, agents sometimes listened on IP addresses dedicated for
    # DHCP communication instead.
    extra_hosts:
      - "agent-kea:172.24.0.100"
      - "agent-kea6:172.24.0.106"
      - "agent-kea-premium-one:172.24.0.103"
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/server:latest"
    networks:
      - storknet
    expose:
      - "8080"
    ports:
      - "8088:8080"
    environment:
      STORK_DATABASE_HOST: postgres
      STORK_DATABASE_PORT: 5432
      STORK_DATABASE_USER_NAME: stork
      STORK_DATABASE_PASSWORD: stork
      STORK_DATABASE_NAME: stork
      STORK_SERVER_ENABLE_METRICS: 1
    volumes:
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/stork-server.conf:/etc/supervisor/conf.d/stork-server.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py
    depends_on:
      - postgres

  webui:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: webui
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/webui:latest"
    networks:
      - storknet
    ports:
      - "8080:80"
    environment:
      API_HOST: server
      API_PORT: 8080
    depends_on:
      - server

  webui-apache:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: webui-apache
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/webui-apache:latest"
    networks:
      - storknet
    ports:
      - "8081:81"
    environment:
      API_HOST: server
      API_PORT: 8080
    depends_on:
      - server

  agent-kea:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    # Explicitly add entries to /etc/hosts for the hosts which are connected
    # to more than two networks. These explicit entries should be added at the
    # beginning of the /etc/hosts file enforcing that the connections by hostname
    # are established with the IP addresses belonging to the storknet network.
    # Before this change, agents sometimes listened on IP addresses dedicated for
    # DHCP communication instead.
    extra_hosts:
      - "agent-kea:172.24.0.100"
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea:latest"
    hostname: agent-kea
    networks:
      # Using priority to ensure predictable assignment of interface names.
      # See the "Using perfdhcp to Generate Traffic" section in the devel docs.
      storknet:
        ipv4_address: 172.24.0.100
        priority: 1000
      subnet-00:
        ipv4_address: 172.100.0.100
        priority: 500
      subnet-01:
        ipv4_address: 172.101.0.100
        priority: 400
      subnet-02:
        ipv4_address: 172.102.0.100
        priority: 300
    expose:
      - "8888" # stork server to agent
      - "9100" # node_exporter for prometheus
      - "9547" # kea_exporter for prometheus
    ports:
      # publish ports for development purposes
      - "8888:8888" # port to agent
      - "9001:9001" # port to supervisor xml-rpc
    environment:
      DB_TYPE: mysql
      DB_HOST: mariadb
      DB_USER: agent_kea
      DB_PASSWORD: agent_kea
      DB_ROOT_USER: root
      DB_ROOT_PASSWORD: root
      DB_NAME: agent_kea
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea
      STORK_AGENT_PORT: "8888"
    volumes:
      - ./docker/config/agent-kea/kea-ctrl-agent.conf:/etc/kea/kea-ctrl-agent.conf
      - ./docker/config/agent-kea/kea-dhcp4.conf:/etc/kea/kea-dhcp4.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp4.conf:/etc/supervisor/conf.d/kea-dhcp4.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py
    depends_on:
      - mariadb

  agent-kea6:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    # Explicitly add entries to /etc/hosts for the hosts which are connected
    # to more than two networks. These explicit entries should be added at the
    # beginning of the /etc/hosts file enforcing that the connections by hostname
    # are established with the IP addresses belonging to the storknet network.
    # Before this change, agents sometimes listened on IP addresses dedicated for
    # DHCP communication instead.
    extra_hosts:
      - "agent-kea6:172.24.0.106"
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea6:latest"
    hostname: agent-kea6
    networks:
      # Using priority to ensure predictable assignment of interface names.
      # See the "Using perfdhcp to Generate Traffic" section in the devel docs.
      storknet:
        ipv4_address: 172.24.0.106
        priority: 1000
      subnet6-00:
        ipv6_address: 3000:db8:1::100
        priority: 500
      subnet6-01:
        ipv6_address: 3001:db8:1::100
        priority: 400
    expose:
      - "8887" # stork server to agent
      - "9547" # kea_exporter for prometheus
    ports:
      # publish ports for development purposes
      - "8887:8887" # port to agent
    environment:
      DB_TYPE: pgsql
      DB_NAME: agent_kea6
      DB_USER: agent_kea6
      DB_PASSWORD: agent_kea6
      DB_HOST: postgres
      DB_ROOT_USER: stork
      DB_ROOT_PASSWORD: stork
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea6
      STORK_AGENT_PORT: "8887"
    volumes:
      - ./docker/config/agent-kea6/kea-ctrl-agent.conf:/etc/kea/kea-ctrl-agent.conf
      - ./docker/config/agent-kea6/kea-dhcp6.conf:/etc/kea/kea-dhcp6.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp6.conf:/etc/supervisor/conf.d/kea-dhcp6.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py
    depends_on:
      - postgres

  agent-kea-ha1:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea-ha1:latest"
    hostname: agent-kea-ha1
    networks:
      storknet:
        ipv4_address: 172.24.0.101
    expose:
      - "8886"
      - "9547" # kea_exporter for prometheus
    ports:
      - "8886:8886" # publish ports for development purposes
    environment:
      DB_TYPE: none
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea-ha1
      STORK_AGENT_PORT: "8886"
    volumes:
      - ./docker/config/agent-kea-ha1/kea-ctrl-agent.conf:/etc/kea/kea-ctrl-agent.conf
      - ./docker/config/agent-kea-ha1/kea-dhcp4.conf:/etc/kea/kea-dhcp4.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp4.conf:/etc/supervisor/conf.d/kea-dhcp4.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py

  agent-kea-ha2:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea-ha2:latest"
    hostname: agent-kea-ha2
    networks:
      storknet:
        ipv4_address: 172.24.0.110
    expose:
      - "8885"
    ports:
      - "8885:8885" # publish ports for development purposes
    environment:
      DB_TYPE: none
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea-ha2
      STORK_AGENT_PORT: "8885"
    volumes:
      - ./docker/config/agent-kea-ha2/kea-ctrl-agent.conf:/etc/kea/kea-ctrl-agent.conf
      - ./docker/config/agent-kea-ha2/kea-dhcp4.conf:/etc/kea/kea-dhcp4.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp4.conf:/etc/supervisor/conf.d/kea-dhcp4.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py

  agent-kea-ha3:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea-ha3:latest"
    hostname: agent-kea-ha3
    networks:
      storknet:
        ipv4_address: 172.24.0.121
    expose:
      - "8890"
      - "9547" # kea_exporter for prometheus
    ports:
      - "8890:8890" # publish ports for development purposes
    environment:
      DB_TYPE: none
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea-ha3
      STORK_AGENT_PORT: "8890"
    volumes:
      - ./docker/config/agent-kea-ha3/kea-ctrl-agent.conf:/etc/kea/kea-ctrl-agent.conf
      - ./docker/config/agent-kea-ha3/kea-dhcp4.conf:/etc/kea/kea-dhcp4.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp4.conf:/etc/supervisor/conf.d/kea-dhcp4.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py

  agent-kea-many-subnets:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-kea-many-subnets:latest"
    hostname: agent-kea-many-subnets
    networks:
      storknet:
        ipv4_address: 172.24.0.102
    expose:
      - "8884"
      - "9547" # kea_exporter for prometheus
    ports:
      - "8884:8884" # publish ports for development purposes
    environment:
      DB_TYPE: none
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-kea-many-subnets
      STORK_AGENT_PORT: "8884"
      STORK_AGENT_PROMETHEUS_KEA_EXPORTER_PER_SUBNET_STATS: "false"
    volumes:
      - ./docker/config/agent-kea-many-subnets:/etc/kea
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/kea-agent.conf:/etc/supervisor/conf.d/kea-agent.conf
      - ./docker/config/supervisor/kea-dhcp4.conf:/etc/supervisor/conf.d/kea-dhcp4.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py
    depends_on:
      - kea-config-generator

  agent-bind9:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: bind
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-bind9:latest"
    hostname: agent-bind9
    ports:
      - "8883:8883"
    networks:
      storknet:
        ipv4_address: 172.24.0.53
    environment:
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-bind9
      STORK_AGENT_PORT: "8883"
    expose:
      - "8883"
      - "9100" # node_exporter for prometheus
      - "9119" # bind_exporter for prometheus
    volumes:
      - ./docker/config/agent-bind9/db.test:/etc/bind/db.test
      - ./docker/config/agent-bind9/named.conf:/etc/bind/named.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/named.conf:/etc/supervisor/conf.d/named.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus-alpine.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py

  # ToDo: This service should be created using --scale agent-bind9=2 option
  # but it isn't supported by the STORK_AGENT_HOST envvar. Both services use
  # the same value and Stork ignores one of them.
  agent-bind9-2:
    restart: always
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: bind
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/agent-bind9:latest"
    hostname: agent-bind9-2
    networks:
      storknet:
        ipv4_address: 172.24.0.54
    environment:
      STORK_AGENT_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
      STORK_AGENT_HOST: agent-bind9-2
      STORK_AGENT_PORT: "8882"
    expose:
      - "8882"
      - "9100" # node_exporter for prometheus
      - "9119" # bind_exporter for prometheus
    ports:
      - "8882:8882"
    volumes:
      - ./docker/config/agent-bind9/db.test:/etc/bind/db.test
      - ./docker/config/agent-bind9/named.conf:/etc/bind/named.conf
      - ./docker/config/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf
      - ./docker/config/supervisor/named.conf:/etc/supervisor/conf.d/named.conf
      - ./docker/config/supervisor/stork-agent.conf:/etc/supervisor/conf.d/stork-agent.conf
      - ./docker/config/supervisor/prometheus-alpine.conf:/etc/supervisor/conf.d/prometheus.conf
      - ./docker/config/supervisor/supervisor_monitor.conf:/etc/supervisor/conf.d/supervisor_monitor.conf
      - ./docker/tools/supervisor_monitor.py:/usr/lib/supervisor_monitor.py

  kea-config-generator:
    build:
      context: .
      dockerfile: docker/images/stork.Dockerfile
      target: kea-config-generator
    volumes:
      - ./docker/config/agent-kea-many-subnets:/etc/kea

  simulator:
    restart: always
    build:
      context: .
      dockerfile: docker/images/simulator.Dockerfile
    # Explicitly add entries to /etc/hosts for the hosts which are connected
    # to more than two networks. These explicit entries should be added at the
    # beginning of the /etc/hosts file enforcing that the connections by hostname
    # are established with the IP addresses belonging to the storknet network.
    # Before this change, agents sometimes listened on IP addresses dedicated for
    # DHCP communication instead.
    extra_hosts:
      - "agent-kea:172.24.0.100"
      - "agent-kea6:172.24.0.106"
      - "agent-kea-premium-one:172.24.0.103"
    image: "${REGISTRY-registry.gitlab.isc.org/isc-projects/stork}/dhcp-traffic:latest"
    hostname: simulator
    networks:
      # Using priority to ensure predictable assignment of interface names.
      # See the "Using perfdhcp to Generate Traffic" section in the devel docs.
      storknet:
        ipv4_address: 172.24.0.200
        priority: 1000
      subnet-00:
        ipv4_address: 172.100.0.200
        priority: 500
      subnet-01:
        ipv4_address: 172.101.0.200
        priority: 400
      subnet-02:
        ipv4_address: 172.102.0.200
        priority: 300
      subnet-03:
        ipv4_address: 172.103.0.200
        priority: 200
      subnet6-00:
        ipv6_address: 3000:db8:1::200
        priority: 500
      subnet6-01:
        ipv6_address: 3001:db8:1::200
        priority: 400
    ports:
      # We used to use port 5000 externally but that doesn't work
      # on macOS that has its own service on that port.
      - "5010:5000"
    environment:
      STORK_SERVER_URL: ${STORK_SERVER_URL-http://server:8080}
    depends_on:
      - server

  prometheus:
    restart: always
    image: prom/prometheus:v2.54.1
    networks:
      - storknet
    ports:
      - "9090:9090"
    volumes:
      - ./docker/config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    restart: always
    image: grafana/grafana:11.2.2
    networks:
      - storknet
    ports:
      - "3000:3000"
    volumes:
      - ./docker/config/grafana/grafana.ini:/etc/grafana/grafana.ini
      - ./docker/config/grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml
      - ./docker/config/grafana/dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml
      - ./grafana/kea-dhcp4.json:/var/lib/grafana/dashboards/kea-dhcp4.json
      - ./grafana/kea-dhcp6.json:/var/lib/grafana/dashboards/kea-dhcp6.json
      - ./grafana/bind9-resolver.json:/var/lib/grafana/dashboards/bind9-resolver.json
    depends_on:
      - prometheus

  openldap:
    image: bitnami/openldap:2
    environment:
      LDAP_ADMIN_USERNAME: admin
      LDAP_ADMIN_PASSWORD: adminpassword
    ports:
      - '1389:1389'
      - '1636:1636'
    profiles:
      - ldap
    networks:
      - storknet
    volumes:
      - ./docker/config/openldap/tree.ldif:/ldifs/tree.ldif

  postgres:
    restart: always
    image: postgres:${POSTGRES_VERSION:-16}
    networks:
      storknet:
        ipv4_address: 172.24.0.234
    environment:
      POSTGRES_USER: stork
      POSTGRES_PASSWORD: stork
      POSTGRES_DB: stork
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U stork" ]
      interval: 5s
      timeout: 5s
      retries: 5
    ports:
      - "5678:5432"

  mariadb:
    restart: always
    image: mariadb:10.7
    networks:
      - storknet
    environment:
      MARIADB_ROOT_PASSWORD: root
    ports:
      - "4417:3306"

networks:
  storknet:
    enable_ipv6: true
    ipam:
      config:
        - subnet: 172.24.0.0/24
        - subnet: 3009:db8:1::/64
  subnet-00:
    ipam:
      config:
        - subnet: 172.100.0.0/24
  subnet-01:
    ipam:
      config:
        - subnet: 172.101.0.0/24
  subnet-02:
    ipam:
      config:
        - subnet: 172.102.0.0/24
  subnet-03:
    ipam:
      config:
        - subnet: 172.103.0.0/24
  subnet6-00:
    enable_ipv6: true
    ipam:
      config:
        - subnet: 3000:db8:1::/64
  subnet6-01:
    enable_ipv6: true
    ipam:
      config:
        - subnet: 3001:db8:1::/64
