diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..2cc0d2d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,50 @@ +name: build-orthanc-prometheus + +on: + push: + branches: + - '*' + tags: + - '*' + +jobs: + + build-orthanc-prometheus: + runs-on: ubuntu-latest + steps: + + - name: checkout + uses: actions/checkout@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker (orthanc-prometheus) + id: meta-orthanc-prometheus + uses: docker/metadata-action@v4 + with: + images: orthancteam/orthanc-prometheus + labels: | + org.opencontainers.image.title=orthanc-prometheus + org.opencontainers.image.vendor=Orthanc Team SRL + + - name: Build and push orthanc-prometheus Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: Dockerfile + push: true + tags: ${{ steps.meta-orthanc-prometheus.outputs.tags }} + labels: ${{ steps.meta-orthanc-prometheus.outputs.labels }} + + - name: Docker Hub Description (orthanc-prometheus) + uses: peter-evans/dockerhub-description@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: orthancteam/orthanc-prometheus + short-description: A Prometheus pushing Orthanc metrics to a remote write destination. + readme-filepath: README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3bf4b39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/orthanc-secrets +/.env +/.idea +/passwords +*/secrets/ +*.env \ No newline at end of file diff --git a/README.md b/README.md index b94d022..68ccacc 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# Orthanc-monitoring +# Orthanc-prometheus -## Summary -Here is only a basic Orthanc with a Postgres. +Based on the official `prom/prometheus` Docker image, here is an extra layer to allow the configuration of the scrap (Orthanc only) and remote write through environment variables. -But these 2 services, as well as the host system and the containers, are monitored thanks to Prometheus. -Grafana is also there to show the metrics. +## How it works? -## How it works +A bash script will get the env var when the container starts and replace the placeholders in the `prometheus.yml` file. -### Prometheus +Then, Prometheus will be started as usual. -Prometheus will collect the metrics from these sources: -- Orthanc ([link to official doc](https://book.orthanc-server.com/users/advanced-rest.html#instrumentation-with-prometheus)) -- Node-exporter (allow to get the metrics from the system: CPU, RAM, disk space,...) -- Postgres (thanks to the exporter) -- CAdvisor (allow to get the metrics from the containers) -### Grafana +## How to use it ? -There is a predefined dashboard with all the metrics listed above. +Define these env vars: -## Misc -- There is a volume for the dashboard (Grafana container) so, if an update (with a new version of the dashboard) has to be made, the volume has to be deleted (otherwise, the dashboard will remain as it was) +- `DEPLOYMENT_NAME` (default: `unnamed_deployement`) +- `ORTHANC_SERVICE_NAME` (default: `orthanc`) +- `ORTHANC_SERVICE_PORT` (default: `8042`) +- `ORTHANC_USERNAME` (default: `orthanc`) +- `ORTHANC_PASSWORD` (default: `orthanc`) + +- `REMOTE_WRITE_URL` (could be something like `https://prometheus-something.grafana.net/api/prom/push`) +- `REMOTE_WRITE_USERNAME` (some sort of ID from Grafana.com) +- `REMOTE_WRITE_PASSWORD` (can be generated from Grafana.com) diff --git a/docker-compose.yml b/docker-compose.yml index 83d6506..65a4f75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.8" services: orthanc: - image: osimis/orthanc:23.3.0 + image: orthancteam/orthanc:24.3.4 restart: unless-stopped depends_on: - postgres @@ -18,11 +18,16 @@ services: ORTHANC__ORTHANC_EXPLORER_2__UI_OPTIONS__STUDY_LIST_SEARCH_MODE: "search-button" ORTHANC__ORTHANC_EXPLORER_2__UI_OPTIONS__STUDY_LIST_EMPTY_IF_NO_SEARCH: "true" ORTHANC__ORTHANC_EXPLORER_2__IS_DEFAULT_ORTHANC_UI: "true" + ORTHANC__ORTHANC_EXPLORER_2__DATE_FORMAT: "dd.MM.yyyy" ORTHANC__POSTGRESQL__HOST: "postgres" ORTHANC__POSTGRESQL__ENABLE_INDEX: "true" ORTHANC__POSTGRESQL__ENABLE_STORAGE: "false" DICOM_WEB_PLUGIN_ENABLED: "true" - ORTHANC__AUTHENTICATION_ENABLED: "false" + ORTHANC__AUTHENTICATION_ENABLED: "true" + ORTHANC__DICOM_MODALITIES: | + { + "test": ["test", "dicom-tls-relay", 50000] + } volumes: ["orthanc-data:/var/lib/orthanc/db:Z"] postgres: @@ -38,77 +43,16 @@ services: - 9090:9090 volumes: - prometheus_data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' restart: unless-stopped - depends_on: - - node-exporter - - node-exporter: - image: prom/node-exporter:v1.5.0 - ports: - - 9100:9100 - # volumes: - # - /proc:/host/proc:ro - # - /sys:/host/sys:ro - # - /:/rootfs:ro - # command: - # - '--path.procfs=/host/proc' - # - '--path.sysfs=/host/sys' - # - '--collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+)($$|/)' - command: - - '--path.rootfs=/host' - # - '--cap-add=SYS_TIME' - volumes: - - '/:/host:ro,rslave' - # - /proc:/host/proc:ro - # - /sys:/host/sys:ro - # - /:/rootfs:ro - restart: unless-stopped - - cadvisor: - image: gcr.io/cadvisor/cadvisor:v0.47.1 - volumes: - - /:/rootfs:ro - - /var/run:/var/run:ro - - /sys:/sys:ro - - /var/lib/docker/:/var/lib/docker:ro - - /dev/disk/:/dev/disk:ro - privileged: true - restart: unless-stopped - - postgres-exporter: - image: quay.io/prometheuscommunity/postgres-exporter:v0.12.0 - restart: unless-stopped - depends_on: - - postgres - environment: - - DATA_SOURCE_NAME=postgresql://postgres@postgres:5432/postgres?sslmode=disable - - grafana: - build: grafana - ports: - - 3000:3000 environment: - - GF_SECURITY_ADMIN_USER=admin - - GF_SECURITY_ADMIN_PASSWORD=admin - - GF_USERS_ALLOW_SIGN_UP=false - - DS_PROMETHEUS=prometheus - depends_on: - - prometheus - restart: unless-stopped - volumes: - - "dashboards:/var/lib/grafana:Z" - - "grafana-config:/etc/grafana:Z" - - "grafana-logs:/var/log/grafana:Z" + DEPLOYMENT_NAME: "test-name3" + env_file: + - ./prometheus.env + - volumes: prometheus_data: orthanc-data: orthanc-index: - dashboards: - grafana-config: - grafana-logs: - + diff --git a/old-tests/README.md b/old-tests/README.md new file mode 100644 index 0000000..c02d938 --- /dev/null +++ b/old-tests/README.md @@ -0,0 +1,26 @@ +# Orthanc-monitoring + +WARNING: This folder contains some old setup which was used for testing/exploration. + +## Summary +Here is only a basic Orthanc with a Postgres. + +But these 2 services, as well as the host system and the containers, are monitored thanks to Prometheus. +Grafana is also there to show the metrics. + +## How it works + +### Prometheus + +Prometheus will collect the metrics from these sources: +- Orthanc ([link to official doc](https://book.orthanc-server.com/users/advanced-rest.html#instrumentation-with-prometheus)) +- Node-exporter (allow to get the metrics from the system: CPU, RAM, disk space,...) +- Postgres (thanks to the exporter) +- CAdvisor (allow to get the metrics from the containers) + +### Grafana + +There is a predefined dashboard with all the metrics listed above. + +## Misc +- There is a volume for the dashboard (Grafana container) so, if an update (with a new version of the dashboard) has to be made, the volume has to be deleted (otherwise, the dashboard will remain as it was) diff --git a/old-tests/docker-compose.yml b/old-tests/docker-compose.yml new file mode 100644 index 0000000..3725196 --- /dev/null +++ b/old-tests/docker-compose.yml @@ -0,0 +1,130 @@ +version: "3.8" + +services: + + orthanc: + image: orthancteam/orthanc:24.3.4 + restart: unless-stopped + depends_on: + - postgres + ports: + - 8042:8042 + environment: + ORTHANC__NAME: "Orthanc PACS" + VERBOSE_ENABLED: "true" + VERBOSE_STARTUP: "true" + STONE_WEB_VIEWER_PLUGIN_ENABLED: "true" + ORTHANC__STONE_WEB_VIEWER__SHOW_INFO_PANEL_AT_STARTUP: "Never" + ORTHANC__ORTHANC_EXPLORER_2__UI_OPTIONS__STUDY_LIST_SEARCH_MODE: "search-button" + ORTHANC__ORTHANC_EXPLORER_2__UI_OPTIONS__STUDY_LIST_EMPTY_IF_NO_SEARCH: "true" + ORTHANC__ORTHANC_EXPLORER_2__IS_DEFAULT_ORTHANC_UI: "true" + ORTHANC__ORTHANC_EXPLORER_2__DATE_FORMAT: "dd.MM.yyyy" + ORTHANC__POSTGRESQL__HOST: "postgres" + ORTHANC__POSTGRESQL__ENABLE_INDEX: "true" + ORTHANC__POSTGRESQL__ENABLE_STORAGE: "false" + DICOM_WEB_PLUGIN_ENABLED: "true" + ORTHANC__AUTHENTICATION_ENABLED: "true" + ORTHANC__DICOM_MODALITIES: | + { + "test": ["test", "dicom-tls-relay", 50000] + } + volumes: ["orthanc-data:/var/lib/orthanc/db:Z"] + + postgres: + image: postgres:15 + restart: unless-stopped + volumes: ["orthanc-index:/var/lib/postgresql/data:Z"] + environment: + POSTGRES_HOST_AUTH_METHOD: "trust" + + prometheus: + build: prometheus + ports: + - 9090:9090 + volumes: + - prometheus_data:/prometheus + restart: unless-stopped + environment: + REMOTE_WRITE_URL: "https://xxxxxx.grafana.net/api/prom/push" + REMOTE_WRITE_USERNAME: 000000 + + #DEPLOYMENT_NAME: "test-name3" + + # node-exporter: + # image: prom/node-exporter:v1.5.0 + # ports: + # - 9100:9100 + # # volumes: + # # - /proc:/host/proc:ro + # # - /sys:/host/sys:ro + # # - /:/rootfs:ro + # # command: + # # - '--path.procfs=/host/proc' + # # - '--path.sysfs=/host/sys' + # # - '--collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+)($$|/)' + # command: + # - '--path.rootfs=/host' + # # - '--cap-add=SYS_TIME' + # volumes: + # - '/:/host:ro,rslave' + # # - /proc:/host/proc:ro + # # - /sys:/host/sys:ro + # # - /:/rootfs:ro + # restart: unless-stopped + + # cadvisor: + # ports: + # - 8080:8080 + # image: gcr.io/cadvisor/cadvisor:v0.47.1 + # volumes: + # - /:/rootfs:ro + # - /var/run:/var/run:ro + # - /sys:/sys:ro + # - /var/lib/docker/:/var/lib/docker:ro + # - /dev/disk/:/dev/disk:ro + # privileged: true + # restart: unless-stopped + + # postgres-exporter: + # ports: + # - 9187:9187 + # image: quay.io/prometheuscommunity/postgres-exporter:v0.12.0 + # restart: unless-stopped + # depends_on: + # - postgres + # environment: + # - DATA_SOURCE_NAME=postgresql://postgres@postgres:5432/postgres?sslmode=disable + + grafana: + build: grafana + ports: + - 3000:3000 + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - DS_PROMETHEUS=prometheus + depends_on: + - prometheus + restart: unless-stopped + volumes: + - "dashboards:/var/lib/grafana:Z" + - "grafana-config:/etc/grafana:Z" + - "grafana-logs:/var/log/grafana:Z" + + + victoria-metrics: + image: victoriametrics/victoria-metrics:v1.94.0 + ports: + - 8428:8428 + volumes: + - ./vm-data/:/victoria-metrics-data + +volumes: + prometheus_data: + orthanc-data: + orthanc-index: + dashboards: + grafana-config: + grafana-logs: + diff --git a/grafana/Dockerfile b/old-tests/grafana/Dockerfile similarity index 100% rename from grafana/Dockerfile rename to old-tests/grafana/Dockerfile diff --git a/grafana/dashboard-pg.json b/old-tests/grafana/dashboard-pg.json similarity index 100% rename from grafana/dashboard-pg.json rename to old-tests/grafana/dashboard-pg.json diff --git a/grafana/dashboard.json b/old-tests/grafana/dashboard.json similarity index 100% rename from grafana/dashboard.json rename to old-tests/grafana/dashboard.json diff --git a/grafana/dashboard.yml b/old-tests/grafana/dashboard.yml similarity index 100% rename from grafana/dashboard.yml rename to old-tests/grafana/dashboard.yml diff --git a/grafana/datasource.yml b/old-tests/grafana/datasource.yml similarity index 100% rename from grafana/datasource.yml rename to old-tests/grafana/datasource.yml diff --git a/old-tests/prometheus/Dockerfile b/old-tests/prometheus/Dockerfile new file mode 100644 index 0000000..28d190e --- /dev/null +++ b/old-tests/prometheus/Dockerfile @@ -0,0 +1,5 @@ +FROM prom/prometheus:v2.51.1 + +COPY prometheus.yml /etc/prometheus/ + +CMD ["--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles", "--enable-feature=expand-external-labels"] \ No newline at end of file diff --git a/old-tests/prometheus/prometheus.yml b/old-tests/prometheus/prometheus.yml new file mode 100644 index 0000000..fef37fc --- /dev/null +++ b/old-tests/prometheus/prometheus.yml @@ -0,0 +1,43 @@ +global: + scrape_interval: 10s + scrape_timeout: 5s + + external_labels: + deployment_name: $DEPLOYMENT_NAME + +remote_write: + - url: http://victoria-metrics:8428/api/v1/write + - url: https://xxxxxx.grafana.net/api/prom/push + basic_auth: + username: 1220892 + #password_file: /etc/prometheus/grafana.env + password: xxxxxxxxxxxxxxx + +scrape_configs: + + - job_name: 'orthanc' + scrape_interval: 10s + metrics_path: /tools/metrics-prometheus + static_configs: + - targets: ['orthanc:8042'] + basic_auth: + username: orthanc + password_file: /etc/prometheus/orthanc.env + + # - job_name: 'prometheus' + # static_configs: + # - targets: ['prometheus:9090'] + + # - job_name: 'node-exporter' + # static_configs: + # - targets: ['node-exporter:9100'] + + # - job_name: 'cadvisor' + # scrape_interval: 5s + # static_configs: + # - targets: ['cadvisor:8080'] + + # - job_name: 'postgres_exporter' + # scrape_interval: 5s + # static_configs: + # - targets: ['postgres-exporter:9187'] \ No newline at end of file diff --git a/prometheus/Dockerfile b/prometheus/Dockerfile index 395ca67..1a35688 100644 --- a/prometheus/Dockerfile +++ b/prometheus/Dockerfile @@ -1,3 +1,10 @@ -FROM prom/prometheus:v2.43.0 +FROM prom/prometheus:v2.51.1 +USER root +COPY ./entrypoint.sh /entrypoint.sh COPY prometheus.yml /etc/prometheus/ + +RUN chmod +x /entrypoint.sh + +USER nobody +ENTRYPOINT [ "/entrypoint.sh" ] \ No newline at end of file diff --git a/prometheus/entrypoint.sh b/prometheus/entrypoint.sh new file mode 100644 index 0000000..5bbd16a --- /dev/null +++ b/prometheus/entrypoint.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# Set environment variables default values if needed +DEPLOYMENT_NAME="${DEPLOYMENT_NAME:-unnamed_deployement}" + +ORTHANC_SERVICE_NAME="${ORTHANC_SERVICE_NAME:-orthanc}" +ORTHANC_SERVICE_PORT="${ORTHANC_SERVICE_PORT:-8042}" +ORTHANC_USERNAME="${ORTHANC_USERNAME:-orthanc}" +ORTHANC_PASSWORD="${ORTHANC_PASSWORD:-orthanc}" + +# Replace placeholders with environment variable values +sed -i "s/\$DEPLOYMENT_NAME/$DEPLOYMENT_NAME/g" /etc/prometheus/prometheus.yml + +# Espace slashes from URL +escaped_remote_write_url=$(echo "$REMOTE_WRITE_URL" | sed 's/\//\\\//g') && sed -i "s/\$REMOTE_WRITE_URL/$escaped_remote_write_url/g" /etc/prometheus/prometheus.yml +sed -i "s/\$REMOTE_WRITE_USERNAME/$REMOTE_WRITE_USERNAME/g" /etc/prometheus/prometheus.yml +sed -i "s/\$REMOTE_WRITE_PASSWORD/$REMOTE_WRITE_PASSWORD/g" /etc/prometheus/prometheus.yml + +sed -i "s/\$ORTHANC_SERVICE_NAME/$ORTHANC_SERVICE_NAME/g" /etc/prometheus/prometheus.yml +sed -i "s/\$ORTHANC_SERVICE_PORT/$ORTHANC_SERVICE_PORT/g" /etc/prometheus/prometheus.yml +sed -i "s/\$ORTHANC_USERNAME/$ORTHANC_USERNAME/g" /etc/prometheus/prometheus.yml +sed -i "s/\$ORTHANC_PASSWORD/$ORTHANC_PASSWORD/g" /etc/prometheus/prometheus.yml + + +## call original prometheus entrypoint +/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles \ No newline at end of file diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml index 6c3db28..d9242ef 100644 --- a/prometheus/prometheus.yml +++ b/prometheus/prometheus.yml @@ -1,29 +1,23 @@ global: - scrape_interval: 6s + scrape_interval: 10s scrape_timeout: 5s + + external_labels: + deployment_name: $DEPLOYMENT_NAME -scrape_configs: +remote_write: + - url: $REMOTE_WRITE_URL + basic_auth: + username: $REMOTE_WRITE_USERNAME + password: $REMOTE_WRITE_PASSWORD - - job_name: 'prometheus' - static_configs: - - targets: ['prometheus:9090'] - - - job_name: 'node-exporter' - static_configs: - - targets: ['node-exporter:9100'] +scrape_configs: - job_name: 'orthanc' scrape_interval: 10s metrics_path: /tools/metrics-prometheus static_configs: - - targets: ['orthanc:8042'] - - - job_name: 'cadvisor' - scrape_interval: 5s - static_configs: - - targets: ['cadvisor:8080'] - - - job_name: 'postgres_exporter' - scrape_interval: 5s - static_configs: - - targets: ['postgres-exporter:9187'] \ No newline at end of file + - targets: ['$ORTHANC_SERVICE_NAME:$ORTHANC_SERVICE_PORT'] + basic_auth: + username: $ORTHANC_USERNAME + password: $ORTHANC_PASSWORD