From 1b1b692627e0121a1d7e6923102443b5ca9d8272 Mon Sep 17 00:00:00 2001 From: "michael.nguyen" Date: Wed, 2 Sep 2026 16:33:26 +0100 Subject: [PATCH 1/3] add Grafana service and configuration for PostgreSQL datasource --- deploy/docker-compose.production.yml | 22 ++++++++++++++++++++++ grafana/dashboards/default.yaml | 24 ++++++++++++++++++++++++ grafana/datasources/postgres.yaml | 25 +++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 grafana/dashboards/default.yaml create mode 100644 grafana/datasources/postgres.yaml diff --git a/deploy/docker-compose.production.yml b/deploy/docker-compose.production.yml index 702995c2..11a71842 100644 --- a/deploy/docker-compose.production.yml +++ b/deploy/docker-compose.production.yml @@ -31,6 +31,23 @@ services: interval: 5s timeout: 3s retries: 30 + grafana: + image: grafana/grafana:13.2.0 + restart: always + ports: + - "3000:3000" + environment: + - GF_SECURITY_ALLOW_EMBEDDING=true + - POSTGRESQL_USER=${POSTGRESQL_USER} + - POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD} + - POSTGRESQL_DB=${POSTGRESQL_DB} + volumes: + - grafana-data:/var/lib/grafana + - ../grafana/datasources:/etc/grafana/provisioning/datasources:ro + - ../grafana/dashboards:/etc/grafana/provisioning/dashboards:ro + - ../grafana/dashboards:/var/lib/grafana/dashboards:ro + networks: + - skynet postgresql: image: postgres:${POSTGRESQL_DOCKER_VERSION} restart: always @@ -88,6 +105,10 @@ services: redis_host: ${REDIS_HOST} postgresql_server: ${POSTGRESQL_HOST} validTestDomains: ${VALID_TEST_DOMAINS} + volumes: + - ../server/config/server.yaml:/usr/src/app/config/server.yaml:ro + ports: + - "3001:3000" restart: always networks: - skynet @@ -147,6 +168,7 @@ volumes: driver: local caddy_data: caddy_config: + grafana-data: networks: skynet: name: skynet diff --git a/grafana/dashboards/default.yaml b/grafana/dashboards/default.yaml new file mode 100644 index 00000000..da92ff30 --- /dev/null +++ b/grafana/dashboards/default.yaml @@ -0,0 +1,24 @@ +apiVersion: 1 + +providers: + # an unique provider name. Required + - name: 'sitespeed.io' + # Org id. Default to 1 + orgId: 1 + # name of the dashboard folder. + folder: 'sitespeed.io' + # folder UID. will be automatically generated if not specified + folderUid: '' + # provider type. Default to 'file' + type: file + # disable dashboard deletion + disableDeletion: false + # how often Grafana will scan for changed dashboards + updateIntervalSeconds: 10 + # allow updating provisioned dashboards from the UI + allowUiUpdates: true + options: + # path to dashboard files on disk. Required when using the 'file' type + path: /var/lib/grafana/dashboards + # use folder names from filesystem to create folders in Grafana + foldersFromFilesStructure: true diff --git a/grafana/datasources/postgres.yaml b/grafana/datasources/postgres.yaml new file mode 100644 index 00000000..8b82ba29 --- /dev/null +++ b/grafana/datasources/postgres.yaml @@ -0,0 +1,25 @@ +# OnlineTest PostgreSQL — URL tables for CWV Group (not Graphite). +# Grafana must be on Docker network `skynet` so host `postgresql` resolves. +# Password comes from the Grafana container env (POSTGRESQL_*). +apiVersion: 1 + +datasources: + - name: onlinetest-postgres + type: postgres + uid: onlinetest-postgres + access: proxy + orgId: 1 + url: postgresql:5432 + user: ${POSTGRESQL_USER} + isDefault: false + editable: true + jsonData: + database: ${POSTGRESQL_DB} + sslmode: disable + postgresVersion: 1600 + timescaledb: false + maxOpenConns: 10 + maxIdleConns: 5 + connMaxLifetime: 14400 + secureJsonData: + password: ${POSTGRESQL_PASSWORD} From c372ce0884d4eebcf26da6d09f2b36d170d6dc50 Mon Sep 17 00:00:00 2001 From: "michael.nguyen" Date: Wed, 2 Sep 2026 16:34:38 +0100 Subject: [PATCH 2/3] update update.sh to load .env from root --- deploy/update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/update.sh b/deploy/update.sh index 1a6abd7b..b88bbaa7 100755 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -105,17 +105,17 @@ if [ -n "$VERSION" ]; then fi echo ">> Pulling images (mode=$MODE)…" -docker compose "${COMPOSE_FILES[@]}" pull +docker compose --env-file "$REPO_ROOT/.env" "${COMPOSE_FILES[@]}" pull echo ">> Restarting services…" -docker compose "${COMPOSE_FILES[@]}" up -d --remove-orphans +docker compose --env-file "$REPO_ROOT/.env" "${COMPOSE_FILES[@]}" up -d --remove-orphans echo ">> Container status:" -docker compose "${COMPOSE_FILES[@]}" ps +docker compose --env-file "$REPO_ROOT/.env" "${COMPOSE_FILES[@]}" ps echo ">> Tailing logs for 10 seconds (Ctrl+C to keep watching)…" # `timeout` returns 124 when it kills the process — that's the success path # here, so swallow the non-zero exit. Plain `|| true` keeps `set -e` happy. -timeout 10 docker compose "${COMPOSE_FILES[@]}" logs --tail 30 -f || true +timeout 10 docker compose --env-file "$REPO_ROOT/.env" "${COMPOSE_FILES[@]}" logs --tail 30 -f || true echo ">> Done." From 40a3368740b6c720088d70f879790d302a1b3780 Mon Sep 17 00:00:00 2001 From: "michael.nguyen" Date: Wed, 2 Sep 2026 16:35:22 +0100 Subject: [PATCH 3/3] integrate server.yaml to production for allowing custom browsertime configs --- deploy/docker-compose.production-server.yml | 2 ++ server/config/server.yaml | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/deploy/docker-compose.production-server.yml b/deploy/docker-compose.production-server.yml index f0f191c6..1162ed71 100644 --- a/deploy/docker-compose.production-server.yml +++ b/deploy/docker-compose.production-server.yml @@ -76,6 +76,8 @@ services: redis_host: ${REDIS_HOST} postgresql_server: ${POSTGRESQL_HOST} validTestDomains: ${VALID_TEST_DOMAINS} + volumes: + - ../server/config/server.yaml:/usr/src/app/config/server.yaml:ro ports: - "3000:3000" restart: always diff --git a/server/config/server.yaml b/server/config/server.yaml index 79509a0f..2b80f92a 100644 --- a/server/config/server.yaml +++ b/server/config/server.yaml @@ -110,4 +110,20 @@ queue: # If you don't setup a default sitespeed.io configuration, you can add # your sitespeed.io configuration directly in this block -sitespeed.io: \ No newline at end of file +sitespeed.io: + slug: default + browsertime: + iterations: 1 + video: false + visualMetrics: false + screenshot: false + screenshotLCP: false + screenshotLS: false + pageCompleteWaitTime: 300 + chrome: + args: + - "--headless=new" + - "--blink-settings=imagesEnabled=false" + - "--disable-dev-shm-usage" + - "--no-sandbox" + - "--disable-gpu"