Skip to content

Templates

Sanitized templates for offline delivery bundles and base service configurations. Use these as starting points and replace placeholders (ALL_CAPS) with environment-specific values before shipping artifacts into Environment B.

Nexus docker-compose.yml (VM1)

Baseline Compose stack for the Nexus host. Exposes repository ports referenced by the CI control plane and runner.

version: "3.9"
services:
  nexus:
    image: sonatype/nexus3:3.63.0
    container_name: nexus
    restart: unless-stopped
    ports:
      - "8081:8081"  # Nexus UI
      - "8082:8082"  # Docker hosted
      - "8083:8083"  # Docker proxy/second registry
    volumes:
      - nexus-data:/nexus-data
    environment:
      - INSTALL4J_ADD_VM_PARAMS=-Xms2703m -Xmx2703m -XX:MaxDirectMemorySize=2703m
volumes:
  nexus-data:
    driver: local

CI control plane docker-compose.yml (VM2)

Compose stack for Gerrit, ZooKeeper, Zuul components, PostgreSQL, and the nodepool launcher. Mount your real configuration files under etc_zuul/ and etc_nodepool/.

version: "3.9"
services:
  gerrit-db:
    image: postgres:13
    environment:
      POSTGRES_DB: reviewdb
      POSTGRES_USER: gerrit
      POSTGRES_PASSWORD: GERRIT_DB_PASSWORD
    volumes:
      - gerrit-db:/var/lib/postgresql/data

  gerrit:
    image: opendevorg/gerrit:3.9.1
    depends_on:
      - gerrit-db
    environment:
      DATABASE_TYPE: postgres
      DATABASE_HOSTNAME: gerrit-db
      DATABASE_DATABASE: reviewdb
      DATABASE_USERNAME: gerrit
      DATABASE_PASSWORD: GERRIT_DB_PASSWORD
      AUTH_TYPE: OAUTH
      WEBURL: http://gerrit:8080/
    ports:
      - "8080:8080"
      - "29418:29418"
    volumes:
      - gerrit-site:/var/gerrit

  zk:
    image: quay.io/zuul-ci/zookeeper:8.4.0
    restart: unless-stopped
    volumes:
      - zk-data:/bitnami/zookeeper
      - ./zk/zoo.cfg:/opt/bitnami/zookeeper/conf/zoo.cfg:ro
      - ./certs:/var/certs:ro

  pgsql:
    image: postgres:13
    environment:
      POSTGRES_DB: zuul
      POSTGRES_USER: zuul
      POSTGRES_PASSWORD: ZUUL_DB_PASSWORD
    volumes:
      - zuul-db:/var/lib/postgresql/data

  zuul-scheduler:
    image: quay.io/zuul-ci/zuul-scheduler:8.4.0
    depends_on:
      - zk
      - pgsql
    restart: unless-stopped
    volumes:
      - ./etc_zuul:/etc/zuul:ro
      - ./certs:/var/certs:ro
      - ./playbooks:/var/playbooks:ro
    command: ["/usr/local/bin/zuul-scheduler", "-d"]

  zuul-web:
    image: quay.io/zuul-ci/zuul-web:8.4.0
    depends_on:
      - zk
      - zuul-scheduler
    restart: unless-stopped
    volumes:
      - ./etc_zuul:/etc/zuul:ro
      - ./certs:/var/certs:ro
    ports:
      - "9000:9000"
    command: ["/usr/local/bin/zuul-web", "-d"]

  zuul-merger:
    image: quay.io/zuul-ci/zuul-merger:8.4.0
    depends_on:
      - zk
    restart: unless-stopped
    volumes:
      - ./etc_zuul:/etc/zuul:ro
      - ./certs:/var/certs:ro
      - /var/lib/zuul/git:/var/lib/zuul/git
    command: ["/usr/local/bin/zuul-merger", "-d"]

  zuul-executor:
    image: quay.io/zuul-ci/zuul-executor:8.4.0
    depends_on:
      - zk
    restart: unless-stopped
    privileged: true
    volumes:
      - ./etc_zuul:/etc/zuul:ro
      - ./certs:/var/certs:ro
      - /var/lib/zuul/keys:/var/lib/zuul/keys
      - /var/lib/zuul/builds:/var/lib/zuul/builds
    command: ["/usr/local/bin/zuul-executor", "-d"]

  nodepool-launcher:
    image: quay.io/zuul-ci/nodepool-launcher:8.4.0
    depends_on:
      - zk
    restart: unless-stopped
    volumes:
      - ./etc_nodepool:/etc/nodepool:ro
      - ./certs:/var/certs:ro
      - /var/lib/nodepool:/var/lib/nodepool
    command: ["/usr/local/bin/nodepool-launcher", "-d"]

