Skip to content

Deploying Cryostat in Docker or Podman Compose

Andrew Azores edited this page Dec 5, 2025 · 4 revisions

Check the README Run section for complete details on how to customize and generate your own compose file for different use cases (ex. external S3 provider, customized credentials, etc.). Below is a sample compose file which you can download, modify as needed, and use with docker compose up to get a running Cryostat instance on your workstation. This of course requires docker and docker-compose to be installed and working on your machine. You will need to either use the smoketest.bash script locally to initialize the Cryostat configuration volumes, or else download the preset .tar.gz archives linked below docker volume import each one.

Once you have downloaded these volume initialization files, you can create your local volumes:

for i in *.tar.gz ; do \
    f=$(echo $i | cut -d. -f1); \
    docker volume create $f; \
    docker volume import $f $f.tar.gz; \
done

Then, copy this YAML content into a file named cryostat-compose.yml and run docker compose up -f cryostat-compose-yml. Once this comes up you can open https://localhost:8443 in your browser to visit the Cryostat UI. The default credentials are user:pass. You may need to make some minor adjustments if you take this YAML file directly rather than generating it by running smoketest.bash for yourself - for example, this YAML hardcodes the Podman socket path at /run/user/1000/podman/podman.sock. If your user uid is not 1000, you do not have rootless Podman configured, or you do not use Podman at all, then this will need to be modified to suit your scenario.

