docker pull library/*quay-image
docker run -d -p 6060:6060 --name clair *quay-image
docker compose up -d
---
# This is just to hold a bunch of yaml anchors and try to consolidate parts of
# the config.
x-anchors:
go: &go-image quay.io/projectquay/golang:1.25
grafana: &grafana-image docker.io/grafana/grafana:10.3.1
jaeger: &jaeger-image docker.io/jaegertracing/all-in-one:1
pgadmin: &pgadmin-image docker.io/dpage/pgadmin4:5.7
postgres: &postgres-image docker.io/library/postgres:15
postgres-exporter: &postgres-exporter-image docker.io/prometheuscommunity/postgres-exporter:latest
prom: &prom-image docker.io/prom/prometheus:latest
pyroscope: &pyroscope-image docker.io/grafana/pyroscope:latest
quay: &quay-image quay.io/projectquay/quay:latest
rabbitmq: &rabbitmq-image docker.io/library/rabbitmq:3
redis: &redis-image docker.io/library/redis:6
skopeo: &skopeo-image quay.io/skopeo/stable:latest
traefik: &traefik-image docker.io/library/traefik:v3.0
clair-service: &clair-service
image: *go-image
depends_on:
clair-database:
condition: service_healthy
volumes:
- "./local-dev/clair:/etc/clair:ro"
- ".:/src"
# Can't specify the config via environment because maps are not recursively
# merged.
command:
- go
- run
- .
- -conf
- /etc/clair/${CLAIR_CONFIG:-config.yaml}
restart: unless-stopped
working_dir: /src/cmd/clair
services:
indexer:
<<: *clair-service
container_name: clair-indexer
environment:
CLAIR_MODE: "indexer"
matcher:
<<: *clair-service
container_name: clair-matcher
environment:
CLAIR_MODE: "matcher"
clair-database:
container_name: clair-database
image: *postgres-image
environment:
POSTGRES_HOST_AUTH_METHOD: trust
volumes:
- type: bind
source: ./local-dev/clair/init.sql
target: /docker-entrypoint-initdb.d/init.sql
healthcheck:
test:
- CMD-SHELL
- "pg_isready -U postgres"
interval: 5s
timeout: 4s
retries: 12
start_period: 10s
traefik:
container_name: clair-traefik
image: *traefik-image
depends_on:
- matcher
- indexer
ports:
- '6060:6060'
- '8080:8080'
- '8443'
- '5432'
volumes:
- './local-dev/traefik/:/etc/traefik/:ro'
# Debugging services -- use profile 'debug'
pgadmin:
container_name: clair-pgadmin
profiles:
- debug
image: *pgadmin-image
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: clair
PGADMIN_SERVER_JSON_FILE: /pgadmin4/config/servers.json
SCRIPT_NAME: /pgadmin
volumes:
- "./local-dev/pgadmin:/pgadmin4/config"
depends_on:
- clair-database
jaeger:
container_name: clair-jaeger
profiles:
- debug
image: *jaeger-image
environment:
QUERY_BASE_PATH: '/jaeger'
COLLECTOR_OTLP_ENABLED: 'true'
prometheus:
container_name: clair-prometheus
profiles:
- debug
image: *prom-image
volumes:
- "./local-dev/prometheus:/etc/prometheus/"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.external-url=http://localhost:8080/prom/'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
pyroscope:
container_name: clair-pyroscope
profiles:
- debug
image: *pyroscope-image
volumes:
- ./local-dev/pyroscope:/etc/pyroscope/
command:
- server
environment:
PYROSCOPE_LOG_LEVEL: info
PYROSCOPE_WAIT_AFTER_STOP: 'true'
grafana:
container_name: clair-grafana
profiles:
- debug
image: *grafana-image
user: "472"
environment:
GF_SERVER_ROOT_URL: /grafana
GF_SERVER_SERVE_FROM_SUB_PATH: 'true'
GF_INSTALL_PLUGINS: 'pyroscope-datasource,pyroscope-panel'
volumes:
- ./local-dev/grafana/provisioning/:/etc/grafana/provisioning/
depends_on:
- prometheus
- pyroscope
postgres-exporter:
container_name: clair-postgres-exporter
profiles:
- debug
image: *postgres-exporter-image
environment:
DATA_SOURCE_NAME: "postgresql://postgres@clair-database:5432/postgres?sslmode=disable"
depends_on:
clair-database:
condition: service_healthy
# Notifier services -- use profile 'notifier'
notifier: ¬ifier
<<: *clair-service
container_name: clair-notifier
profiles:
- notifier
environment:
CLAIR_MODE: "notifier"
NOTIFIER_TEST_MODE: "true"
webhook-target:
<<: *clair-service
container_name: webhook-target
profiles:
- notifier
working_dir: /src
depends_on: {}
command:
- go
- run
- ./notifier/webhook/cmd/webhookd
- -D
- -key
- c2VjcmV0
rabbitmq:
# This provides STOMP and AMQP on the usual ports.
# The web UI is available on /rabbitmq
container_name: clair-rabbitmq
profiles:
- notifier
image: *rabbitmq-image
command:
- sh
- -c
- |
set -e
rabbitmq-plugins enable rabbitmq_stomp rabbitmq_management >/dev/null
exec rabbitmq-server
# Quay -- starts a Quay stack for integration testing.
# Use profile 'quay'
quay:
container_name: clair-quay
profiles:
- quay
image: *quay-image
volumes:
- "./local-dev/quay:/quay-registry/conf/stack"
environment:
DEBUGLOG: "true"
IGNORE_VALIDATION: "true"
depends_on:
- redis
- clair-database
redis:
container_name: quay-redis
profiles:
- quay
image: *redis-image
quay-notifier:
<<: *notifier
profiles:
- quay
environment:
CLAIR_MODE: "notifier"
skopeo:
container_name: quay-skopeo
profiles:
- quay
image: *skopeo-image
entrypoint:
- sleep
- inf