volumes:
  gerrit-db:
  gerrit-site:
  zk-data:
  zuul-db:

Static node inventory (etc_nodepool/nodepool.yaml)

Current static node definition for the Jammy runner host.

zookeeper-servers:
  - host: zk
    port: 2281

zookeeper-tls:
  ca:   /var/certs/certs/cacert.pem
  cert: /var/certs/certs/client.pem
  key:  /var/certs/keys/clientkey.pem

labels:
  - name: ubuntu-jammy

providers:
  - name: static
    driver: static
    pools:
      - name: ubuntu-jammy
        nodes:
          - name: 94.101.184.58
            labels: [ubuntu-jammy]
            tenants: ['kolla-local']
            timeout: 60
            max-parallel-jobs: 1
            username: ubuntu
            # Nodepool will SSH as this user using the key mounted above
            host-key-checking: false
            connection-port: 22
            python-path: /usr/bin/python3

Zuul scheduler logging (etc_zuul/scheduler-logging.yaml)

version: 1
handlers: {console: {class: logging.StreamHandler, stream: ext://sys.stdout, level: INFO}}
root: {handlers: [console], level: INFO}

Zuul tenants (etc_zuul/tenants.yaml)

- tenant:
    name: local
    source:
      gerrit:
        config-projects: [openstack/project-config]
        untrusted-projects: [openstack/kolla]

Zuul configuration (etc_zuul/zuul.conf)

[zookeeper]
hosts=zk:2281
tls_ca=/var/certs/certs/cacert.pem
tls_cert=/var/certs/certs/client.pem
tls_key=/var/certs/keys/clientkey.pem

[keystore]
password=x

[web]
listen_address=0.0.0.0
port=9000
root=http://37.32.27.200:9000

[scheduler]
tenant_config=/etc/zuul/tenants.yaml
log_config=/etc/zuul/scheduler-logging.yaml

[connection opengerrit]
driver=gerrit
server=git.opendev.neor.cloud
port=29418
user=admin
sshkey=/var/lib/zuul/.ssh/zuul_gerrit
baseurl=http://git.opendev.neor.cloud:8080/
verify_ssl=false

[database]
dburi = postgresql://zuul:x@pgsql/zuul

[merger]
git_timeout=1800
git_user_name=admin
git_user_email=admin@example.com

Zuul wait scripts (playbooks/)

wait-to-start-certs.sh

#!/bin/bash

# Zuul needs ssl certs to be present to talk to zookeeper before it
# starts.

wait_for_certs() {
    echo `date -Iseconds` "Wait for certs to be present"
    for i in $(seq 1 300); do
        # Introduced for 3.7.0: zookeeper shall wait for certificates to be available
        # examples_zk_1.examples_default.pem is the last file created by ./tools/zk-ca.sh
        [ -f /var/certs/keystores/examples_zk_1.examples_default.pem ] && return
        sleep 1
    done;

    echo `date -Iseconds` "Timeout waiting for certs"
    exit 1
}

wait_for_certs

wait-to-start.sh

#!/bin/bash

# Zuul needs to be able to connect to the remote systems in order to
# start.

wait_for_mysql() {
    echo `date -Iseconds` "Wait for mysql to start"
    for i in $(seq 1 120); do
        cat < /dev/null > /dev/tcp/mysql/3306 && return
        sleep 1
    done

    echo `date -Iseconds` "Timeout waiting for mysql"
    exit 1
}

wait_for_gerrit() {
    echo `date -Iseconds` "Wait for zuul user to be created"
    for i in $(seq 1 120); do
        [ $(curl -s -o /dev/null -w "%{http_code}" http://admin:secret@gerrit:8080/a/accounts/zuul/sshkeys) = "200" ] && return
        sleep 1
    done

    echo `date -Iseconds` "Timeout waiting for gerrit"
    exit 1
}

wait_for_mysql
wait_for_gerrit

Usage guidance

  • Keep templates under version control alongside the LLD/implementation docs.
  • Replace placeholder secrets and hostnames with environment-specific values during bundle preparation.
  • Align compose image tags with the offline images you ship for Environment B.
  • Use the static node and Zuul configuration templates as-is unless your topology changes.