name: compose
services:
  auth:
    command:
      - --alpha-config=/tmp/auth_proxy_alpha_config.yml
    depends_on:
      cryostat:
        condition: service_healthy
        required: true
    deploy:
      resources:
        limits:
          cpus: 0.5
          memory: "134217728"
    environment:
      CRYOSTAT_PROXY_PORT: "8443"
      CRYOSTAT_PROXY_PROTOCOL: https
      OAUTH2_PROXY_COOKIE_SECRET: __24_BYTE_COOKIE_SECRET_
      OAUTH2_PROXY_HTPASSWD_FILE: /tmp/auth_proxy_htpasswd
      OAUTH2_PROXY_HTPASSWD_USER_GROUP: write
      OAUTH2_PROXY_REDIRECT_URL: https://localhost:8443/oauth2/callback
      OAUTH2_PROXY_SKIP_AUTH_ROUTES: ^/health(/liveness)?$$
    hostname: auth
    healthcheck:
      test:
        - CMD-SHELL
        - wget --no-check-certificate -q --spider https://localhost:8443/ping || exit 1
      timeout: 5s
      interval: 10s
      retries: 3
      start_period: 10s
    image: quay.io/oauth2-proxy/oauth2-proxy:latest-alpine
    networks:
      default: null
    ports:
      - mode: ingress
        target: 8443
        published: "8443"
        protocol: tcp
    restart: unless-stopped
    volumes:
      - type: volume
        source: auth_proxy_cfg
        target: /tmp
        volume: {}
      - type: volume
        source: auth_proxy_certs
        target: /certs
        volume: {}
  cryostat:
    depends_on:
      db:
        condition: service_healthy
        required: true
      s3:
        condition: service_healthy
        required: true
    deploy:
      resources:
        limits:
          cpus: 2
          memory: "1073741824"
    environment:
      AWS_ACCESS_KEY_ID: access_key
      AWS_SECRET_ACCESS_KEY: secret_key
      CRYOSTAT_AGENT_TLS_REQUIRED: "false"
      CRYOSTAT_DISCOVERY_DOCKER_ENABLED: "true"
      CRYOSTAT_DISCOVERY_JDP_ENABLED: "true"
      CRYOSTAT_DISCOVERY_PODMAN_ENABLED: "true"
      CRYOSTAT_HTTP_PROXY_HOST: auth
      CRYOSTAT_HTTP_PROXY_PORT: "8443"
      CRYOSTAT_HTTP_PROXY_TLS_ENABLED: "true"
      GRAFANA_DASHBOARD_EXT_URL: /grafana/
      GRAFANA_DASHBOARD_URL: http://grafana:3000
      GRAFANA_DATASOURCE_URL: http://jfr-datasource:8080
      JAVA_OPTS_APPEND: -XX:StartFlightRecording=filename=/tmp/,name=onstart,settings=default,disk=true,maxage=5m -XX:StartFlightRecording=filename=/tmp/,name=startup,settings=profile,disk=true,duration=30s -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false
      QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://db:5432/cryostat
      QUARKUS_DATASOURCE_PASSWORD: cryostat
      QUARKUS_DATASOURCE_USERNAME: cryostat
      QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION: none
      QUARKUS_HIBERNATE_ORM_LOG_SQL: "true"
      QUARKUS_HIBERNATE_ORM_SQL_LOAD_SCRIPT: no-file
      QUARKUS_HTTP_ACCESS_LOG_ENABLED: "true"
      QUARKUS_HTTP_ACCESS_LOG_PATTERN: long
      QUARKUS_HTTP_HOST: cryostat
      QUARKUS_HTTP_PORT: "8181"
      QUARKUS_HTTP_PROXY_ALLOW_X_FORWARDED: "true"
      QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_HOST: "true"
      QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_PREFIX: "true"
      QUARKUS_HTTP_PROXY_PROXY_ADDRESS_FORWARDING: "true"
      QUARKUS_LOG_LEVEL: INFO
      QUARKUS_REST_CLIENT_LOGGING_SCOPE: request-response
      QUARKUS_REST_CLIENT_REPORTS_URL: http://reports:10001
      QUARKUS_S3_AWS_REGION: us-east-1
      QUARKUS_S3_ENDPOINT_OVERRIDE: http://s3:8333
      QUARKUS_S3_PATH_STYLE_ACCESS: "true"
      STORAGE_BUCKETS_METADATA_NAME: cryostatmeta
      STORAGE_EXT_URL: /storage/
      STORAGE_METADATA_STORAGE_MODE: tagging
    expose:
      - "8181"
    hostname: cryostat
    healthcheck:
      test:
        - CMD-SHELL
        - curl --fail http://cryostat:8181/health/liveness || exit 1
      timeout: 5s
      interval: 10s
      retries: 3
      start_period: 30s
    image: quay.io/cryostat/cryostat:latest
    networks:
      default: null
    restart: unless-stopped
    security_opt:
      - label:disable
    user: "1000"
    volumes:
      - type: bind
        source: /run/user/1000/podman/podman.sock
        target: /run/user/1000/podman/podman.sock
        bind:
          selinux: Z
          create_host_path: true
      - type: volume
        source: jmxtls_cfg
        target: /truststore
        volume: {}
      - type: volume
        source: templates
        target: /opt/cryostat.d/templates.d
        volume: {}
      - type: volume
        source: probes
        target: /opt/cryostat.d/probes.d
        volume: {}
      - type: volume
        source: credentials
        target: /opt/cryostat.d/credentials.d
        volume: {}
  db:
    environment:
      PG_ENCRYPT_KEY: REPLACEME
      POSTGRESQL_DATABASE: cryostat
      POSTGRESQL_PASSWORD: cryostat
      POSTGRESQL_USER: cryostat
    expose:
      - "5432"
    hostname: db
    healthcheck:
      test:
        - CMD-SHELL
        - pg_isready -U cryostat -d cryostat || exit 1
      timeout: 5s
      interval: 10s
      retries: 3
      start_period: 10s
    image: quay.io/cryostat/cryostat-db:latest
    networks:
      default: null
    restart: always
    volumes:
      - type: volume
        source: postgresql
        target: /var/lib/pgsql/data
        volume: {}
  grafana:
    deploy:
      resources:
        limits:
          cpus: 0.1
          memory: "268435456"
    environment:
      GF_AUTH_ANONYMOUS_ENABLED: "true"
      GF_INSTALL_PLUGINS: grafana-simple-json-datasource
      GF_SERVER_DOMAIN: localhost
      GF_SERVER_ROOT_URL: https://localhost:8443/grafana/
      GF_SERVER_SERVE_FROM_SUB_PATH: "true"
      JFR_DATASOURCE_URL: http://jfr-datasource:8080
    expose:
      - "3000"
    hostname: grafana
    healthcheck:
      test:
        - CMD-SHELL
        - curl --fail http://localhost:3000/ || exit 1
      timeout: 1s
      interval: 30s
      retries: 3
      start_period: 10s
    image: quay.io/cryostat/cryostat-grafana-dashboard:latest
    networks:
      default: null
    restart: unless-stopped
  jfr-datasource:
    deploy:
      resources:
        limits:
          cpus: 0.4
          memory: "536870912"
    environment:
      JAVA_OPTS_APPEND: -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11223 -Dcom.sun.management.jmxremote.rmi.port=11223 -Djava.rmi.server.hostname=jfr-datasource -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false
    expose:
      - "8080"
    hostname: jfr-datasource
    healthcheck:
      test:
        - CMD-SHELL
        - curl --fail http://localhost:8080/ || exit 1
      timeout: 1s
      interval: 30s
      retries: 3
      start_period: 10s
    image: quay.io/cryostat/jfr-datasource:latest
    labels:
      io.cryostat.discovery: "true"
      io.cryostat.jmxHost: jfr-datasource
      io.cryostat.jmxPort: "11223"
    networks:
      default: null
    restart: unless-stopped
  reports:
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 2
          memory: "1073741824"
      endpoint_mode: vip
    environment:
      JAVA_OPTS_APPEND: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11224 -Dcom.sun.management.jmxremote.rmi.port=11224 -Djava.rmi.server.hostname=reports -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false
      QUARKUS_HTTP_PORT: "10001"
    expose:
      - "10001"
    hostname: reports
    healthcheck:
      test:
        - CMD-SHELL
        - curl --fail http://localhost:10001/ || exit 1
      timeout: 1s
      interval: 30s
      retries: 3
      start_period: 30s
    image: quay.io/cryostat/cryostat-reports:latest
    labels:
      io.cryostat.discovery: "true"
      io.cryostat.jmxHost: reports
      io.cryostat.jmxPort: "11224"
    networks:
      default: null
    restart: unless-stopped
  s3:
    environment:
      CRYOSTAT_ACCESS_KEY: access_key
      CRYOSTAT_BUCKETS: metadata,archivedrecordings,archivedreports,eventtemplates,probes,threaddumps,heapdumps
      CRYOSTAT_SECRET_KEY: secret_key
      DATA_DIR: /data
      IP_BIND: 0.0.0.0
      REST_ENCRYPTION_ENABLE: "1"
      WEED_V: "4"
    expose:
      - "8333"
    hostname: s3
    healthcheck:
      test:
        - CMD-SHELL
        - timeout
        - 5s
        - bash
        - -c
        - :> /dev/tcp/127.0.0.1/8333
      timeout: 5s
      interval: 10s
      retries: 3
      start_period: 30s
    image: quay.io/cryostat/cryostat-storage:latest
    networks:
      default: null
    ports:
      - mode: ingress
        target: 8888
        published: "8888"
        protocol: tcp
    restart: always
    volumes:
      - type: volume
        source: seaweed_data
        target: /data
        volume: {}
networks:
  default:
    name: compose_default
volumes:
  auth_proxy_certs:
    name: auth_proxy_certs
    external: true
  auth_proxy_cfg:
    name: auth_proxy_cfg
    external: true
  credentials:
    name: credentials
    external: true
  jmxtls_cfg:
    name: jmxtls_cfg
    external: true
  postgresql:
    name: compose_postgresql
    driver: local
  probes:
    name: probes
    external: true
  seaweed_data:
    name: compose_seaweed_data
    driver: local
  templates:
    name: templates
    external: true

Clone this wiki locally