diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..055d895 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "Base STATUS Codespace", + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "installDockerComposeSwitch": false + } + }, + "hostRequirements": { + "cpus": 8 + } + } \ No newline at end of file diff --git a/.env.deploy b/.env.deploy index db899f0..9cf3ab7 100644 --- a/.env.deploy +++ b/.env.deploy @@ -6,8 +6,8 @@ GH_CLIENT_SECRET="CLIENT_SECRET" # Replace with the GitHub client secret # JWT configuration -JWT_SECRET=cb780b1b721563ca4d88227e5dfeeedbce9ce7ba095a1df08b4761b52125815398ea59dec673f4b55954ecee6b1dbde528bdf7cb33b3b13326c49521813cdb75 -REFRESH_JWT_SECRET=4f86ea37357fbd6ea96a4d217540e2922ff849b92bc5a9176794c1236bedeed112de221c5bf8eb29f378feb88d04567c41293cf20938f40462c1d1d9fb4fa903 +JWT_SECRET=secret +REFRESH_JWT_SECRET=secret # OpenAI configuration @@ -22,40 +22,32 @@ DB_PORT='3306' DB_USER='root' DB_PASSWORD='' DB_NAME='statusdb' +DB_GRAFANA_HOST='mysql:3306' DB_CONFIG='' -## BLUEJAY CONFIG - -GOV_INFRASTRUCTURE=http://host.docker.internal:5200/api/v1/public/infrastructure-local.yaml -NODE_ENV=development - -# Repository branch that will be cloned into assetsmanager -ASSETS_REPOSITORY_BRANCH=develop - -# Influx database url -INFLUX_URL=http://host.docker.internal:5002 - -# EVENT COLLECTOR -KEY_GITHUB=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 - -# FRONTENDS ACCESS ACCOUNT -USER_RENDER=a -PASS_RENDER=a -USER_ASSETS=a -PASS_ASSETS=a - -#ASSETS MANAGER -KEY_ASSETS_MANAGER_PRIVATE=bluejay-assets-private-key - -#SCOPE MANAGER -KEY_SCOPE_MANAGER=bluejay-scope-private-key - -#COMPOSE CONFIG -COMPOSE_HTTP_TIMEOUT=200 - #STATUS NODE-RED USER_STATUS=example_user PASS_STATUS=example_pass ## NODE-RED URL -NODE_RED_URL=http://node-red-status:1880/api \ No newline at end of file +NODE_RED_URL=http://node-red-status:1880 + +#GRAFANA URL +GRAFANA_URL='http://grafana:3000' +GRAFANA_USER=example_user +GRAFANA_PASSWORD=example_pass +GRAFANA_API_KEY= + +#REDIS +DRAGONFLY_HOST=dragonfly +DRAGONFLY_PORT=6379 + +#API_PREFIX +API_PREFIX=/api/v1 + +# REGISTRY +OASTLM_MODULE_DISABLED=false +HTTPS_SERVER=null +MONGOADMIN= +MONGOPASS= +REGISTRY_URL=http://registry:80 \ No newline at end of file diff --git a/.gitignore b/.gitignore index b0e405a..baa5297 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,7 @@ node-red node-red-status status-backend status-frontend -collector-events -reporter +grafana # Node modules node_modules @@ -14,7 +13,8 @@ node_modules settings.js # Local env -.env +.env* +!.env.deploy # Mac files .DS_Store \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1c9d515..d8ae220 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nodered/node-red:3.1.3 +FROM nodered/node-red:3.1.14-minimal ## As /data is usually going to be used to provide the node-red flows, we change the cache ## to another directory, since when mounting /data the cache will be lost @@ -10,6 +10,9 @@ RUN mkdir -p /npm_cache && \ USER node-red -RUN npm install --save @alvarobc2412/status@latest +RUN npm install --save @statuscompliance/status@latest @statuscompliance/control-flow@latest @statuscompliance/extraction@latest @statuscompliance/filtering@latest @statuscompliance/integration@latest @statuscompliance/logic@latest @statuscompliance/validation@latest EXPOSE 1880 + + +ENTRYPOINT ["node-red"] \ No newline at end of file diff --git a/Windows/initial_data.ps1 b/Windows/initial_data.ps1 index 490def9..cc36778 100644 --- a/Windows/initial_data.ps1 +++ b/Windows/initial_data.ps1 @@ -6,9 +6,6 @@ Write-Host "_______________________INITIAL DATA_______________________" # Disable SSL verification [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -# Make GET request to retrieve user information -Invoke-WebRequest -Uri "http://localhost:3001/api/user" -Method GET -UseBasicParsing | Out-Null - # Define JSON payload for creating a new user $jsonBodySignUp = @{ username = "$username" @@ -25,7 +22,40 @@ $jsonBodySignIn = @{ username = "$username" password = "$passwordPlainText" } | ConvertTo-Json + $response = Invoke-WebRequest -Uri "http://localhost:3001/api/user/signIn" -Method POST -ContentType "application/json" -Body $jsonBodySignIn -UseBasicParsing $accessToken = ($response.Content | ConvertFrom-Json).accessToken Write-Host "Token JWT: $accessToken" + +$baseUrl = "http://localhost:3001/api/grafana" +$envFile = "../status-backend/.env" + +$serviceAccountPayload = @{ + name = "Status system" + role = "Admin" +} | ConvertTo-Json + +$responseServiceAccount = Invoke-WebRequest -Uri "$baseUrl/serviceaccount" -Method POST -ContentType "application/json" -Body $serviceAccountPayload -UseBasicParsing +$serviceAccountId = ($responseServiceAccount.Content | ConvertFrom-Json).id + +if (-not $serviceAccountId) { + Write-Host "Error: No se pudo obtener el ID del Service Account" + exit 1 +} + +$tokenPayload = @{ + name = "STATUS System Token" +} | ConvertTo-Json + +$responseToken = Invoke-WebRequest -Uri "$baseUrl/serviceaccount/$serviceAccountId/token" -Method POST -ContentType "application/json" -Body $tokenPayload -UseBasicParsing +$tokenKey = ($responseToken.Content | ConvertFrom-Json).key + +if (-not $tokenKey) { + Write-Host "Error: No se pudo obtener el token" + exit 1 +} + +(Get-Content $envFile) -replace '^(GRAFANA_API_KEY=).*', "`$1$tokenKey" | Set-Content $envFile + +Write-Host "Grafana API Key: $tokenKey" diff --git a/Windows/prepare_environment.ps1 b/Windows/prepare_environment.ps1 index c252599..ca1b6d8 100644 --- a/Windows/prepare_environment.ps1 +++ b/Windows/prepare_environment.ps1 @@ -54,7 +54,7 @@ else { } # Clean up previous installations -$directories = "status-backend", "status-frontend", "node-red-status", "mysql", "collector-events", "reporter" +$directories = "status-backend", "status-frontend", "node-red-status", "mysql", "grafana" foreach ($dir in $directories) { if (Test-Path "..\$dir") { @@ -66,10 +66,8 @@ foreach ($dir in $directories) { # Clone repositories Write-Host "_______________________CLONING REPOSITORIES_______________________" -git clone -b develop https://github.com/statuscompliance/status-backend ..\status-backend -git clone -b develop https://github.com/statuscompliance/status-frontend ..\status-frontend -git clone https://github.com/statuscompliance/reporter ..\reporter -git clone https://github.com/statuscompliance/collector-events ..\collector-events +# git clone -b feature/33-Integrate_grafana https://github.com/statuscompliance/status-backend ..\status-backend +# git clone -b develop https://github.com/statuscompliance/status-frontend ..\status-frontend @@ -77,6 +75,9 @@ git clone https://github.com/statuscompliance/collector-events ..\collector-even if (-not (Test-Path "..\node-red-status")) { New-Item -ItemType Directory -Path "..\node-red-status" | Out-Null } +if (-not (Test-Path "..\status-backend")) { + New-Item -ItemType Directory -Path "..\status-backend" | Out-Null +} # Delete settings.js if exists and create new from settings_template.js if (Test-Path "..\settings.js") { @@ -107,6 +108,5 @@ docker rmi $bcryptImage > $null 2>&1 (Get-Content "..\.env.deploy") -replace 'example_user', $username -replace 'example_pass', $passwordPlainText | Set-Content "..\.env" Copy-Item ..\.env ..\status-backend\.env -Copy-Item ..\.env ..\collector-events\.env Write-Host "Node-RED user created successfully." diff --git a/bin/cross_platform_utils.sh b/bin/cross_platform_utils.sh index a0a777f..84e0bad 100755 --- a/bin/cross_platform_utils.sh +++ b/bin/cross_platform_utils.sh @@ -28,7 +28,7 @@ function setupCrossPlatformEnvironment() { function getDockerCompose() { if needs_emulation; then - echo "docker-compose-emulated.yml" + echo "docker-compose.yml" else echo "docker-compose.yml" fi diff --git a/bin/initial_data.sh b/bin/initial_data.sh index fb46a16..d8ef67d 100755 --- a/bin/initial_data.sh +++ b/bin/initial_data.sh @@ -5,20 +5,54 @@ set -e echo "" echo "_______________________INITIAL DATA_______________________" -curl -s -X GET http://localhost:3001/api/user > /dev/null 2>&1 - -## Create a new user curl -s -X POST http://localhost:3001/api/user/signUp \ -H "Content-Type: application/json" \ -d "{ \"username\": \"${username}\", \"password\": \"${password}\", \"authority\": \"ADMIN\", \"email\": \"${email}\" }" > /dev/null 2>&1 - -## Sign in to get the access token token_payload=$(curl -s -X POST http://localhost:3001/api/user/signIn \ -H "Content-Type: application/json" \ -d "{ \"username\": \"${username}\", \"password\": \"${password}\" }") + docker pull linuxserver/yq > /dev/null 2>&1 token=$(docker run --rm --entrypoint jq --env JSON_DATA="$token_payload" linuxserver/yq -r -n "env.JSON_DATA | fromjson.accessToken") -docker rmi linuxserver/yq > /dev/null 2>&1 echo "Token JWT: $token" + +BASE_URL="http://localhost:3001/api/grafana" +ENV_FILE="./status-backend/.env" + +RESPONSE=$(curl -s -X POST "${BASE_URL}/serviceaccount" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $token" \ + -d '{ + "name": "Status system", + "role": "Admin" + }') + +SERVICE_ACCOUNT_ID=$(docker run --rm --entrypoint jq --env JSON_DATA="$RESPONSE" linuxserver/yq -r -n "env.JSON_DATA | fromjson.id") + +if [ -z "$SERVICE_ACCOUNT_ID" ]; then + echo "Error: No se pudo obtener el ID del Service Account" + exit 1 +fi + +# Crear un nuevo token para la cuenta de servicio +TOKEN_RESPONSE=$(curl -s -X POST "${BASE_URL}/serviceaccount/${SERVICE_ACCOUNT_ID}/token" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $token" \ + -d '{ + "name": "STATUS System Token" + }') + +TOKEN_KEY=$(docker run --rm --entrypoint jq --env JSON_DATA="$TOKEN_RESPONSE" linuxserver/yq -r -n "env.JSON_DATA | fromjson.key") + +if [ -z "$TOKEN_KEY" ]; then + echo "Error: No se pudo obtener el token" + exit 1 +fi + +sed -i.bak "s/^GRAFANA_API_KEY=.*/GRAFANA_API_KEY=$TOKEN_KEY/" "$ENV_FILE" +rm "$ENV_FILE.bak" + +echo "Grafana API Key: $TOKEN_KEY" +docker rmi linuxserver/yq > /dev/null 2>&1 \ No newline at end of file diff --git a/bin/prepare_environment.sh b/bin/prepare_environment.sh index ec2aa91..092218a 100755 --- a/bin/prepare_environment.sh +++ b/bin/prepare_environment.sh @@ -21,7 +21,7 @@ fi echo "" ## Clean up previous installations -directories=("status-backend" "status-frontend" "node-red-status" "collector-events" "reporter" ".env") +directories=("status-backend" "status-frontend" "node-red-status" "grafana" ".env") for dir in "${directories[@]}"; do if [ -d "$dir" ]; then @@ -34,16 +34,15 @@ echo "" ## Clone repositories -echo "_______________________CLONING REPOSITORIES_______________________" +# echo "_______________________CLONING REPOSITORIES_______________________" -git clone -b develop https://github.com/statuscompliance/status-backend status-backend -git clone -b develop https://github.com/statuscompliance/status-frontend status-frontend -git clone https://github.com/statuscompliance/reporter reporter -git clone https://github.com/statuscompliance/collector-events collector-events +# git clone -b feature/33-Integrate_grafana https://github.com/statuscompliance/status-backend status-backend +# git clone -b develop https://github.com/statuscompliance/status-frontend status-frontend ## If a folder is not created before doing a bind mount in Docker, the folder will be created with root permissions only. mkdir -p node-red-status +mkdir -p status-backend ## If a settings.js file exists, delete it and create a new one from settings_template.js if [ -f "settings.js" ]; then @@ -85,7 +84,6 @@ function setVariables() { setVariables cp .env status-backend/.env -cp .env collector-events/.env echo "Node-RED user created successfully." echo "" diff --git a/config/datasource-provider.yaml b/config/datasource-provider.yaml new file mode 100644 index 0000000..0b8b556 --- /dev/null +++ b/config/datasource-provider.yaml @@ -0,0 +1,34 @@ +# config file version +apiVersion: 1 + +datasources: + - name: STATUS datasource + type: postgres + access: proxy + orgId: 1 + # custom UID which can be used to reference this datasource in other parts of the configuration, if not specified will be generated automatically + # uid: my_unique_uid + url: postgres:5432 + # database user, if used + user: grafanauser + # database name, if used + database: statusdb + # enable/disable basic auth + basicAuth: false + # basic auth username + basicAuthUser: grafanauser + # enable/disable with credentials headers + withCredentials: + jsonData: + sslmode: 'disable' # disable/require/verify-ca/verify-full + maxOpenConns: 100 + maxIdleConns: 100 + maxIdleConnsAuto: true + connMaxLifetime: 14400 + postgresVersion: 1500 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 + timescaledb: false + secureJsonData: + password: grafanapass + isDefault: true + version: 1 + editable: false diff --git a/config/init.sql b/config/init.sql new file mode 100644 index 0000000..b1eebc9 --- /dev/null +++ b/config/init.sql @@ -0,0 +1,9 @@ +-- Step 1: Create user +CREATE USER grafanauser WITH PASSWORD 'grafanapass'; + +-- Step 2: Grant SELECT privilege on all tables in the public schema +GRANT SELECT ON ALL TABLES IN SCHEMA public TO grafanauser; + +-- (Optional) If you want the user to be able to access tables in the future, +-- you can give them the ability to automatically get SELECT privilege on new tables: +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO grafanauser; diff --git a/docker-compose-emulated.yml b/docker-compose-emulated.yml deleted file mode 100644 index d714011..0000000 --- a/docker-compose-emulated.yml +++ /dev/null @@ -1,329 +0,0 @@ -services: - ############### MICROSERVICES ############### - status-backend: - restart: always - container_name: status-backend - build: - context: ./status-backend - dockerfile: Dockerfile - ports: - - "3001:3001" - networks: - - web_network - - mysql_network - healthcheck: - test: curl -f -s http://127.0.0.1:3001/api/user - retries: 10 - depends_on: - mysql: - condition: service_healthy - nodered: - condition: service_healthy - # ================================================ - status-frontend: - restart: always - container_name: status-frontend - build: - context: ./status-frontend - dockerfile: Dockerfile - ports: - - "3000:80" - networks: - - web_network - # ================================================ - nodered: - restart: always - container_name: node-red-status - build: - context: . - dockerfile: Dockerfile - ports: - - "1880:1880" - volumes: - - ./node-red-status:/data - - ./settings.js:/data/settings.js - command: node-red - networks: - - web_network - # ================================================ - bluejay-render: - platform: linux/amd64 - container_name: bluejay-render - image: governify/render:develop - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - LAYOUT=bootstrap5.html - - LOGIN_USER=${USER_RENDER:?} - - LOGIN_PASSWORD=${PASS_RENDER:?} - - DEFAULT_VIEW=http://host.docker.internal:5200/api/v1/public/renders/index/view.html - - DEFAULT_CONTROLLER=http://host.docker.internal:5200/api/v1/public/renders/index/controller.js - - DEFAULT_MODEL=http://host.docker.internal:5200/api/v1/public/renders/index/model.json - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - volumes: - - "../logs/render:/opt/app/logs" - ports: - - "5100:80" - depends_on: - - bluejay-assets-manager - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-assets-manager: - platform: linux/amd64 - container_name: bluejay-assets-manager - image: "governify/assets-manager:develop" - # Needed so the volume can be written by the container after creation - user: root - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - LOGIN_USER=${USER_ASSETS:?} - - LOGIN_PASSWORD=${PASS_ASSETS:?} - - PRIVATE_KEY=${KEY_ASSETS_MANAGER_PRIVATE:?} - - GOV_INFRASTRUCTURE=/home/project/public/infrastructure-local.yaml - - ASSETS_REPOSITORY=https://github.com/governify/assets-bluejay - - ASSETS_REPOSITORY_BRANCH=${ASSETS_REPOSITORY_BRANCH:?} - volumes: - - "../assets:/home/project" - ports: - - "5200:80" - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-reporter: - platform: linux/amd64 - container_name: bluejay-reporter - build: - context: ./reporter - dockerfile: Dockerfile - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - volumes: - - "../logs/bluejay-reporter:/opt/app/logs" - ports: - - "5300:80" - mem_limit: 400m - restart: "unless-stopped" - depends_on: - - bluejay-assets-manager - - bluejay-mongo-registry - - bluejay-influx-reporter - # ================================================ - bluejay-registry: - platform: linux/amd64 - container_name: bluejay-registry - image: "governify/registry:v3.7.0" - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - volumes: - - "../logs/registry:/opt/app/logs" - - "../static:/opt/app/public/static" - ports: - - "5400:80" - depends_on: - - bluejay-assets-manager - - bluejay-mongo-registry - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-collector-events: - platform: linux/amd64 - container_name: bluejay-collector-events - build: - context: ./collector-events - dockerfile: Dockerfile - extra_hosts: - - "host.docker.internal:host-gateway" - env_file: - - .env - environment: - - NODE_ENV=production - - PORT=80 - - KEY_SCOPE_MANAGER=${KEY_SCOPE_MANAGER} - - KEY_GITHUB=${KEY_GITHUB} - - KEY_PIVOTAL=${KEY_PIVOTAL} - - KEY_TRAVIS_PUBLIC=${KEY_TRAVIS_PUBLIC} - - KEY_TRAVIS_PRIVATE=${KEY_TRAVIS_PRIVATE} - - KEY_HEROKU=${KEY_HEROKU} - - KEY_CODECLIMATE=${KEY_CODECLIMATE} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - ports: - - "5500:80" - depends_on: - - bluejay-assets-manager - - bluejay-redis-ec - mem_limit: 700m - restart: "unless-stopped" - networks: - - web_network - # ================================================ - bluejay-dashboard: - platform: linux/amd64 - container_name: bluejay-dashboard - image: governify/dashboard:develop - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - INFLUX_URL=http://host.docker.internal:5002 - - GF_PATHS_PLUGINS=/usr/share/grafana/plugins - volumes: - - "bluejay-dashboard-volume:/var/lib/grafana" - ports: - - "5600:3000" - depends_on: - - bluejay-assets-manager - - bluejay-reporter - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-director: - platform: linux/amd64 - container_name: bluejay-director - image: "governify/director:develop" - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - INFLUXDB_BIND_ADDRESS=:8088 - - NODE_ENV=production - - PORT=80 - - KEY_ASSETS_MANAGER_PRIVATE=${KEY_ASSETS_MANAGER_PRIVATE} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - ports: - - "5800:80" - depends_on: - - bluejay-assets-manager - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-scope-manager: - platform: linux/amd64 - container_name: bluejay-scope-manager - image: "governify/scope-manager:develop" - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - PRIVATE_KEY=${PRIVATE_KEY} - - NODE_ENV=production - - PORT=80 - - KEY_ASSETS_MANAGER_PRIVATE=${KEY_ASSETS_MANAGER_PRIVATE} - - KEY_SCOPE_MANAGER=${KEY_SCOPE_MANAGER} - - KEY_HEROKU=${KEY_HEROKU} - - KEY_PIVOTAL=${KEY_PIVOTAL} - - KEY_GITHUB=${KEY_GITHUB} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - ports: - - "5700:80" - depends_on: - - bluejay-assets-manager - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-join: - platform: linux/amd64 - container_name: bluejay-join - image: "governify/join-bluejay:develop" - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - PRIVATE_KEY=${PRIVATE_KEY} - - KEY_GITHUB=${KEY_GITHUB} - - NODE_ENV=development - - PORT=80 - ports: - - "6001:80" - mem_limit: 400m - restart: "unless-stopped" - ############### DATABASES ############### - bluejay-influx-reporter: - platform: linux/amd64 - image: "influxdb:1.8.4-alpine" - container_name: bluejay-influx-reporter - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - INFLUXDB_BIND_ADDRESS=:8088 - volumes: - - "bluejay-influx-reporter-volume:/var/lib/influxdb" - - "../configurations/influxdb:/etc/influxdb" - ports: - - "5002:8086" - - "8088:8088" - mem_limit: 1200m - restart: "unless-stopped" - # ================================================ - bluejay-mongo-registry: - container_name: bluejay-mongo-registry - image: mongo - extra_hosts: - - "host.docker.internal:host-gateway" - volumes: - - "bluejay-mongo-registry-volume:/data/db" - ports: - - "5001:27017" - #mem_limit: 2000m - mem_limit: 3000m - restart: "unless-stopped" - # ================================================ - bluejay-redis-ec: - platform: linux/amd64 - container_name: bluejay-redis-ec - image: redis - extra_hosts: - - "host.docker.internal:host-gateway" - volumes: - - "bluejay-redis-ec-volume:/data" - ports: - - "5003:6379" - mem_limit: 1200m - restart: "unless-stopped" - # ================================================ - mysql: - restart: always - image: mysql:8.3.0 - container_name: mysql - networks: - - mysql_network - env_file: - - .env - environment: - MYSQL_DATABASE: ${DB_NAME} - MYSQL_PASSWORD: ${DB_PASSWORD} - MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} - MYSQL_ALLOW_EMPTY_PASSWORD: yes - healthcheck: - test: mysqladmin ping -h localhost - start_period: 10s - retries: 10 - ports: - - "3306:3306" - volumes: - - mysql:/var/lib/mysql -networks: - mysql_network: - driver: bridge - web_network: - driver: bridge - -volumes: - bluejay-influx-reporter-volume: null - bluejay-mongo-registry-volume: null - bluejay-dashboard-volume: null - bluejay-redis-ec-volume: null - nodered: - name: node-red-status - mysql: - name: mysql diff --git a/docker-compose.yml b/docker-compose.yml index 46ff5e1..cc99747 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,317 +1,204 @@ services: ############### MICROSERVICES ############### status-backend: - restart: always + restart: unless-stopped container_name: status-backend - build: - context: ./status-backend - dockerfile: Dockerfile + image: statuscompliance/status-backend + # build: ../status-backend ports: - "3001:3001" - networks: - - web_network - - mysql_network healthcheck: - test: curl -f -s http://127.0.0.1:3001/api/user - retries: 10 + test: wget -q --spider http://127.0.0.1:3001/api/user + retries: 15 + environment: + DB_HOST: ${DB_HOST} + DB_NAME: ${DB_NAME} + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + NODE_RED_URL: ${NODE_RED_URL} + GRAFANA_URL: ${GRAFANA_URL} + GRAFANA_USER: ${GRAFANA_USER} + GRAFANA_PASSWORD: ${GRAFANA_PASSWORD} + GRAFANA_API_KEY: ${GRAFANA_API_KEY} + API_PREFIX: ${API_PREFIX} + DRAGONFLY_HOST: ${DRAGONFLY_HOST} + DRAGONFLY_PORT: ${DRAGONFLY_PORT} + JWT_SECRET: ${JWT_SECRET} + REFRESH_JWT_SECRET: ${REFRESH_JWT_SECRET} + GH_CLIENT_ID: ${GH_CLIENT_ID} + GH_CLIENT_SECRET: ${GH_CLIENT_SECRET} + REGISTRY_URL: ${REGISTRY_URL} depends_on: - mysql: + postgres: condition: service_healthy nodered: condition: service_healthy + dragonfly: + condition: service_healthy + networks: + - web_network + - mysql_network + - nodered_network # ================================================ status-frontend: - restart: always + restart: unless-stopped container_name: status-frontend - build: - context: ./status-frontend - dockerfile: Dockerfile + image: statuscompliance/status-frontend:PR.51 ports: - "3000:80" networks: - web_network # ================================================ nodered: - restart: always + restart: unless-stopped container_name: node-red-status build: context: . dockerfile: Dockerfile + user: "0:0" ports: - "1880:1880" + healthcheck: + test: curl -f -s http://127.0.0.1:1880 + interval: 5s + timeout: 10s + retries: 5 volumes: - - ./node-red-status:/data - - ./settings.js:/data/settings.js - command: node-red + - ./node-red-status:/root/.node-red + - ./settings.js:/root/.node-red/settings.js networks: - web_network + - nodered_network # ================================================ - bluejay-render: - container_name: bluejay-render - image: governify/render:develop - extra_hosts: - - "host.docker.internal:host-gateway" + postgres: + restart: unless-stopped + image: postgres:17.2 + container_name: postgres + networks: + - mysql_network environment: - - NODE_ENV=production - - PORT=80 - - LAYOUT=bootstrap5.html - - LOGIN_USER=${USER_RENDER:?} - - LOGIN_PASSWORD=${PASS_RENDER:?} - - DEFAULT_VIEW=http://host.docker.internal:5200/api/v1/public/renders/index/view.html - - DEFAULT_CONTROLLER=http://host.docker.internal:5200/api/v1/public/renders/index/controller.js - - DEFAULT_MODEL=http://host.docker.internal:5200/api/v1/public/renders/index/model.json - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - volumes: - - "../logs/render:/opt/app/logs" + POSTGRES_DB: ${DB_NAME} + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + healthcheck: + test: pg_isready -U ${DB_USER} + interval: 10s + timeout: 10s + retries: 10 ports: - - "5100:80" - depends_on: - - bluejay-assets-manager - mem_limit: 400m - restart: "unless-stopped" + - "5432:5432" + volumes: + - postgres:/var/lib/postgresql/data + - ./config/init.sql:/docker-entrypoint-initdb.d/init.sql # ================================================ - bluejay-assets-manager: - container_name: bluejay-assets-manager - image: "governify/assets-manager:develop" - # Needed so the volume can be written by the container after creation + grafana: + restart: unless-stopped + image: grafana/grafana-oss:latest + container_name: grafana user: root - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - LOGIN_USER=${USER_ASSETS:?} - - LOGIN_PASSWORD=${PASS_ASSETS:?} - - PRIVATE_KEY=${KEY_ASSETS_MANAGER_PRIVATE:?} - - GOV_INFRASTRUCTURE=/home/project/public/infrastructure-local.yaml - - ASSETS_REPOSITORY=https://github.com/governify/assets-bluejay - - ASSETS_REPOSITORY_BRANCH=${ASSETS_REPOSITORY_BRANCH:?} - volumes: - - "../assets:/home/project" ports: - - "5200:80" - mem_limit: 400m - restart: "unless-stopped" - # ================================================ - bluejay-reporter: - container_name: bluejay-reporter - build: - context: ./reporter - dockerfile: Dockerfile - extra_hosts: - - "host.docker.internal:host-gateway" + - "3100:3000" + networks: + - mysql_network environment: - - NODE_ENV=production - - PORT=80 - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} + - GF_SECURITY_ADMIN_USER=${USER_STATUS} + - GF_SECURITY_ADMIN_PASSWORD=${PASS_STATUS} volumes: - - "../logs/bluejay-reporter:/opt/app/logs" - ports: - - "5300:80" + - grafana:/var/lib/grafana + - ./config:/etc/grafana/provisioning/datasources mem_limit: 400m - restart: "unless-stopped" depends_on: - - bluejay-assets-manager - - bluejay-mongo-registry - - bluejay-influx-reporter - # ================================================ - bluejay-registry: - container_name: bluejay-registry - image: "governify/registry:v3.7.0" - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - PORT=80 - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} - volumes: - - "../logs/registry:/opt/app/logs" - - "../static:/opt/app/public/static" - ports: - - "5400:80" - depends_on: - - bluejay-assets-manager - - bluejay-mongo-registry - mem_limit: 400m - restart: "unless-stopped" + postgres: + condition: service_healthy # ================================================ - bluejay-collector-events: - container_name: bluejay-collector-events - build: - context: ./collector-events - dockerfile: Dockerfile - extra_hosts: - - "host.docker.internal:host-gateway" - env_file: - - .env - environment: - - NODE_ENV=production - - PORT=80 - - KEY_SCOPE_MANAGER=${KEY_SCOPE_MANAGER} - - KEY_GITHUB=${KEY_GITHUB} - - KEY_PIVOTAL=${KEY_PIVOTAL} - - KEY_TRAVIS_PUBLIC=${KEY_TRAVIS_PUBLIC} - - KEY_TRAVIS_PRIVATE=${KEY_TRAVIS_PRIVATE} - - KEY_HEROKU=${KEY_HEROKU} - - KEY_CODECLIMATE=${KEY_CODECLIMATE} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} + dragonfly: + restart: unless-stopped + image: ghcr.io/dragonflydb/dragonfly:latest + container_name: dragonfly + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 5s ports: - - "5500:80" - depends_on: - - bluejay-assets-manager - - bluejay-redis-ec - mem_limit: 700m - restart: "unless-stopped" + - '6379:6379' networks: - - web_network - # ================================================ - bluejay-dashboard: - container_name: bluejay-dashboard - image: governify/dashboard:develop - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - NODE_ENV=production - - INFLUX_URL=http://host.docker.internal:5002 - - GF_PATHS_PLUGINS=/usr/share/grafana/plugins + - mysql_network volumes: - - "bluejay-dashboard-volume:/var/lib/grafana" - ports: - - "5600:3000" - depends_on: - - bluejay-assets-manager - - bluejay-reporter - mem_limit: 400m - restart: "unless-stopped" + - dragonfly-data:/data/dragonfly # ================================================ - bluejay-director: - container_name: bluejay-director - image: "governify/director:develop" - extra_hosts: - - "host.docker.internal:host-gateway" + director: + container_name: director + image: 'governify/director:develop' environment: - - INFLUXDB_BIND_ADDRESS=:8088 - NODE_ENV=production - PORT=80 - - KEY_ASSETS_MANAGER_PRIVATE=${KEY_ASSETS_MANAGER_PRIVATE} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} + - GOV_INFRASTRUCTURE=./infrastructure.yaml ports: - - "5800:80" - depends_on: - - bluejay-assets-manager + - '5800:80' + healthcheck: + test: curl -f http://localhost:80/info + interval: 30s + timeout: 10s + retries: 5 + networks: + - mysql_network mem_limit: 400m - restart: "unless-stopped" + restart: 'unless-stopped' # ================================================ - bluejay-scope-manager: - container_name: bluejay-scope-manager - image: "governify/scope-manager:develop" - extra_hosts: - - "host.docker.internal:host-gateway" + registry: + container_name: registry + image: 'governify/registry:develop' + # build: ../renovate-reg/regJanuary/registry environment: - - PRIVATE_KEY=${PRIVATE_KEY} - - NODE_ENV=production + - NODE_ENV=development - PORT=80 - - KEY_ASSETS_MANAGER_PRIVATE=${KEY_ASSETS_MANAGER_PRIVATE} - - KEY_SCOPE_MANAGER=${KEY_SCOPE_MANAGER} - - KEY_HEROKU=${KEY_HEROKU} - - KEY_PIVOTAL=${KEY_PIVOTAL} - - KEY_GITHUB=${KEY_GITHUB} - - GOV_INFRASTRUCTURE=${GOV_INFRASTRUCTURE:?} + - GOV_INFRASTRUCTURE=./infrastructure.yaml + - GOV_LOG_LEVEL=debug + - MONGOPASS=${MONGOPASS} + - MONGOADMIN=${MONGOADMIN} + - HTTPS_SERVER=${HTTPS_SERVER} + - OASTLM_MODULE_DISABLED=${OASTLM_MODULE_DISABLED} + volumes: + - '../logs/registry:/opt/app/logs' + - '../static:/opt/app/public/static' ports: - - "5700:80" + - '5400:80' depends_on: - - bluejay-assets-manager + - mongo-registry + networks: + - mysql_network mem_limit: 400m - restart: "unless-stopped" + restart: 'unless-stopped' # ================================================ - bluejay-join: - container_name: bluejay-join - image: "governify/join-bluejay:develop" - extra_hosts: - - "host.docker.internal:host-gateway" + mongo-registry: + container_name: mongo-registry + image: mongo:latest environment: - - PRIVATE_KEY=${PRIVATE_KEY} - - KEY_GITHUB=${KEY_GITHUB} - - NODE_ENV=development - - PORT=80 - ports: - - "6001:80" - mem_limit: 400m - restart: "unless-stopped" - ############### DATABASES ############### - bluejay-influx-reporter: - image: "influxdb:1.8.4-alpine" - container_name: bluejay-influx-reporter - extra_hosts: - - "host.docker.internal:host-gateway" - environment: - - INFLUXDB_BIND_ADDRESS=:8088 - volumes: - - "bluejay-influx-reporter-volume:/var/lib/influxdb" - - "../configurations/influxdb:/etc/influxdb" - ports: - - "5002:8086" - - "8088:8088" - mem_limit: 1200m - restart: "unless-stopped" - # ================================================ - bluejay-mongo-registry: - container_name: bluejay-mongo-registry - image: mongo - extra_hosts: - - "host.docker.internal:host-gateway" + - MONGO_INITDB_ROOT_USERNAME=${MONGOADMIN} + - MONGO_INITDB_ROOT_PASSWORD=${MONGOPASS} volumes: - - "bluejay-mongo-registry-volume:/data/db" + - 'registry-data:/data/db' ports: - "5001:27017" - mem_limit: 3000m - restart: "unless-stopped" - # ================================================ - bluejay-redis-ec: - container_name: bluejay-redis-ec - image: redis - extra_hosts: - - "host.docker.internal:host-gateway" - volumes: - - "bluejay-redis-ec-volume:/data" - ports: - - "5003:6379" - mem_limit: 1200m - restart: "unless-stopped" - # ================================================ - mysql: - restart: always - image: mysql:8.3.0 - container_name: mysql networks: - mysql_network - env_file: - - .env - environment: - MYSQL_DATABASE: ${DB_NAME} - MYSQL_PASSWORD: ${DB_PASSWORD} - MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} - MYSQL_ALLOW_EMPTY_PASSWORD: yes - healthcheck: - test: mysqladmin ping -h localhost - start_period: 10s - retries: 10 - ports: - - "3306:3306" - volumes: - - mysql:/var/lib/mysql + mem_limit: 2000m + restart: 'unless-stopped' + networks: mysql_network: driver: bridge web_network: driver: bridge + nodered_network: + driver: bridge volumes: - bluejay-influx-reporter-volume: null - bluejay-mongo-registry-volume: null - bluejay-dashboard-volume: null - bluejay-redis-ec-volume: null + dragonfly-data: + registry-data: nodered: name: node-red-status - mysql: - name: mysql + postgres: + grafana: \ No newline at end of file diff --git a/settings_template.js b/settings_template.js index 857c2cd..2c43d85 100644 --- a/settings_template.js +++ b/settings_template.js @@ -193,7 +193,7 @@ module.exports = { * can be used to specifiy a different root path. If set to false, this is * disabled. */ - //httpNodeRoot: '/red-nodes', + httpNodeRoot: '/api/v1', /** The following property can be used to configure cross-origin resource sharing * in the HTTP nodes.