diff --git a/.commitlintrc.js b/.commitlintrc.js
deleted file mode 100644
index 28c36622..00000000
--- a/.commitlintrc.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import commitlintConfigConventional from "@commitlint/config-conventional"
-
-const ruleMaxLineLength =
- commitlintConfigConventional.rules["body-max-line-length"];
-
-ruleMaxLineLength[0] = process.env.CI === "true" ? 1 : 2;
-
-export default {
- extends: ["@commitlint/config-conventional"],
- rules: {
- "body-max-line-length": ruleMaxLineLength,
- "footer-max-line-length": ruleMaxLineLength,
- },
-};
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index f78d206a..46823ac1 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,12 +1 @@
-# These are supported funding model platforms
-
-github: [dargmuesli] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
-patreon: # Replace with a single Patreon username
-open_collective: # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+github: [dargmuesli]
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8d408ce0..8897680b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,12 +20,30 @@ jobs:
build:
needs: ci-optimization
if: needs.ci-optimization.outputs.continue == 'true'
- name: dargstack rgen
- uses: dargmuesli/github-actions/.github/workflows/dargstack-rgen.yml@661e39fe1c9e484d94c6a5a9d4c9946d57c41771 # 5.1.0
+ name: Update generated docs
+ runs-on: ubuntu-latest
permissions:
- contents: read
- with:
- APT_PACKAGES: mkcert
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.head_ref || github.ref_name }}
+ - name: Regenerate docs
+ run: |
+ go install github.com/dargstack/dargstack/v4/cmd/dargstack@latest
+ export PATH="$(go env GOPATH)/bin:$PATH"
+ dargstack document
+ - name: Commit and push updated docs
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add artifacts/docs/
+ if git diff --staged --quiet; then
+ echo "Docs are already up to date"
+ else
+ git commit -m "chore: update generated docs"
+ git push
+ fi
release-semantic:
needs: build
name: Semantic Release
diff --git a/.husky/commit-msg b/.husky/commit-msg
deleted file mode 100755
index 2b99f23e..00000000
--- a/.husky/commit-msg
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-export NVM_DIR="$HOME/.nvm"
-# shellcheck source=/dev/null
-[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
-
-pnpm commitlint --edit "$1"
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
deleted file mode 100644
index 862a47b8..00000000
--- a/.husky/pre-commit
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-export NVM_DIR="$HOME/.nvm"
-# shellcheck source=/dev/null
-[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
-
-pnpm dargstack_rgen --validate
diff --git a/.nvmrc b/.nvmrc
deleted file mode 100644
index a45fd52c..00000000
--- a/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-24
diff --git a/.releaserc.json b/.releaserc.json
index 38b975bb..1f79157c 100644
--- a/.releaserc.json
+++ b/.releaserc.json
@@ -15,9 +15,7 @@
}
],
"@semantic-release/changelog",
- "@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
- ],
- "tagFormat": "${version}"
+ ]
}
diff --git a/Dockerfile.md b/Dockerfile.md
new file mode 100644
index 00000000..4762ebf4
--- /dev/null
+++ b/Dockerfile.md
@@ -0,0 +1,3 @@
+#
+FROM ghcr.io/dargstack/dargstack:4.0.0-beta.1
+#
diff --git a/README.md b/README.md
deleted file mode 100644
index 7b8e6434..00000000
--- a/README.md
+++ /dev/null
@@ -1,411 +0,0 @@
-# stack
-
-
-The Docker stack configuration for [vibetype.app](https://vibetype.app/).
-
-This project is deployed in accordance to the [DargStack template](https://github.com/dargstack/dargstack_template/) to make deployment a breeze. It is closely related to [Vibetype's source code](https://github.com/maevsi/vibetype/).
-
-## Table of Contents
-
-
- 1. [x-shared](#x-shared)
-
- 2. [secrets](#secrets)
-
- 3. [services](#services)
-
- 4. [volumes](#volumes)
-
-
-## x-shared
-
-
- - ### `zammad-service`
-
- You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
-
-
-## secrets
-
-
- - ### `elasticsearch-keystore_password`
-
- The search engine's password for the keystore.
-
- - ### `elasticsearch-password`
-
- The search engine's password for the default user.
-
- - ### `grafana_admin_email`
-
- The observation dashboard's admin email.
-
- - ### `grafana_admin_password`
-
- The observation dashboard's admin password.
-
- - ### `grafana_admin_user`
-
- The observation dashboard's admin user.
-
- - ### `grafana_discord_webhook`
-
- The observation dashboard's contact point for Discord.
-
- - ### `jobber_aliases`
-
- The job scheduler's SMTP client mail alias.
-
- - ### `jobber_aws-bucket`
-
- The job scheduler's AWS bucket name.
-
- - ### `jobber_aws-configuration`
-
- The job scheduler's AWS configuration.
-
- - ### `jobber_aws-credentials`
-
- The job scheduler's AWS credentials.
-
- - ### `jobber_msmtprc`
-
- The job scheduler's SMTP client configuration.
-
- - ### `portainer_admin-password`
-
- The container manager's admin password.
-
- - ### `postgraphile_connection`
-
- The GraphQL API's database URI.
-
- - ### `postgraphile_jwt-secret`
-
- The GraphQL API's JWT secret.
-
- - ### `postgraphile_owner-connection`
-
- The GraphQL API's database owner URI.
-
- - ### `postgres-backup_db` 
-
- The database's name.
-
- - ### `postgres_db`
-
- The database's name.
-
- - ### `postgres_password`
-
- The database's password.
-
- - ### `postgres_role_service_grafana_password`
-
- The password of the observation dashboard's database role.
-
- - ### `postgres_role_service_grafana_username`
-
- The username of the observation dashboard's database role.
-
- - ### `postgres_role_service_postgraphile_password`
-
- The password of the GraphQL API database wrapper's database role.
-
- - ### `postgres_role_service_postgraphile_username`
-
- The username of the GraphQL API database wrapper's database role.
-
- - ### `postgres_role_service_vibetype_password`
-
- The `tusd` database role's password.
-
- - ### `postgres_role_service_vibetype_username`
-
- The `tusd` database role's password.
-
- - ### `postgres_role_service_zammad_password`
-
- The password of the customer service database role.
-
- - ### `postgres_role_service_zammad_username`
-
- The username of the customer service database role.
-
- - ### `postgres_user`
-
- The database's default user.
-
- - ### `reccoom_ingest-api-key`
-
- The AI provider's API key for the recommendation engine.
-
- - ### `reccoom_openai-api-key`
-
- The AI provider's API key for the recommendation engine.
-
- - ### `sqitch_target`
-
- The database change management application's database connection string.
-
- - ### `traefik_cf-dns-api-token` 
-
- The DNS provider's DNS API token.
-
- - ### `traefik_cf-zone-api-token` 
-
- The DNS provider's zone API token.
-
- - ### `tusd_aws`
-
- The upload service's s3 credentials file.
-
- - ### `vibetype_api-notification-secret`
-
- The notification endpoint's secret.
-
- - ### `vibetype_aws-credentials`
-
- The cloud computing provider's user credentials.
-
- - ### `vibetype_firebase-service-account-credentials`
-
- The notification provider's service account credentials.
-
- - ### `vibetype_monday`
-
- The project management software's configuration.
-
- - ### `vibetype_openai-api-key`
-
- The AI provider's API key for the frontend.
-
- - ### `vibetype_turnstile-key`
-
- The captcha provider's application key.
-
-
-## services
-
-
- - ### `adminer`
-
- You can access the database's frontend at [adminer.app.localhost](https://adminer.app.localhost/).
- This information is required for login:
-
- | | |
- | -------- | ------------------- |
- | System | PostgreSQL |
- | Server | postgres |
- | Username | [postgres_user] |
- | Password | [postgres_password] |
- | Database | [postgres_db] |
-
- Values in square brackets are [Docker secrets](https://docs.docker.com/engine/swarm/secrets/).
-
- - ### `cloudflared` 
-
- You can configure the secure tunnel at [dash.cloudflare.com](https://dash.cloudflare.com/).
-
- - ### `debezium`
-
- You can see how changes in the database end up in the event stream using `redpanda-console`.
-
- - ### `debezium-postgres-connector`
-
- You can check the database connector's setup logs using `portainer`.
-
- - ### `elasticsearch`
-
- You cannot access the search engine via a web interface.
-
- - ### `geoip`
-
- You cannot access the ip geolocator via a web interface.
-
- - ### `grafana`
-
- You can access the observation dashboard at [grafana.app.localhost](https://grafana.app.localhost/).
-
- - ### `jobber`
-
- You cannot access the jobber via a web interface.
-
- - ### `memcached`
-
- You cannot access the caching system via a web interface.
-
- - ### `minio` 
-
- You can access the s3 console at [minio.app.localhost](https://minio.app.localhost/).
- You can access the s3 api service at [s3.app.localhost](https://s3.app.localhost/) if you want to access via cli from outside the stack.
-
- - ### `portainer`
-
- You can access the container manager's frontend at [portainer.app.localhost](https://portainer.app.localhost/).
-
- - ### `portainer-agent`
-
- You cannot access the container manager's agent directly.
-
- - ### `postgraphile`
-
- You can access the GraphQL API for the PostgreSQL database at [postgraphile.app.localhost](https://postgraphile.app.localhost/).
-
- - ### `postgres`
-
- You can access the database via `adminer`.
-
- - ### `postgres_backup` 
-
- You cannot access the database backup directly.
-
- - ### `prometheus`
-
- You can access the metrics monitoring at [prometheus.app.localhost](https://prometheus.app.localhost/).
-
- - ### `reccoom`
-
- You cannot access the recommendation service directly.
-
- - ### `reccoom_postgres`
-
- You can access reccoom's database via `adminer`.
-
- - ### `redis`
-
- You cannot access the caching system via a web interface.
-
- - ### `redpanda`
-
- You can access the event streaming platform's ui as described under `redpanda-console`.
-
- - ### `redpanda-console`
-
- You can access the event streaming platform's ui at [redpanda.app.localhost](https://redpanda.app.localhost/).
-
- - ### `sqitch`
-
- You cannot access the database migrations directly.
-
- - ### `traefik`
-
- You can access the reverse proxy's dashboard at [traefik.app.localhost](https://traefik.app.localhost/).
-
- - ### `traefik_certs-dumper` 
-
- You cannot access the reverse proxy's certificate helper directly.
-
- - ### `tusd`
-
- You can access the upload service at [tusd.app.localhost](https://tusd.app.localhost/).
-
- - ### `vibetype`
-
- You can access the main project's frontend at [app.localhost](https://app.localhost/).
-
- - ### `zammad-backup`
-
- You cannot access the helpdesk backup service via a web interface.
-
- - ### `zammad-init`
-
- You cannot access the helpdesk initialization service via a web interface.
-
- - ### `zammad-nginx`
-
- You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
-
- - ### `zammad-railsserver`
-
- You cannot access the helpdesk application server directly.
-
- - ### `zammad-scheduler`
-
- You cannot access the helpdesk scheduler directly.
-
- - ### `zammad-websocket`
-
- You cannot access the helpdesk websocket server directly.
-
-
-## volumes
-
-
- - ### `acme_data` 
-
- The reverse proxy's certificate data.
-
- - ### `debezium_kafka_configuration`
-
- The change data capture's configuration.
-
- - ### `debezium_kafka_data`
-
- The change data capture's data.
-
- - ### `debezium_kafka_logs`
-
- The change data capture's logs.
-
- - ### `elasticsearch-configuration`
-
- The search engine's configuration.
-
- - ### `elasticsearch_data`
-
- The search engine's data.
-
- - ### `grafana_data`
-
- The observation dashboard's data.
-
- - ### `minio_data`
-
- The s3 server's data.
-
- - ### `pnpm_data`
-
- The node package manager's data.
-
- - ### `portainer_data`
-
- The container manager's data.
-
- - ### `postgraphile_data`
-
- The GraphQL API's data.
-
- - ### `postgres_data`
-
- The database's data.
-
- - ### `prometheus_data`
-
- The metrics monitoring's data.
-
- - ### `reccoom_postgres_data`
-
- The recommendation database's data.
-
- - ### `redis_data`
-
- The caching system's data.
-
- - ### `redpanda_data`
-
- The message queue's data.
-
- - ### `vibetype_data`
-
- The frontend's data.
-
- - ### `zammad-backup_data`
-
- The helpdesk backup's data.
-
- - ### `zammad_data`
-
- The helpdesk's data.
-
-
diff --git a/artifacts/.gitignore b/artifacts/.gitignore
new file mode 100644
index 00000000..87bd3818
--- /dev/null
+++ b/artifacts/.gitignore
@@ -0,0 +1,4 @@
+audit-log/
+certificates/
+secrets/
+.env.merged
\ No newline at end of file
diff --git a/artifacts/docs/README.md b/artifacts/docs/README.md
new file mode 100644
index 00000000..984f0154
--- /dev/null
+++ b/artifacts/docs/README.md
@@ -0,0 +1,172 @@
+# vibetype
+
+The Docker stack configuration for [vibetype.app](https://vibetype.app/).
+
+## Profiles
+
+### analytics
+
+Services: grafana, prometheus
+
+### default
+
+Services: adminer, cloudflared, portainer, portainer-agent, postgraphile, postgres, sqitch, traefik, vibetype
+
+### event-streaming
+
+Services: debezium, debezium-postgres-connector, redpanda, redpanda-console
+
+### recommendation
+
+Services: reccoom, reccoom_postgres
+
+### upload
+
+Services: minio, tusd
+
+### zammad
+
+Services: elasticsearch, memcached, redis, zammad-backup, zammad-init, zammad-nginx, zammad-railsserver, zammad-scheduler, zammad-websocket
+
+## Services
+
+### adminer
+
+You can access the database's frontend at [adminer.app.localhost](https://adminer.app.localhost/).
+This information is required for login:
+
+| | |
+| -------- | ------------------- |
+| System | PostgreSQL |
+| Server | postgres |
+| Username | [postgres-user] |
+| Password | [postgres-password] |
+| Database | [postgres-db] |
+
+Values in square brackets are [Docker secrets](https://docs.docker.com/engine/swarm/secrets/).
+
+### cloudflared *(production only)*
+
+You can configure the secure tunnel at [dash.cloudflare.com](https://dash.cloudflare.com/).
+
+### debezium
+
+You can see how changes in the database end up in the event stream using `redpanda-console`.
+
+### debezium-postgres-connector
+
+You can check the database connector's setup logs using `portainer`.
+
+### elasticsearch
+
+You cannot access the search engine via a web interface.
+
+### geoip
+
+You cannot access the ip geolocator via a web interface.
+
+### grafana
+
+You can access the observation dashboard at [grafana.app.localhost](https://grafana.app.localhost/).
+
+### jobber
+
+You cannot access the jobber via a web interface.
+
+### memcached
+
+You cannot access the caching system via a web interface.
+
+### minio
+
+You can access the s3 console at [minio.app.localhost](https://minio.app.localhost/).
+You can access the s3 api service at [s3.app.localhost](https://s3.app.localhost/) if you want to access via cli from outside the stack.
+
+### portainer
+
+You can access the container manager's frontend at [portainer.app.localhost](https://portainer.app.localhost/).
+
+### portainer-agent
+
+You cannot access the container manager's agent directly.
+
+### postgraphile
+
+You can access the GraphQL API for the PostgreSQL database at [postgraphile.app.localhost](https://postgraphile.app.localhost/).
+
+### postgres
+
+You can access the database via `adminer`.
+
+### postgres-backup *(production only)*
+
+You cannot access the database backup directly.
+
+### prometheus
+
+You can access the metrics monitoring at [prometheus.app.localhost](https://prometheus.app.localhost/).
+
+### reccoom
+
+You cannot access the recommendation service directly.
+
+### reccoom_postgres
+
+You can access reccoom's database via `adminer`.
+
+### redis
+
+You cannot access the caching system via a web interface.
+
+### redpanda
+
+You can access the event streaming platform's ui as described under `redpanda-console`.
+
+### redpanda-console
+
+You can access the event streaming platform's ui at [redpanda.app.localhost](https://redpanda.app.localhost/).
+
+### sqitch
+
+You cannot access the database migrations directly.
+
+### traefik
+
+You can access the reverse proxy's dashboard at [traefik.app.localhost](https://traefik.app.localhost/).
+
+### traefik-certs-dumper *(production only)*
+
+You cannot access the reverse proxy's certificate helper directly.
+
+### tusd
+
+You can access the upload service at [tusd.app.localhost](https://tusd.app.localhost/).
+
+### vibetype
+
+You can access the main project's frontend at [app.localhost](https://app.localhost/).
+
+### zammad-backup
+
+You cannot access the helpdesk backup service via a web interface.
+
+### zammad-init
+
+You cannot access the helpdesk initialization service via a web interface.
+
+### zammad-nginx
+
+You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
+
+### zammad-railsserver
+
+You cannot access the helpdesk application server directly.
+
+### zammad-scheduler
+
+You cannot access the helpdesk scheduler directly.
+
+### zammad-websocket
+
+You cannot access the helpdesk websocket server directly.
+
diff --git a/NOTES.md b/artifacts/docs/SERVICES_ADDITIONAL.md
similarity index 91%
rename from NOTES.md
rename to artifacts/docs/SERVICES_ADDITIONAL.md
index ce1846d5..3ac38388 100644
--- a/NOTES.md
+++ b/artifacts/docs/SERVICES_ADDITIONAL.md
@@ -1,4 +1,5 @@
# Additional Services
+
- ## `status`  [](https://www.statuscake.com)
- You can access the status dashboard at [status.vibetype.app](https://status.vibetype.app/)
\ No newline at end of file
+ You can access the status dashboard at [status.vibetype.app](https://status.vibetype.app/)
diff --git a/dargstack.env b/dargstack.env
deleted file mode 100644
index aff39cd0..00000000
--- a/dargstack.env
+++ /dev/null
@@ -1 +0,0 @@
-PROJECT_NAME=vibetype
\ No newline at end of file
diff --git a/dargstack.yaml b/dargstack.yaml
new file mode 100644
index 00000000..dd68f610
--- /dev/null
+++ b/dargstack.yaml
@@ -0,0 +1,47 @@
+# Dargstack configuration file
+
+# # Stack name — used as Docker stack name and image tag prefix
+name: "vibetype"
+
+# # Source code metadata (for documentation generation)
+# source:
+# name: "example"
+# url: "https://github.com/example/example"
+
+#####
+
+# Version: This CLI is compatible with config versions < 1.0.0
+compatibility: ">=4.0.0-0 <5.0.0"
+
+# Sudo mode — if Docker requires sudo on this machine, set to "always"
+# Options: "always", "never", "auto" (default)
+sudo: "auto"
+
+# Behavior configuration
+behavior:
+ build:
+ # Skip rebuilding images if they already exist
+ skip: true
+ prompt:
+ volume:
+ # Prompt to remove volumes before deploying (development only)
+ remove: false # default: true
+
+# Production environment settings
+production:
+ # Stack domain — used by the public to reach the services
+ domain: "vibetype.app"
+ # Git branch for production deployments
+ branch: "main"
+ # Tag strategy for production — use "latest" to auto-detect from git tags
+ tag: "latest"
+
+# Development environment settings
+development:
+ # Domain used for development deployments (defaults to "app.localhost").
+ domain: "app.localhost"
+ certificate:
+ # Additional domains for development TLS certificates (beyond the auto-discovered ones).
+ domains: []
+ # - "*.app.localhost"
+ # - "custom.localhost"
\ No newline at end of file
diff --git a/package.json b/package.json
deleted file mode 100644
index 6ab49f14..00000000
--- a/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "author": "Jonas Thelemann ",
- "description": "Dargstack configuration for Vibetype.",
- "devDependencies": {
- "@commitlint/cli": "20.4.3",
- "@commitlint/config-conventional": "20.4.3",
- "conventional-changelog-conventionalcommits": "9.3.0",
- "dargstack": "3.0.0",
- "dargstack_rgen": "0.9.86",
- "husky": "9.1.7"
- },
- "engines": {
- "node": "24"
- },
- "license": "GPL-3.0-only",
- "name": "@maevsi/stack",
- "packageManager": "pnpm@10.30.3",
- "private": true,
- "repository": "https://github.com/maevsi/stack.git",
- "scripts": {
- "prepare": "husky && ./src/development/certificates/mkcert.sh"
- },
- "type": "module",
- "version": "17.0.0-beta.4"
-}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
deleted file mode 100644
index 7d4e1034..00000000
--- a/pnpm-lock.yaml
+++ /dev/null
@@ -1,837 +0,0 @@
-lockfileVersion: '9.0'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-importers:
-
- .:
- devDependencies:
- '@commitlint/cli':
- specifier: 20.4.3
- version: 20.4.3(@types/node@25.3.5)(typescript@5.9.3)
- '@commitlint/config-conventional':
- specifier: 20.4.3
- version: 20.4.3
- conventional-changelog-conventionalcommits:
- specifier: 9.3.0
- version: 9.3.0
- dargstack:
- specifier: 3.0.0
- version: 3.0.0
- dargstack_rgen:
- specifier: 0.9.86
- version: 0.9.86
- husky:
- specifier: 9.1.7
- version: 9.1.7
-
-packages:
-
- '@babel/code-frame@7.29.0':
- resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-validator-identifier@7.28.5':
- resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
- engines: {node: '>=6.9.0'}
-
- '@commitlint/cli@20.4.3':
- resolution: {integrity: sha512-Z37EMoDT7+Upg500vlr/vZrgRsb6Xc5JAA3Tv7BYbobnN/ZpqUeZnSLggBg2+1O+NptRDtyujr2DD1CPV2qwhA==}
- engines: {node: '>=v18'}
- hasBin: true
-
- '@commitlint/config-conventional@20.4.3':
- resolution: {integrity: sha512-9RtLySbYQAs8yEqWEqhSZo9nYhbm57jx7qHXtgRmv/nmeQIjjMcwf6Dl+y5UZcGWgWx435TAYBURONaJIuCjWg==}
- engines: {node: '>=v18'}
-
- '@commitlint/config-validator@20.4.3':
- resolution: {integrity: sha512-jCZpZFkcSL3ZEdL5zgUzFRdytv3xPo8iukTe9VA+QGus/BGhpp1xXSVu2B006GLLb2gYUAEGEqv64kTlpZNgmA==}
- engines: {node: '>=v18'}
-
- '@commitlint/ensure@20.4.3':
- resolution: {integrity: sha512-WcXGKBNn0wBKpX8VlXgxqedyrLxedIlLBCMvdamLnJFEbUGJ9JZmBVx4vhLV3ZyA8uONGOb+CzW0Y9HDbQ+ONQ==}
- engines: {node: '>=v18'}
-
- '@commitlint/execute-rule@20.0.0':
- resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==}
- engines: {node: '>=v18'}
-
- '@commitlint/format@20.4.3':
- resolution: {integrity: sha512-UDJVErjLbNghop6j111rsHJYGw6MjCKAi95K0GT2yf4eeiDHy3JDRLWYWEjIaFgO+r+dQSkuqgJ1CdMTtrvHsA==}
- engines: {node: '>=v18'}
-
- '@commitlint/is-ignored@20.4.3':
- resolution: {integrity: sha512-W5VQKZ7fdJ1X3Tko+h87YZaqRMGN1KvQKXyCM8xFdxzMIf1KCZgN4uLz3osLB1zsFcVS4ZswHY64LI26/9ACag==}
- engines: {node: '>=v18'}
-
- '@commitlint/lint@20.4.3':
- resolution: {integrity: sha512-CYOXL23e+nRKij81+d0+dymtIi7Owl9QzvblJYbEfInON/4MaETNSLFDI74LDu+YJ0ML5HZyw9Vhp9QpckwQ0A==}
- engines: {node: '>=v18'}
-
- '@commitlint/load@20.4.3':
- resolution: {integrity: sha512-3cdJOUVP+VcgHa7bhJoWS+Z8mBNXB5aLWMBu7Q7uX8PSeWDzdbrBlR33J1MGGf7r1PZDp+mPPiFktk031PgdRw==}
- engines: {node: '>=v18'}
-
- '@commitlint/message@20.4.3':
- resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==}
- engines: {node: '>=v18'}
-
- '@commitlint/parse@20.4.3':
- resolution: {integrity: sha512-hzC3JCo3zs3VkQ833KnGVuWjWIzR72BWZWjQM7tY/7dfKreKAm7fEsy71tIFCRtxf2RtMP2d3RLF1U9yhFSccA==}
- engines: {node: '>=v18'}
-
- '@commitlint/read@20.4.3':
- resolution: {integrity: sha512-j42OWv3L31WfnP8WquVjHZRt03w50Y/gEE8FAyih7GQTrIv2+pZ6VZ6pWLD/ml/3PO+RV2SPtRtTp/MvlTb8rQ==}
- engines: {node: '>=v18'}
-
- '@commitlint/resolve-extends@20.4.3':
- resolution: {integrity: sha512-QucxcOy+00FhS9s4Uy0OyS5HeUV+hbC6OLqkTSIm6fwMdKva+OEavaCDuLtgd9akZZlsUo//XzSmPP3sLKBPog==}
- engines: {node: '>=v18'}
-
- '@commitlint/rules@20.4.3':
- resolution: {integrity: sha512-Yuosd7Grn5qiT7FovngXLyRXTMUbj9PYiSkvUgWK1B5a7+ZvrbWDS7epeUapYNYatCy/KTpPFPbgLUdE+MUrBg==}
- engines: {node: '>=v18'}
-
- '@commitlint/to-lines@20.0.0':
- resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==}
- engines: {node: '>=v18'}
-
- '@commitlint/top-level@20.4.3':
- resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==}
- engines: {node: '>=v18'}
-
- '@commitlint/types@20.4.3':
- resolution: {integrity: sha512-51OWa1Gi6ODOasPmfJPq6js4pZoomima4XLZZCrkldaH2V5Nb3bVhNXPeT6XV0gubbainSpTw4zi68NqAeCNCg==}
- engines: {node: '>=v18'}
-
- '@simple-libs/stream-utils@1.2.0':
- resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==}
- engines: {node: '>=18'}
-
- '@types/node@25.3.5':
- resolution: {integrity: sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==}
-
- ajv@8.18.0:
- resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
-
- ansi-regex@5.0.1:
- resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
- engines: {node: '>=8'}
-
- ansi-regex@6.2.2:
- resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
- engines: {node: '>=12'}
-
- ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
-
- ansi-styles@6.2.3:
- resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
- engines: {node: '>=12'}
-
- argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
-
- array-ify@1.0.0:
- resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
-
- callsites@3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
- engines: {node: '>=6'}
-
- cliui@8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
-
- cliui@9.0.1:
- resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==}
- engines: {node: '>=20'}
-
- color-convert@2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
-
- color-name@1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-
- compare-func@2.0.0:
- resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
-
- conventional-changelog-angular@8.3.0:
- resolution: {integrity: sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==}
- engines: {node: '>=18'}
-
- conventional-changelog-conventionalcommits@9.3.0:
- resolution: {integrity: sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==}
- engines: {node: '>=18'}
-
- conventional-commits-parser@6.3.0:
- resolution: {integrity: sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==}
- engines: {node: '>=18'}
- hasBin: true
-
- cosmiconfig-typescript-loader@6.2.0:
- resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==}
- engines: {node: '>=v18'}
- peerDependencies:
- '@types/node': '*'
- cosmiconfig: '>=9'
- typescript: '>=5'
-
- cosmiconfig@9.0.1:
- resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==}
- engines: {node: '>=14'}
- peerDependencies:
- typescript: '>=4.9.5'
- peerDependenciesMeta:
- typescript:
- optional: true
-
- dargs@8.1.0:
- resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
- engines: {node: '>=12'}
-
- dargstack@3.0.0:
- resolution: {integrity: sha512-hJn6NSEDiDvkH+3THlnLGHyvxagrm+t7f1snRSNER0u5A+manl2Wy1A7oFq6tWGtBIj0DDVoT0llpMlh8R9xQw==}
- engines: {node: '24'}
-
- dargstack_rgen@0.9.86:
- resolution: {integrity: sha512-3pwqv3r7BqaSu8LWYyzA8S5OP4EAxBHXhAEHywEGPXiSbl9j17KAhGHIUaFmGX5GPeUWF0B+N5Uh5nmlMkD/Vg==}
- engines: {node: '24'}
- hasBin: true
-
- deepmerge@4.3.1:
- resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
- engines: {node: '>=0.10.0'}
-
- diff@8.0.3:
- resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
- engines: {node: '>=0.3.1'}
-
- dot-prop@5.3.0:
- resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
- engines: {node: '>=8'}
-
- emoji-regex@10.6.0:
- resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
-
- emoji-regex@8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
-
- env-paths@2.2.1:
- resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
- engines: {node: '>=6'}
-
- error-ex@1.3.4:
- resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
-
- escalade@3.2.0:
- resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
- engines: {node: '>=6'}
-
- fast-deep-equal@3.1.3:
- resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
-
- fast-uri@3.1.0:
- resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
-
- get-caller-file@2.0.5:
- resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
- engines: {node: 6.* || 8.* || >= 10.*}
-
- get-east-asian-width@1.5.0:
- resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==}
- engines: {node: '>=18'}
-
- git-raw-commits@4.0.0:
- resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==}
- engines: {node: '>=16'}
- deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.
- hasBin: true
-
- global-directory@4.0.1:
- resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
- engines: {node: '>=18'}
-
- husky@9.1.7:
- resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
- engines: {node: '>=18'}
- hasBin: true
-
- import-fresh@3.3.1:
- resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
- engines: {node: '>=6'}
-
- import-meta-resolve@4.2.0:
- resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==}
-
- indento@1.1.14:
- resolution: {integrity: sha512-K4cK97v4M/ucCAbe3LUpg994folYL0WnEiCFxHXAIowKLbBb/Ahiazkz3Ao5gRar4i9pDr3imcpq4suOu0FbNw==}
-
- ini@4.1.1:
- resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
-
- is-arrayish@0.2.1:
- resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
-
- is-fullwidth-code-point@3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
-
- is-obj@2.0.0:
- resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
- engines: {node: '>=8'}
-
- is-plain-obj@4.1.0:
- resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
- engines: {node: '>=12'}
-
- jiti@2.6.1:
- resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
- hasBin: true
-
- js-tokens@4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
-
- js-yaml@4.1.1:
- resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
- hasBin: true
-
- json-parse-even-better-errors@2.3.1:
- resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
-
- json-schema-traverse@1.0.0:
- resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
-
- json2md@2.0.3:
- resolution: {integrity: sha512-ZPzh6Djvqz8grJMxKllfCHo0p+p7BsbZ1J95KcCJgvvfdoy7myuKrrkUp80Kpy+wGauykC0dYljLqLY0kENaOw==}
-
- lines-and-columns@1.2.4:
- resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
-
- lodash.camelcase@4.3.0:
- resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
-
- lodash.kebabcase@4.1.1:
- resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
-
- lodash.mergewith@4.6.2:
- resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
-
- lodash.snakecase@4.1.1:
- resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
-
- lodash.startcase@4.4.0:
- resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
-
- lodash.upperfirst@4.3.1:
- resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==}
-
- meow@12.1.1:
- resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==}
- engines: {node: '>=16.10'}
-
- meow@13.2.0:
- resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
- engines: {node: '>=18'}
-
- minimist@1.2.8:
- resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
-
- parent-module@1.0.1:
- resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
- engines: {node: '>=6'}
-
- parse-json@5.2.0:
- resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
- engines: {node: '>=8'}
-
- picocolors@1.1.1:
- resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
-
- require-directory@2.1.1:
- resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
- engines: {node: '>=0.10.0'}
-
- require-from-string@2.0.2:
- resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
- engines: {node: '>=0.10.0'}
-
- resolve-from@4.0.0:
- resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
- engines: {node: '>=4'}
-
- resolve-from@5.0.0:
- resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
- engines: {node: '>=8'}
-
- semver@7.7.4:
- resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
- engines: {node: '>=10'}
- hasBin: true
-
- split2@4.2.0:
- resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
- engines: {node: '>= 10.x'}
-
- string-width@4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
-
- string-width@7.2.0:
- resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
- engines: {node: '>=18'}
-
- strip-ansi@6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
-
- strip-ansi@7.2.0:
- resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
- engines: {node: '>=12'}
-
- tinyexec@1.0.2:
- resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
- engines: {node: '>=18'}
-
- typescript@5.9.3:
- resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
- engines: {node: '>=14.17'}
- hasBin: true
-
- undici-types@7.18.2:
- resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
-
- wrap-ansi@7.0.0:
- resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
- engines: {node: '>=10'}
-
- wrap-ansi@9.0.2:
- resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
- engines: {node: '>=18'}
-
- y18n@5.0.8:
- resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
- engines: {node: '>=10'}
-
- yaml@2.8.2:
- resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
- engines: {node: '>= 14.6'}
- hasBin: true
-
- yargs-parser@21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
-
- yargs-parser@22.0.0:
- resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
- engines: {node: ^20.19.0 || ^22.12.0 || >=23}
-
- yargs@17.7.2:
- resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
- engines: {node: '>=12'}
-
- yargs@18.0.0:
- resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==}
- engines: {node: ^20.19.0 || ^22.12.0 || >=23}
-
-snapshots:
-
- '@babel/code-frame@7.29.0':
- dependencies:
- '@babel/helper-validator-identifier': 7.28.5
- js-tokens: 4.0.0
- picocolors: 1.1.1
-
- '@babel/helper-validator-identifier@7.28.5': {}
-
- '@commitlint/cli@20.4.3(@types/node@25.3.5)(typescript@5.9.3)':
- dependencies:
- '@commitlint/format': 20.4.3
- '@commitlint/lint': 20.4.3
- '@commitlint/load': 20.4.3(@types/node@25.3.5)(typescript@5.9.3)
- '@commitlint/read': 20.4.3
- '@commitlint/types': 20.4.3
- tinyexec: 1.0.2
- yargs: 17.7.2
- transitivePeerDependencies:
- - '@types/node'
- - typescript
-
- '@commitlint/config-conventional@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- conventional-changelog-conventionalcommits: 9.3.0
-
- '@commitlint/config-validator@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- ajv: 8.18.0
-
- '@commitlint/ensure@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- lodash.camelcase: 4.3.0
- lodash.kebabcase: 4.1.1
- lodash.snakecase: 4.1.1
- lodash.startcase: 4.4.0
- lodash.upperfirst: 4.3.1
-
- '@commitlint/execute-rule@20.0.0': {}
-
- '@commitlint/format@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- picocolors: 1.1.1
-
- '@commitlint/is-ignored@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- semver: 7.7.4
-
- '@commitlint/lint@20.4.3':
- dependencies:
- '@commitlint/is-ignored': 20.4.3
- '@commitlint/parse': 20.4.3
- '@commitlint/rules': 20.4.3
- '@commitlint/types': 20.4.3
-
- '@commitlint/load@20.4.3(@types/node@25.3.5)(typescript@5.9.3)':
- dependencies:
- '@commitlint/config-validator': 20.4.3
- '@commitlint/execute-rule': 20.0.0
- '@commitlint/resolve-extends': 20.4.3
- '@commitlint/types': 20.4.3
- cosmiconfig: 9.0.1(typescript@5.9.3)
- cosmiconfig-typescript-loader: 6.2.0(@types/node@25.3.5)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3)
- is-plain-obj: 4.1.0
- lodash.mergewith: 4.6.2
- picocolors: 1.1.1
- transitivePeerDependencies:
- - '@types/node'
- - typescript
-
- '@commitlint/message@20.4.3': {}
-
- '@commitlint/parse@20.4.3':
- dependencies:
- '@commitlint/types': 20.4.3
- conventional-changelog-angular: 8.3.0
- conventional-commits-parser: 6.3.0
-
- '@commitlint/read@20.4.3':
- dependencies:
- '@commitlint/top-level': 20.4.3
- '@commitlint/types': 20.4.3
- git-raw-commits: 4.0.0
- minimist: 1.2.8
- tinyexec: 1.0.2
-
- '@commitlint/resolve-extends@20.4.3':
- dependencies:
- '@commitlint/config-validator': 20.4.3
- '@commitlint/types': 20.4.3
- global-directory: 4.0.1
- import-meta-resolve: 4.2.0
- lodash.mergewith: 4.6.2
- resolve-from: 5.0.0
-
- '@commitlint/rules@20.4.3':
- dependencies:
- '@commitlint/ensure': 20.4.3
- '@commitlint/message': 20.4.3
- '@commitlint/to-lines': 20.0.0
- '@commitlint/types': 20.4.3
-
- '@commitlint/to-lines@20.0.0': {}
-
- '@commitlint/top-level@20.4.3':
- dependencies:
- escalade: 3.2.0
-
- '@commitlint/types@20.4.3':
- dependencies:
- conventional-commits-parser: 6.3.0
- picocolors: 1.1.1
-
- '@simple-libs/stream-utils@1.2.0': {}
-
- '@types/node@25.3.5':
- dependencies:
- undici-types: 7.18.2
-
- ajv@8.18.0:
- dependencies:
- fast-deep-equal: 3.1.3
- fast-uri: 3.1.0
- json-schema-traverse: 1.0.0
- require-from-string: 2.0.2
-
- ansi-regex@5.0.1: {}
-
- ansi-regex@6.2.2: {}
-
- ansi-styles@4.3.0:
- dependencies:
- color-convert: 2.0.1
-
- ansi-styles@6.2.3: {}
-
- argparse@2.0.1: {}
-
- array-ify@1.0.0: {}
-
- callsites@3.1.0: {}
-
- cliui@8.0.1:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
-
- cliui@9.0.1:
- dependencies:
- string-width: 7.2.0
- strip-ansi: 7.2.0
- wrap-ansi: 9.0.2
-
- color-convert@2.0.1:
- dependencies:
- color-name: 1.1.4
-
- color-name@1.1.4: {}
-
- compare-func@2.0.0:
- dependencies:
- array-ify: 1.0.0
- dot-prop: 5.3.0
-
- conventional-changelog-angular@8.3.0:
- dependencies:
- compare-func: 2.0.0
-
- conventional-changelog-conventionalcommits@9.3.0:
- dependencies:
- compare-func: 2.0.0
-
- conventional-commits-parser@6.3.0:
- dependencies:
- '@simple-libs/stream-utils': 1.2.0
- meow: 13.2.0
-
- cosmiconfig-typescript-loader@6.2.0(@types/node@25.3.5)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3):
- dependencies:
- '@types/node': 25.3.5
- cosmiconfig: 9.0.1(typescript@5.9.3)
- jiti: 2.6.1
- typescript: 5.9.3
-
- cosmiconfig@9.0.1(typescript@5.9.3):
- dependencies:
- env-paths: 2.2.1
- import-fresh: 3.3.1
- js-yaml: 4.1.1
- parse-json: 5.2.0
- optionalDependencies:
- typescript: 5.9.3
-
- dargs@8.1.0: {}
-
- dargstack@3.0.0: {}
-
- dargstack_rgen@0.9.86:
- dependencies:
- deepmerge: 4.3.1
- diff: 8.0.3
- json2md: 2.0.3
- yaml: 2.8.2
- yargs: 18.0.0
-
- deepmerge@4.3.1: {}
-
- diff@8.0.3: {}
-
- dot-prop@5.3.0:
- dependencies:
- is-obj: 2.0.0
-
- emoji-regex@10.6.0: {}
-
- emoji-regex@8.0.0: {}
-
- env-paths@2.2.1: {}
-
- error-ex@1.3.4:
- dependencies:
- is-arrayish: 0.2.1
-
- escalade@3.2.0: {}
-
- fast-deep-equal@3.1.3: {}
-
- fast-uri@3.1.0: {}
-
- get-caller-file@2.0.5: {}
-
- get-east-asian-width@1.5.0: {}
-
- git-raw-commits@4.0.0:
- dependencies:
- dargs: 8.1.0
- meow: 12.1.1
- split2: 4.2.0
-
- global-directory@4.0.1:
- dependencies:
- ini: 4.1.1
-
- husky@9.1.7: {}
-
- import-fresh@3.3.1:
- dependencies:
- parent-module: 1.0.1
- resolve-from: 4.0.0
-
- import-meta-resolve@4.2.0: {}
-
- indento@1.1.14: {}
-
- ini@4.1.1: {}
-
- is-arrayish@0.2.1: {}
-
- is-fullwidth-code-point@3.0.0: {}
-
- is-obj@2.0.0: {}
-
- is-plain-obj@4.1.0: {}
-
- jiti@2.6.1: {}
-
- js-tokens@4.0.0: {}
-
- js-yaml@4.1.1:
- dependencies:
- argparse: 2.0.1
-
- json-parse-even-better-errors@2.3.1: {}
-
- json-schema-traverse@1.0.0: {}
-
- json2md@2.0.3:
- dependencies:
- indento: 1.1.14
-
- lines-and-columns@1.2.4: {}
-
- lodash.camelcase@4.3.0: {}
-
- lodash.kebabcase@4.1.1: {}
-
- lodash.mergewith@4.6.2: {}
-
- lodash.snakecase@4.1.1: {}
-
- lodash.startcase@4.4.0: {}
-
- lodash.upperfirst@4.3.1: {}
-
- meow@12.1.1: {}
-
- meow@13.2.0: {}
-
- minimist@1.2.8: {}
-
- parent-module@1.0.1:
- dependencies:
- callsites: 3.1.0
-
- parse-json@5.2.0:
- dependencies:
- '@babel/code-frame': 7.29.0
- error-ex: 1.3.4
- json-parse-even-better-errors: 2.3.1
- lines-and-columns: 1.2.4
-
- picocolors@1.1.1: {}
-
- require-directory@2.1.1: {}
-
- require-from-string@2.0.2: {}
-
- resolve-from@4.0.0: {}
-
- resolve-from@5.0.0: {}
-
- semver@7.7.4: {}
-
- split2@4.2.0: {}
-
- string-width@4.2.3:
- dependencies:
- emoji-regex: 8.0.0
- is-fullwidth-code-point: 3.0.0
- strip-ansi: 6.0.1
-
- string-width@7.2.0:
- dependencies:
- emoji-regex: 10.6.0
- get-east-asian-width: 1.5.0
- strip-ansi: 7.2.0
-
- strip-ansi@6.0.1:
- dependencies:
- ansi-regex: 5.0.1
-
- strip-ansi@7.2.0:
- dependencies:
- ansi-regex: 6.2.2
-
- tinyexec@1.0.2: {}
-
- typescript@5.9.3: {}
-
- undici-types@7.18.2: {}
-
- wrap-ansi@7.0.0:
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
-
- wrap-ansi@9.0.2:
- dependencies:
- ansi-styles: 6.2.3
- string-width: 7.2.0
- strip-ansi: 7.2.0
-
- y18n@5.0.8: {}
-
- yaml@2.8.2: {}
-
- yargs-parser@21.1.1: {}
-
- yargs-parser@22.0.0: {}
-
- yargs@17.7.2:
- dependencies:
- cliui: 8.0.1
- escalade: 3.2.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 21.1.1
-
- yargs@18.0.0:
- dependencies:
- cliui: 9.0.1
- escalade: 3.2.0
- get-caller-file: 2.0.5
- string-width: 7.2.0
- y18n: 5.0.8
- yargs-parser: 22.0.0
diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644
index 71cda2dc..00000000
--- a/src/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-**/backups/*/**
-**/production/secrets/**/*.secret
-*.crt
-*.csr
-*.env
-*.key
-!**/README.md
-!**/*.template
-production/stack.yml
diff --git a/src/development/adminer/compose.yaml b/src/development/adminer/compose.yaml
new file mode 100644
index 00000000..8f9a6eee
--- /dev/null
+++ b/src/development/adminer/compose.yaml
@@ -0,0 +1,28 @@
+services:
+ adminer:
+ # You can access the database's frontend at [adminer.app.localhost](https://adminer.app.localhost/).
+ # This information is required for login:
+ #
+ # | | |
+ # | -------- | ------------------- |
+ # | System | PostgreSQL |
+ # | Server | postgres |
+ # | Username | [postgres-user] |
+ # | Password | [postgres-password] |
+ # | Database | [postgres-db] |
+ #
+ # Values in square brackets are [Docker secrets](https://docs.docker.com/engine/swarm/secrets/).
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ - traefik.enable=true
+ - traefik.http.routers.adminer.entryPoints=web
+ - traefik.http.routers.adminer.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.adminer.rule=Host(`adminer.${STACK_DOMAIN}`)
+ - traefik.http.routers.adminer-secure.entryPoints=web-secure
+ - traefik.http.routers.adminer-secure.rule=Host(`adminer.${STACK_DOMAIN}`)
+ - traefik.http.routers.adminer-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.adminer.loadbalancer.server.port=8080
+ image: adminer:5.4.2-standalone
+ volumes:
+ - ./configurations/adminer.css:/var/www/html/adminer.css:ro
diff --git a/src/development/adminer/configurations/adminer.css b/src/development/adminer/configurations/adminer.css
new file mode 100755
index 00000000..3da66c8c
--- /dev/null
+++ b/src/development/adminer/configurations/adminer.css
@@ -0,0 +1,7 @@
+a {
+ color: blue;
+}
+
+a:visited {
+ color: blue;
+}
diff --git a/src/development/certificates/mkcert.sh b/src/development/certificates/mkcert.sh
deleted file mode 100755
index 25c841c4..00000000
--- a/src/development/certificates/mkcert.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-THIS=$(dirname "$(readlink -f "$0")")
-
-create() {
- NAME="$1"
- shift
- CONTENT=$*
-
- path="$THIS/$NAME"
- certfile="$path.crt"
- keyfile="$path.key"
-
- if [ "$CONTENT" != "" ]; then
- # shellcheck disable=SC2086
- mkcert \
- -cert-file "$certfile" \
- -ecdsa \
- -key-file "$keyfile" $CONTENT
- fi
-
- cat "$(mkcert -CAROOT)/rootCA.pem" >> "$certfile"
-}
-
-echo "key crt" | tr ' ' '\n' | while read -r glob; do
- if test -n "$(find "$THIS" -maxdepth 1 -name "*.$glob" -print -quit)"; then
- rm "$THIS"/*."$glob"
- fi
-done
-
-create "root"
-create "traefik" \
- `# adminer` "adminer.app.localhost" \
- `# grafana` "grafana.app.localhost" \
- `# minio` "minio.app.localhost" \
- `# portainer` "portainer.app.localhost" \
- `# postgraphile` "postgraphile.app.localhost" \
- `# prometheus` "prometheus.app.localhost" \
- `# reccoom` "reccoom.app.localhost" \
- `# redpanda` "redpanda.app.localhost" \
- `# traefik` "traefik.app.localhost" \
- `# tusd` "tusd.app.localhost" \
- `# vibetype` "app.localhost" "www.app.localhost" "127.0.0.1" "0.0.0.0" \
- `# zammad` "zammad.app.localhost"
\ No newline at end of file
diff --git a/src/development/compose.yaml b/src/development/compose.yaml
new file mode 100644
index 00000000..38b1f0ed
--- /dev/null
+++ b/src/development/compose.yaml
@@ -0,0 +1,5 @@
+version: "3.7"
+volumes:
+ pnpm-data:
+ # The node package manager's data.
+ {}
diff --git a/src/development/configurations/postgraphile/jwtRS256.key.pub b/src/development/configurations/postgraphile/jwtRS256.key.pub
deleted file mode 100644
index 65de2425..00000000
--- a/src/development/configurations/postgraphile/jwtRS256.key.pub
+++ /dev/null
@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtBuHX2uH5GviLbocSUBK
-aRE4iKEjjEoB1eh7VQdBoKi1Wd+DNUilVyCtq0ootPSDR/8yOTa8W396Wu1xm07+
-xDAyFzsilIppu8DNcJo28Gb3PZCm4nXmITPkknVSKf80hosgauoe7itqDxgMASYT
-U8CgBH8zXPaowhqzjz0M/T9RqD1mRzMn3NEprDnaVAsh11r3DSandHjsnlgKCf1d
-lh4ixCZ6zUhtb0sT6GxuJaGjNVevLbPLuugMTu3d484FwbND+AmpAjIgdnX5lJQn
-eT7HxgnaiwLDazSwLM0jmiyEvnrmSPJZ2sgp87XS0VTVwMYk3M3RCy/3RiamJG5v
-7qZuVr4L87cXWvLHCwV5dGaPu0Dc3/75lcKcWy+BtBQUI+n+om1EitLtUo+lxE9a
-SyG6bhYQNu+XMRwY768TrzrvBwYt5JxoO9y3ybIFzoi/mufkp2NY7XB7CHfMcrn3
-XzCBbXJwt0Zlu2K1R8FPVN0SlsjtOVQun1al9cjC808hihjpiiGpKURoaFsxkh4B
-8n2Qli/fl5BQVAPClmFbsvToSzy+ENEDpXc53eve5Dhzx5SB/qe0DwlljDdc2W8n
-hozYHaOtnLnhG/TU9mmOliw5jmsHb5m1OMdBXMEhrGv4hkHJNg9+hCSJDzvbFRkN
-Y95lZj/fbtFrSHR5WwdsgI8CAwEAAQ==
------END PUBLIC KEY-----
diff --git a/src/development/configurations/traefik/dynamic.yml b/src/development/configurations/traefik/dynamic.yml
deleted file mode 100644
index 5fdce1e4..00000000
--- a/src/development/configurations/traefik/dynamic.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-tls:
- certificates:
- - certFile: /etc/traefik/acme/traefik.crt
- keyFile: /etc/traefik/acme/traefik.key
- options:
- mintls13:
- minVersion: VersionTLS13
\ No newline at end of file
diff --git a/src/development/debezium/compose.yaml b/src/development/debezium/compose.yaml
new file mode 100644
index 00000000..261a497b
--- /dev/null
+++ b/src/development/debezium/compose.yaml
@@ -0,0 +1,49 @@
+services:
+ debezium:
+ # You can see how changes in the database end up in the event stream using `redpanda-console`.
+ deploy:
+ labels:
+ - dargstack.profiles=event-streaming
+ environment:
+ BOOTSTRAP_SERVERS: redpanda:9092
+ CONFIG_STORAGE_TOPIC: connect_configs
+ GROUP_ID: 1
+ OFFSET_STORAGE_TOPIC: connect_offsets
+ STATUS_STORAGE_TOPIC: connect_statuses
+ # healthcheck:
+ # test: ["CMD", "curl", "--fail", "--silent", "--show-error", "http://localhost:8083/connectors"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 20s
+ image: quay.io/debezium/connect:3.5
+ volumes:
+ - debezium-kafka-configuration:/kafka/config
+ - debezium-kafka-data:/kafka/data
+ - debezium-kafka-logs:/kafka/logs
+ debezium-postgres-connector:
+ # You can check the database connector's setup logs using `portainer`.
+ command: /entrypoint.sh
+ deploy:
+ labels:
+ - dargstack.profiles=event-streaming
+ restart_policy:
+ condition: on-failure
+ entrypoint: sh
+ image: curlimages/curl:8.18.0
+ secrets:
+ - postgres-db
+ - postgres-password
+ - postgres-user
+ volumes:
+ - ./configurations/entrypoint.sh:/entrypoint.sh:ro
+volumes:
+ debezium-kafka-configuration:
+ # The change data capture's configuration.
+ {}
+ debezium-kafka-data:
+ # The change data capture's data.
+ {}
+ debezium-kafka-logs:
+ # The change data capture's logs.
+ {}
diff --git a/src/production/configurations/debezium-postgres-connector/entrypoint.sh b/src/development/debezium/configurations/entrypoint.sh
similarity index 91%
rename from src/production/configurations/debezium-postgres-connector/entrypoint.sh
rename to src/development/debezium/configurations/entrypoint.sh
index 5130d89f..66a731e2 100755
--- a/src/production/configurations/debezium-postgres-connector/entrypoint.sh
+++ b/src/development/debezium/configurations/entrypoint.sh
@@ -2,9 +2,9 @@
CONNECTOR_NAME="postgres-connector"
DEBEZIUM_URL="http://debezium:8083/connectors"
-POSTGRES_DB=$(cat /run/secrets/postgres_db)
-POSTGRES_PASSWORD=$(cat /run/secrets/postgres_password)
-POSTGRES_USER=$(cat /run/secrets/postgres_user)
+POSTGRES_DB=$(cat /run/secrets/postgres-db)
+POSTGRES_PASSWORD=$(cat /run/secrets/postgres-password)
+POSTGRES_USER=$(cat /run/secrets/postgres-user)
# Wait for Debezium to be healthy (REST API ready)
echo "Waiting for Debezium to be ready..."
diff --git a/src/development/elasticsearch/compose.yaml b/src/development/elasticsearch/compose.yaml
new file mode 100644
index 00000000..85bb290b
--- /dev/null
+++ b/src/development/elasticsearch/compose.yaml
@@ -0,0 +1,53 @@
+secrets:
+ elasticsearch-keystore-password:
+ # The search engine's password for the keystore.
+ file: ../../../artifacts/secrets/elasticsearch-keystore-password.secret
+ elasticsearch-password:
+ # The search engine's password for the default user.
+ file: ../../../artifacts/secrets/elasticsearch-password.secret
+services:
+ elasticsearch:
+ # You cannot access the search engine via a web interface.
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ environment:
+ bootstrap.memory_lock: "true"
+ discovery.type: single-node
+ ELASTIC_PASSWORD_FILE: /run/secrets/elasticsearch-password
+ ES_JAVA_OPTS: -Xms1g -Xmx1g
+ KEYSTORE_PASSWORD_FILE: /run/secrets/elasticsearch-keystore-password
+ network.publish_host: elasticsearch
+ image: elasticsearch:8.19.12
+ secrets:
+ - source: elasticsearch-keystore-password
+ uid: "1000"
+ gid: "1000"
+ mode: 0o400
+ - source: elasticsearch-password
+ uid: "1000"
+ gid: "1000"
+ mode: 0o400
+ ulimits:
+ nofile:
+ soft: 65535
+ hard: 65535
+ memlock:
+ soft: -1
+ hard: -1
+ volumes:
+ - elasticsearch-configuration:/usr/share/elasticsearch/config
+ - elasticsearch-data:/usr/share/elasticsearch/data
+volumes:
+ elasticsearch-configuration:
+ # The search engine's configuration.
+ {}
+ elasticsearch-data:
+ # The search engine's data.
+ {}
+x-dargstack:
+ secrets:
+ elasticsearch-keystore-password:
+ type: random_string
+ elasticsearch-password:
+ type: random_string
diff --git a/src/development/geoip/compose.yaml b/src/development/geoip/compose.yaml
new file mode 100644
index 00000000..a03531ab
--- /dev/null
+++ b/src/development/geoip/compose.yaml
@@ -0,0 +1,4 @@
+services:
+ geoip:
+ # You cannot access the ip geolocator via a web interface.
+ image: ghcr.io/observabilitystack/geoip-api:2026-02
diff --git a/src/development/grafana/compose.yaml b/src/development/grafana/compose.yaml
new file mode 100644
index 00000000..2086f442
--- /dev/null
+++ b/src/development/grafana/compose.yaml
@@ -0,0 +1,65 @@
+secrets:
+ grafana-admin-email:
+ # The observation dashboard's admin email.
+ file: ../../../artifacts/secrets/grafana-admin-email.secret
+ grafana-admin-password:
+ # The observation dashboard's admin password.
+ file: ../../../artifacts/secrets/grafana-admin-password.secret
+ grafana-admin-user:
+ # The observation dashboard's admin user.
+ file: ../../../artifacts/secrets/grafana-admin-user.secret
+ grafana-discord-webhook:
+ # The observation dashboard's contact point for Discord.
+ file: ../../../artifacts/secrets/grafana-discord-webhook.secret
+services:
+ grafana:
+ # You can access the observation dashboard at [grafana.app.localhost](https://grafana.app.localhost/).
+ deploy:
+ labels:
+ - dargstack.profiles=analytics
+ - traefik.enable=true
+ - traefik.http.routers.grafana.entryPoints=web
+ - traefik.http.routers.grafana.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.grafana.rule=Host(`grafana.${STACK_DOMAIN}`)
+ - traefik.http.routers.grafana-secure.entryPoints=web-secure
+ - traefik.http.routers.grafana-secure.rule=Host(`grafana.${STACK_DOMAIN}`)
+ - traefik.http.routers.grafana-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.grafana.loadbalancer.server.port=3000
+ environment:
+ GF_DATABASE_HOST: postgres:5432
+ GF_DATABASE_PASSWORD__FILE: /run/secrets/postgres-role-service-grafana-password
+ GF_DATABASE_TYPE: postgres
+ GF_DATABASE_USER__FILE: /run/secrets/postgres-role-service-grafana-username
+ GF_SECURITY_ADMIN_EMAIL__FILE: /run/secrets/grafana-admin-email
+ GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana-admin-password
+ GF_SECURITY_ADMIN_USER__FILE: /run/secrets/grafana-admin-user
+ GF_SERVER_ROOT_URL: https://grafana.${STACK_DOMAIN}/
+ image: grafana/grafana:12.4.1
+ secrets:
+ - grafana-admin-email
+ - grafana-admin-password
+ - grafana-admin-user
+ - grafana-discord-webhook
+ - postgres-db
+ - postgres-role-service-grafana-password
+ - postgres-role-service-grafana-username
+ volumes:
+ - ./configurations/dashboards:/var/lib/grafana/dashboards:ro
+ - ./configurations/provisioning:/etc/grafana/provisioning:ro
+ - grafana-data:/var/lib/grafana
+volumes:
+ grafana-data:
+ # The observation dashboard's data.
+ {}
+x-dargstack:
+ secrets:
+ grafana-admin-email:
+ insecure_default: admin@localhost
+ type: insecure_default
+ grafana-admin-password:
+ type: random_string
+ grafana-admin-user:
+ type: word
+ grafana-discord-webhook:
+ hint: https://discord.com/api/webhooks//
+ type: third_party
diff --git a/src/production/configurations/grafana/dashboards/Infrastructure/Advanced/grafana.json b/src/development/grafana/configurations/dashboards/Infrastructure/Advanced/grafana.json
similarity index 100%
rename from src/production/configurations/grafana/dashboards/Infrastructure/Advanced/grafana.json
rename to src/development/grafana/configurations/dashboards/Infrastructure/Advanced/grafana.json
diff --git a/src/production/configurations/grafana/dashboards/Infrastructure/Advanced/prometheus-2.0.json b/src/development/grafana/configurations/dashboards/Infrastructure/Advanced/prometheus-2.0.json
similarity index 100%
rename from src/production/configurations/grafana/dashboards/Infrastructure/Advanced/prometheus-2.0.json
rename to src/development/grafana/configurations/dashboards/Infrastructure/Advanced/prometheus-2.0.json
diff --git a/src/production/configurations/grafana/dashboards/Infrastructure/operations.json b/src/development/grafana/configurations/dashboards/Infrastructure/operations.json
similarity index 100%
rename from src/production/configurations/grafana/dashboards/Infrastructure/operations.json
rename to src/development/grafana/configurations/dashboards/Infrastructure/operations.json
diff --git a/src/production/configurations/grafana/dashboards/Infrastructure/redpanda.json b/src/development/grafana/configurations/dashboards/Infrastructure/redpanda.json
similarity index 100%
rename from src/production/configurations/grafana/dashboards/Infrastructure/redpanda.json
rename to src/development/grafana/configurations/dashboards/Infrastructure/redpanda.json
diff --git a/src/production/configurations/grafana/dashboards/Management/kpis.json b/src/development/grafana/configurations/dashboards/Management/kpis.json
similarity index 100%
rename from src/production/configurations/grafana/dashboards/Management/kpis.json
rename to src/development/grafana/configurations/dashboards/Management/kpis.json
diff --git a/src/production/configurations/grafana/provisioning/alerting/alert-notifications-pending.yaml b/src/development/grafana/configurations/provisioning/alerting/alert-notifications-pending.yaml
similarity index 100%
rename from src/production/configurations/grafana/provisioning/alerting/alert-notifications-pending.yaml
rename to src/development/grafana/configurations/provisioning/alerting/alert-notifications-pending.yaml
diff --git a/src/production/configurations/grafana/provisioning/alerting/contact-points.yaml b/src/development/grafana/configurations/provisioning/alerting/contact-points.yaml
similarity index 94%
rename from src/production/configurations/grafana/provisioning/alerting/contact-points.yaml
rename to src/development/grafana/configurations/provisioning/alerting/contact-points.yaml
index cf88e5ce..832c0958 100644
--- a/src/production/configurations/grafana/provisioning/alerting/contact-points.yaml
+++ b/src/development/grafana/configurations/provisioning/alerting/contact-points.yaml
@@ -1,7 +1,7 @@
apiVersion: 1
contactPoints:
- orgId: 1
- name: 'Discord'
+ name: Discord
receivers:
- uid: aen6t8xrd6pkwb
type: discord
@@ -25,6 +25,6 @@ contactPoints:
{{ template "__alert_details" .Alerts.Resolved }}{{ end }}{{ end }}{{ template "default.message_custom" . }}
<@&1377144332154572831>
- url: $__file{/run/secrets/grafana_discord_webhook}
+ url: $__file{/run/secrets/grafana-discord-webhook}
use_discord_username: false
disableResolveMessage: false
diff --git a/src/production/configurations/grafana/provisioning/dashboards/file.yml b/src/development/grafana/configurations/provisioning/dashboards/file.yml
similarity index 89%
rename from src/production/configurations/grafana/provisioning/dashboards/file.yml
rename to src/development/grafana/configurations/provisioning/dashboards/file.yml
index 7129ad74..c23fbd8b 100644
--- a/src/production/configurations/grafana/provisioning/dashboards/file.yml
+++ b/src/development/grafana/configurations/provisioning/dashboards/file.yml
@@ -2,13 +2,13 @@ apiVersion: 1
providers:
# an unique provider name. Required
- - name: 'File'
+ - name: "File"
# Org id. Default to 1
orgId: 1
# name of the dashboard folder.
- folder: ''
+ folder: ""
# folder UID. will be automatically generated if not specified
- folderUid: ''
+ folderUid: ""
# provider type. Default to 'file'
type: file
# disable dashboard deletion
@@ -21,4 +21,4 @@ providers:
# 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
\ No newline at end of file
+ foldersFromFilesStructure: true
diff --git a/src/development/grafana/configurations/provisioning/datasources/postgres.yaml b/src/development/grafana/configurations/provisioning/datasources/postgres.yaml
new file mode 100644
index 00000000..9d53b3fc
--- /dev/null
+++ b/src/development/grafana/configurations/provisioning/datasources/postgres.yaml
@@ -0,0 +1,14 @@
+apiVersion: 1
+
+datasources:
+ - access: proxy
+ jsonData:
+ database: $__file{/run/secrets/postgres-db}
+ postgresVersion: 1500
+ sslmode: disable
+ name: PostgreSQL
+ secureJsonData:
+ password: $__file{/run/secrets/postgres-role-service-grafana-password}
+ type: grafana-postgresql-datasource
+ url: postgres:5432
+ user: $__file{/run/secrets/postgres-role-service-grafana-username}
diff --git a/src/production/configurations/grafana/provisioning/datasources/prometheus.yaml b/src/development/grafana/configurations/provisioning/datasources/prometheus.yaml
similarity index 100%
rename from src/production/configurations/grafana/provisioning/datasources/prometheus.yaml
rename to src/development/grafana/configurations/provisioning/datasources/prometheus.yaml
diff --git a/src/development/jobber/compose.yaml b/src/development/jobber/compose.yaml
new file mode 100644
index 00000000..447213f2
--- /dev/null
+++ b/src/development/jobber/compose.yaml
@@ -0,0 +1,90 @@
+secrets:
+ jobber-aliases:
+ # The job scheduler's SMTP client mail alias.
+ file: ../../../artifacts/secrets/jobber-aliases.secret
+ jobber-aws-bucket:
+ # The job scheduler's AWS bucket name.
+ file: ../../../artifacts/secrets/jobber-aws-bucket.secret
+ jobber-aws-credentials:
+ # The job scheduler's AWS credentials.
+ file: ../../../artifacts/secrets/jobber-aws-credentials.secret
+ jobber-aws-configuration:
+ # The job scheduler's AWS configuration.
+ file: ../../../artifacts/secrets/jobber-aws-configuration.secret
+ jobber-msmtprc:
+ # The job scheduler's SMTP client configuration.
+ file: ../../../artifacts/secrets/jobber-msmtprc.secret
+services:
+ jobber:
+ # You cannot access the jobber via a web interface.
+ environment:
+ AWS_SHARED_CREDENTIALS_FILE: /run/secrets/jobber-aws-credentials
+ image: ghcr.io/dargmuesli/jobber-aws-msmtp:1.3.0
+ secrets:
+ - source: jobber-aliases
+ target: /etc/aliases
+ - jobber-aws-bucket
+ - jobber-aws-credentials
+ - source: jobber-aws-configuration
+ target: /home/jobberuser/.aws/config
+ - source: jobber-msmtprc
+ target: /etc/msmtprc
+ volumes:
+ - ./configurations/sinks:/srv/sinks:ro
+ - ./configurations/.jobber:/home/jobberuser/.jobber:ro
+x-dargstack:
+ secrets:
+ jobber-aliases:
+ type: insecure_default
+ insecure_default: "default: mail@localhost"
+ jobber-aws-bucket:
+ type: word
+ jobber-aws-credentials:
+ type: insecure_default
+ insecure_default: |
+ [default]
+ aws_access_key_id = s3user
+ aws_secret_access_key = s3password
+ jobber-aws-configuration:
+ type: template
+ template: |
+ [default]
+ region =
+
+ s3 =
+ endpoint_url =
+ signature_version = s3v4
+ max_concurrent_requests = 100
+ max_queue_size = 1000
+ multipart_threshold = 50MB
+ # Edit the multipart_chunksize value according to the file sizes that you want to upload. The present configuration allows to upload files up to 10 GB (100 requests * 10MB). For example setting it to 5GB allows you to upload files up to 5TB.
+ multipart_chunksize = 10MB
+ s3api =
+ endpoint_url =
+
+ [plugins]
+ endpoint = awscli_plugin_endpoint
+ jobber-msmtprc:
+ type: template
+ template: |
+ # Set default values for all following accounts.
+ defaults
+ auth on
+ tls on
+ tls_trust_file /etc/ssl/certs/ca-certificates.crt
+ syslog on
+
+ #
+ account
+ host
+ port
+ from
+ user
+ password
+ # or
+ #auth off
+ #tls off
+
+ # Set a default account
+ account default :
+ aliases /etc/aliases
diff --git a/src/development/configurations/jobber/.jobber b/src/development/jobber/configurations/.jobber
similarity index 76%
rename from src/development/configurations/jobber/.jobber
rename to src/development/jobber/configurations/.jobber
index d9067df7..906ff841 100644
--- a/src/development/configurations/jobber/.jobber
+++ b/src/development/jobber/configurations/.jobber
@@ -2,7 +2,7 @@ version: 1.4
jobs:
DBBackup:
- cmd: aws s3 sync /backups s3://$(cat /run/secrets/jobber_aws-bucket)/backups
+ cmd: aws s3 sync /backups s3://$(cat /run/secrets/jobber-aws-bucket)/backups
time: 0 0 0 *
notifyOnSuccess:
- type: system-email
diff --git a/src/production/configurations/jobber/sinks/sentry/error.sh b/src/development/jobber/configurations/sinks/sentry/error.sh
similarity index 100%
rename from src/production/configurations/jobber/sinks/sentry/error.sh
rename to src/development/jobber/configurations/sinks/sentry/error.sh
diff --git a/src/production/configurations/jobber/sinks/sentry/in-progress.sh b/src/development/jobber/configurations/sinks/sentry/in-progress.sh
similarity index 100%
rename from src/production/configurations/jobber/sinks/sentry/in-progress.sh
rename to src/development/jobber/configurations/sinks/sentry/in-progress.sh
diff --git a/src/production/configurations/jobber/sinks/sentry/ok.sh b/src/development/jobber/configurations/sinks/sentry/ok.sh
similarity index 100%
rename from src/production/configurations/jobber/sinks/sentry/ok.sh
rename to src/development/jobber/configurations/sinks/sentry/ok.sh
diff --git a/src/development/secrets/jobber/aliases.secret.template b/src/development/jobber/secrets/aliases.secret.template
similarity index 100%
rename from src/development/secrets/jobber/aliases.secret.template
rename to src/development/jobber/secrets/aliases.secret.template
diff --git a/src/development/secrets/jobber/aws-bucket.secret.template b/src/development/jobber/secrets/aws-bucket.secret.template
similarity index 100%
rename from src/development/secrets/jobber/aws-bucket.secret.template
rename to src/development/jobber/secrets/aws-bucket.secret.template
diff --git a/src/development/secrets/jobber/aws-configuration.secret.template b/src/development/jobber/secrets/aws-configuration.secret.template
similarity index 100%
rename from src/development/secrets/jobber/aws-configuration.secret.template
rename to src/development/jobber/secrets/aws-configuration.secret.template
diff --git a/src/development/secrets/jobber/aws-credentials.secret.template b/src/development/jobber/secrets/aws-credentials.secret.template
similarity index 100%
rename from src/development/secrets/jobber/aws-credentials.secret.template
rename to src/development/jobber/secrets/aws-credentials.secret.template
diff --git a/src/development/secrets/jobber/msmtprc.secret.template b/src/development/jobber/secrets/msmtprc.secret.template
similarity index 100%
rename from src/development/secrets/jobber/msmtprc.secret.template
rename to src/development/jobber/secrets/msmtprc.secret.template
diff --git a/src/development/memcached/compose.yaml b/src/development/memcached/compose.yaml
new file mode 100644
index 00000000..23da3818
--- /dev/null
+++ b/src/development/memcached/compose.yaml
@@ -0,0 +1,8 @@
+services:
+ memcached:
+ # You cannot access the caching system via a web interface.
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ image: memcached:1.6.41-alpine
+ # command: memcached -m 256M
diff --git a/src/development/minio/compose.yaml b/src/development/minio/compose.yaml
new file mode 100644
index 00000000..afc36ee8
--- /dev/null
+++ b/src/development/minio/compose.yaml
@@ -0,0 +1,43 @@
+services:
+ minio: # dargstack:dev-only
+ # You can access the s3 console at [minio.app.localhost](https://minio.app.localhost/).
+ # You can access the s3 api service at [s3.app.localhost](https://s3.app.localhost/) if you want to access via cli from outside the stack.
+ command: server /data --console-address ":9001" # dargstack:dev-only
+ deploy: # dargstack:dev-only
+ labels: # dargstack:dev-only
+ - dargstack.profiles=upload
+ - traefik.enable=true # dargstack:dev-only
+ # Minio Console
+ - traefik.http.routers.minio.entryPoints=web # dargstack:dev-only
+ - traefik.http.routers.minio.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.minio.rule=Host(`minio.${STACK_DOMAIN}`) # dargstack:dev-only
+ - traefik.http.routers.minio.service=minio # dargstack:dev-only
+ - traefik.http.routers.minio-secure.entryPoints=web-secure # dargstack:dev-only
+ - traefik.http.routers.minio-secure.rule=Host(`minio.${STACK_DOMAIN}`) # dargstack:dev-only
+ - traefik.http.routers.minio-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.routers.minio-secure.service=minio # dargstack:dev-only
+ - traefik.http.services.minio.loadbalancer.server.port=9001 # dargstack:dev-only
+ - traefik.http.services.minio.loadbalancer.passhostheader=true # dargstack:dev-only
+ # Minio itself
+ - traefik.http.routers.s3.entryPoints=web # dargstack:dev-only
+ - traefik.http.routers.s3.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.s3.rule=Host(`s3.${STACK_DOMAIN}`) # dargstack:dev-only
+ - traefik.http.routers.s3.service=s3 # dargstack:dev-only
+ - traefik.http.routers.s3-secure.entryPoints=web-secure # dargstack:dev-only
+ - traefik.http.routers.s3-secure.rule=Host(`s3.${STACK_DOMAIN}`) # dargstack:dev-only
+ - traefik.http.routers.s3-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.routers.s3-secure.service=s3 # dargstack:dev-only
+ - traefik.http.services.s3.loadbalancer.server.port=9000 # dargstack:dev-only
+ - traefik.http.services.s3.loadbalancer.passhostheader=true # dargstack:dev-only
+ entrypoint: /patched-entrypoint.sh # dargstack:dev-only
+ image: minio/minio # dargstack:dev-only
+ volumes: # dargstack:dev-only
+ - minio-data:/data # dargstack:dev-only
+ - ./configurations/entrypoint.sh:/patched-entrypoint.sh # dargstack:dev-only
+ environment: # dargstack:dev-only
+ MINIO_ROOT_PASSWORD: s3password # dargstack:dev-only
+ MINIO_ROOT_USER: s3user # dargstack:dev-only
+volumes:
+ minio-data:
+ # The s3 server's data.
+ {}
diff --git a/src/development/configurations/minio/entrypoint.sh b/src/development/minio/configurations/entrypoint.sh
similarity index 100%
rename from src/development/configurations/minio/entrypoint.sh
rename to src/development/minio/configurations/entrypoint.sh
diff --git a/src/development/portainer/compose.yaml b/src/development/portainer/compose.yaml
new file mode 100644
index 00000000..6e586ad1
--- /dev/null
+++ b/src/development/portainer/compose.yaml
@@ -0,0 +1,49 @@
+secrets:
+ portainer-admin-password:
+ # The container manager's admin password.
+ file: ../../../artifacts/secrets/portainer-admin-password.secret
+services:
+ portainer:
+ # You can access the container manager's frontend at [portainer.app.localhost](https://portainer.app.localhost/).
+ command: -H tcp://tasks.portainer-agent:9001 --tlsskipverify --admin-password-file '/run/secrets/portainer-admin-password'
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ - traefik.enable=true
+ - traefik.http.routers.portainer.entryPoints=web
+ - traefik.http.routers.portainer.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.portainer.rule=Host(`portainer.${STACK_DOMAIN}`)
+ - traefik.http.routers.portainer-secure.entryPoints=web-secure
+ - traefik.http.routers.portainer-secure.rule=Host(`portainer.${STACK_DOMAIN}`)
+ - traefik.http.routers.portainer-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.portainer.loadbalancer.server.port=9000
+ placement:
+ constraints:
+ - node.role == manager
+ replicas: 1
+ image: portainer/portainer-ce:2.39.0-alpine
+ secrets:
+ - portainer-admin-password
+ volumes:
+ - portainer-data:/data
+ portainer-agent:
+ # You cannot access the container manager's agent directly.
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ mode: global
+ placement:
+ constraints:
+ - node.platform.os == linux
+ image: portainer/agent:2.39.0
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /var/lib/docker/volumes:/var/lib/docker/volumes
+volumes:
+ portainer-data:
+ # The container manager's data.
+ {}
+x-dargstack:
+ secrets:
+ portainer-admin-password:
+ type: random_string
diff --git a/src/development/secrets/portainer/admin-password.secret.template b/src/development/portainer/secrets/admin-password.secret.template
similarity index 100%
rename from src/development/secrets/portainer/admin-password.secret.template
rename to src/development/portainer/secrets/admin-password.secret.template
diff --git a/src/development/postgraphile/compose.yaml b/src/development/postgraphile/compose.yaml
new file mode 100644
index 00000000..4d5b270b
--- /dev/null
+++ b/src/development/postgraphile/compose.yaml
@@ -0,0 +1,66 @@
+secrets:
+ postgraphile-connection:
+ # The GraphQL API's database URI.
+ file: ../../../artifacts/secrets/postgraphile-connection.secret
+ postgraphile-jwt-secret:
+ # The GraphQL API's JWT secret.
+ file: ../../../artifacts/secrets/postgraphile-jwt-secret.secret
+ postgraphile-owner-connection:
+ # The GraphQL API's database owner URI.
+ file: ../../../artifacts/secrets/postgraphile-owner-connection.secret
+services:
+ postgraphile:
+ # You can access the GraphQL API for the PostgreSQL database at [postgraphile.app.localhost](https://postgraphile.app.localhost/).
+ deploy:
+ labels:
+ - dargstack.development.build=../../../../postgraphile
+ - dargstack.profiles=default
+ - traefik.enable=true
+ - traefik.http.middlewares.postgraphile-auth.forwardauth.address=http://vibetype:3000/api/internal/service/postgraphile/authentication
+ - traefik.http.middlewares.postgraphile-auth.forwardauth.forwardBody=true
+ - traefik.http.middlewares.postgraphile-auth.forwardauth.preserveRequestMethod=true
+ - traefik.http.middlewares.postgraphile-cors.headers.accessControlAllowCredentials=true
+ - traefik.http.middlewares.postgraphile-cors.headers.accessControlAllowHeaders=authorization
+ - traefik.http.middlewares.postgraphile-cors.headers.accessControlAllowOriginList=https://${STACK_DOMAIN},https://localhost:3000,https://app.localhost:3000
+ - traefik.http.routers.postgraphile.entryPoints=web
+ - traefik.http.routers.postgraphile.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.postgraphile.rule=Host(`postgraphile.${STACK_DOMAIN}`)
+ - traefik.http.routers.postgraphile-secure.entryPoints=web-secure
+ - traefik.http.routers.postgraphile-secure.middlewares=postgraphile-auth,postgraphile-cors
+ - traefik.http.routers.postgraphile-secure.rule=Host(`postgraphile.${STACK_DOMAIN}`) && Path(`/graphql`)
+ - traefik.http.routers.postgraphile-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.routers.postgraphile-secure-graphiql.entryPoints=web-secure
+ - traefik.http.routers.postgraphile-secure-graphiql.rule=Host(`postgraphile.${STACK_DOMAIN}`)
+ - traefik.http.routers.postgraphile-secure-graphiql.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.postgraphile.loadbalancer.server.port=5678
+ # # Use the DEBUG environment variable for extended debugging.
+ # environment:
+ # DEBUG: graphile-build:warn,graphile-build-pg:sql
+ image: vibetype/postgraphile:development
+ secrets:
+ - source: postgraphile-connection
+ target: /run/environment-variables/POSTGRAPHILE_CONNECTION
+ - source: postgraphile-jwt-secret
+ target: /run/environment-variables/POSTGRAPHILE_JWT_SECRET_KEY
+ - source: postgraphile-owner-connection
+ target: /run/environment-variables/POSTGRAPHILE_OWNER_CONNECTION
+ volumes:
+ - ../../../../postgraphile/:/srv/app/ # dargstack:dev-only
+ - ./configurations/jwtES256.key.pub:/run/environment-variables/POSTGRAPHILE_JWT_PUBLIC_KEY:ro
+ - pnpm-data:/srv/.pnpm-store/ # dargstack:dev-only
+ - postgraphile-data:/srv/app/node_modules # dargstack:dev-only
+volumes:
+ postgraphile-data:
+ # The GraphQL API's data.
+ {}
+x-dargstack:
+ secrets:
+ postgraphile-connection:
+ type: template
+ template: postgres://{{secret:postgres-role-service-postgraphile-username}}:{{secret:postgres-role-service-postgraphile-password}}@postgres:5432/{{secret:postgres-db}}
+ postgraphile-jwt-secret:
+ type: private_key
+ key_type: ecdsa
+ postgraphile-owner-connection:
+ type: template
+ template: postgres://{{secret:postgres-user}}:{{secret:postgres-password}}@postgres:5432/{{secret:postgres-db}}
diff --git a/src/development/postgraphile/configurations/jwtES256.key.pub b/src/development/postgraphile/configurations/jwtES256.key.pub
new file mode 100644
index 00000000..e9b2a5e8
--- /dev/null
+++ b/src/development/postgraphile/configurations/jwtES256.key.pub
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgIYyEMm+hZzEnXhJLGUx9lwr3cKs
+W2uJ+zLvei380CrUEPARnWQNR/V0usS0EFypTQllniuCpbLG6un87kxh6w==
+-----END PUBLIC KEY-----
diff --git a/src/development/secrets/postgraphile/connection.secret.template b/src/development/postgraphile/secrets/connection.secret.template
similarity index 100%
rename from src/development/secrets/postgraphile/connection.secret.template
rename to src/development/postgraphile/secrets/connection.secret.template
diff --git a/src/development/secrets/postgraphile/jwt-secret.secret.template b/src/development/postgraphile/secrets/jwt-secret.secret.template
similarity index 100%
rename from src/development/secrets/postgraphile/jwt-secret.secret.template
rename to src/development/postgraphile/secrets/jwt-secret.secret.template
diff --git a/src/development/secrets/postgraphile/owner-connection.secret.template b/src/development/postgraphile/secrets/owner-connection.secret.template
similarity index 100%
rename from src/development/secrets/postgraphile/owner-connection.secret.template
rename to src/development/postgraphile/secrets/owner-connection.secret.template
diff --git a/src/development/postgres/compose.yaml b/src/development/postgres/compose.yaml
new file mode 100644
index 00000000..19af7499
--- /dev/null
+++ b/src/development/postgres/compose.yaml
@@ -0,0 +1,92 @@
+secrets:
+ postgres-db:
+ # The database's name.
+ file: ../../../artifacts/secrets/postgres-db.secret
+ postgres-password:
+ # The database's password.
+ file: ../../../artifacts/secrets/postgres-password.secret
+ postgres-role-service-grafana-password:
+ # The password of the observation dashboard's database role.
+ file: ../../../artifacts/secrets/postgres-role-service-grafana-password.secret
+ postgres-role-service-grafana-username:
+ # The username of the observation dashboard's database role.
+ file: ../../../artifacts/secrets/postgres-role-service-grafana-username.secret
+ postgres-role-service-postgraphile-password:
+ # The password of the GraphQL API database wrapper's database role.
+ file: ../../../artifacts/secrets/postgres-role-service-postgraphile-password.secret
+ postgres-role-service-postgraphile-username:
+ # The username of the GraphQL API database wrapper's database role.
+ file: ../../../artifacts/secrets/postgres-role-service-postgraphile-username.secret
+ postgres-role-service-vibetype-password:
+ # The `tusd` database role's password.
+ file: ../../../artifacts/secrets/postgres-role-service-vibetype-password.secret
+ postgres-role-service-vibetype-username:
+ # The `tusd` database role's password.
+ file: ../../../artifacts/secrets/postgres-role-service-vibetype-username.secret
+ postgres-role-service-zammad-password:
+ # The password of the customer service database role.
+ file: ../../../artifacts/secrets/postgres-role-service-zammad-password.secret
+ postgres-role-service-zammad-username:
+ # The username of the customer service database role.
+ file: ../../../artifacts/secrets/postgres-role-service-zammad-username.secret
+ postgres-user:
+ # The database's default user.
+ file: ../../../artifacts/secrets/postgres-user.secret
+services:
+ postgres:
+ # You can access the database via `adminer`.
+ command: -c vibetype.jwt_expiry_duration='1 month' -c wal_level=logical
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ environment:
+ POSTGRES_DB_FILE: /run/secrets/postgres-db
+ POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
+ POSTGRES_USER_FILE: /run/secrets/postgres-user
+ image: postgis/postgis:18-3.6-alpine
+ ports: # dargstack:dev-only
+ - 5432:5432 # dargstack:dev-only
+ secrets:
+ - postgres-db
+ - postgres-password
+ - postgres-user
+ # sysctls:
+ # # Prevent Docker Swarm from killing connections (https://github.com/moby/moby/issues/31208)
+ # - net.ipv4.tcp_keepalive_time=600
+ # - net.ipv4.tcp_keepalive_intvl=30
+ # - net.ipv4.tcp_keepalive_probes=10
+ volumes:
+ - postgres-data:/var/lib/postgresql/
+volumes:
+ postgres-data:
+ # The database's data.
+ {}
+x-dargstack:
+ secrets:
+ postgres-db:
+ type: word
+ postgres-password:
+ special_characters: false
+ type: random_string
+ postgres-role-service-grafana-password:
+ special_characters: false
+ type: random_string
+ postgres-role-service-grafana-username:
+ type: word
+ postgres-role-service-postgraphile-password:
+ special_characters: false
+ type: random_string
+ postgres-role-service-postgraphile-username:
+ type: word
+ postgres-role-service-vibetype-password:
+ special_characters: false
+ type: random_string
+ postgres-role-service-vibetype-username:
+ type: word
+ postgres-role-service-zammad-password:
+ special_characters: false
+ type: random_string
+ postgres-role-service-zammad-username:
+ type: word
+ postgres-user:
+ type: word
diff --git a/src/development/secrets/postgres/db.secret b/src/development/postgres/secrets/db.secret.old
similarity index 100%
rename from src/development/secrets/postgres/db.secret
rename to src/development/postgres/secrets/db.secret.old
diff --git a/src/development/secrets/elasticsearch/keystore_password.secret.template b/src/development/postgres/secrets/db.secret.template.old
similarity index 100%
rename from src/development/secrets/elasticsearch/keystore_password.secret.template
rename to src/development/postgres/secrets/db.secret.template.old
diff --git a/src/development/secrets/elasticsearch/password.secret.template b/src/development/postgres/secrets/password.secret.template
similarity index 100%
rename from src/development/secrets/elasticsearch/password.secret.template
rename to src/development/postgres/secrets/password.secret.template
diff --git a/src/development/secrets/postgres/role_service_grafana_password.secret.template b/src/development/postgres/secrets/role_service_grafana_password.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_grafana_password.secret.template
rename to src/development/postgres/secrets/role_service_grafana_password.secret.template
diff --git a/src/development/secrets/postgres/role_service_grafana_username.secret.template b/src/development/postgres/secrets/role_service_grafana_username.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_grafana_username.secret.template
rename to src/development/postgres/secrets/role_service_grafana_username.secret.template
diff --git a/src/development/secrets/postgres/role_service_postgraphile_password.secret.template b/src/development/postgres/secrets/role_service_postgraphile_password.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_postgraphile_password.secret.template
rename to src/development/postgres/secrets/role_service_postgraphile_password.secret.template
diff --git a/src/development/secrets/postgres/role_service_postgraphile_username.secret.template b/src/development/postgres/secrets/role_service_postgraphile_username.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_postgraphile_username.secret.template
rename to src/development/postgres/secrets/role_service_postgraphile_username.secret.template
diff --git a/src/development/secrets/postgres/role_service_vibetype_password.secret.template b/src/development/postgres/secrets/role_service_vibetype_password.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_vibetype_password.secret.template
rename to src/development/postgres/secrets/role_service_vibetype_password.secret.template
diff --git a/src/development/secrets/postgres/role_service_vibetype_username.secret.template b/src/development/postgres/secrets/role_service_vibetype_username.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_vibetype_username.secret.template
rename to src/development/postgres/secrets/role_service_vibetype_username.secret.template
diff --git a/src/development/secrets/postgres/role_service_zammad_password.secret.template b/src/development/postgres/secrets/role_service_zammad_password.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_zammad_password.secret.template
rename to src/development/postgres/secrets/role_service_zammad_password.secret.template
diff --git a/src/development/secrets/postgres/role_service_zammad_username.secret.template b/src/development/postgres/secrets/role_service_zammad_username.secret.template
similarity index 100%
rename from src/development/secrets/postgres/role_service_zammad_username.secret.template
rename to src/development/postgres/secrets/role_service_zammad_username.secret.template
diff --git a/src/development/secrets/postgres/user.secret.template b/src/development/postgres/secrets/user.secret.template
similarity index 100%
rename from src/development/secrets/postgres/user.secret.template
rename to src/development/postgres/secrets/user.secret.template
diff --git a/src/development/prometheus/compose.yaml b/src/development/prometheus/compose.yaml
new file mode 100644
index 00000000..4c393d3c
--- /dev/null
+++ b/src/development/prometheus/compose.yaml
@@ -0,0 +1,22 @@
+services:
+ prometheus:
+ # You can access the metrics monitoring at [prometheus.app.localhost](https://prometheus.app.localhost/).
+ deploy:
+ labels:
+ - dargstack.profiles=analytics
+ - traefik.enable=true
+ - traefik.http.routers.prometheus.entryPoints=web
+ - traefik.http.routers.prometheus.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.prometheus.rule=Host(`prometheus.${STACK_DOMAIN}`)
+ - traefik.http.routers.prometheus-secure.entryPoints=web-secure
+ - traefik.http.routers.prometheus-secure.rule=Host(`prometheus.${STACK_DOMAIN}`)
+ - traefik.http.routers.prometheus-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.prometheus.loadbalancer.server.port=9090
+ image: prom/prometheus:v3.10.0
+ volumes:
+ - ./configurations/prometheus.yaml:/etc/prometheus/prometheus.yml:ro
+ - prometheus-data:/prometheus
+volumes:
+ prometheus-data:
+ # The metrics monitoring's data.
+ {}
diff --git a/src/production/configurations/prometheus/prometheus.yaml b/src/development/prometheus/configurations/prometheus.yaml
similarity index 97%
rename from src/production/configurations/prometheus/prometheus.yaml
rename to src/development/prometheus/configurations/prometheus.yaml
index 372a7580..0f7725eb 100644
--- a/src/production/configurations/prometheus/prometheus.yaml
+++ b/src/development/prometheus/configurations/prometheus.yaml
@@ -32,4 +32,4 @@ scrape_configs:
static_configs:
- targets:
- redpanda:9644
- metrics_path: /public_metrics
\ No newline at end of file
+ metrics_path: /public_metrics
diff --git a/src/development/reccoom/compose.yaml b/src/development/reccoom/compose.yaml
new file mode 100644
index 00000000..f476237a
--- /dev/null
+++ b/src/development/reccoom/compose.yaml
@@ -0,0 +1,64 @@
+secrets:
+ reccoom-ingest-api-key:
+ # The AI provider's API key for the recommendation engine.
+ file: ../../../artifacts/secrets/reccoom-ingest-api-key.secret
+ reccoom-openai-api-key:
+ # The AI provider's API key for the recommendation engine.
+ file: ../../../artifacts/secrets/reccoom-openai-api-key.secret
+services:
+ reccoom:
+ # You cannot access the recommendation service directly.
+ deploy:
+ labels:
+ - dargstack.development.build=../../../../reccoom
+ - dargstack.profiles=recommendation
+ - traefik.enable=true
+ - traefik.http.routers.reccoom.entryPoints=web
+ - traefik.http.routers.reccoom.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.reccoom.rule=Host(`reccoom.${STACK_DOMAIN}`)
+ - traefik.http.routers.reccoom-secure.entryPoints=web-secure
+ - traefik.http.routers.reccoom-secure.rule=Host(`reccoom.${STACK_DOMAIN}`)
+ - traefik.http.routers.reccoom-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.reccoom.loadbalancer.server.port=5245
+ environment:
+ POSTGRES_HOST: postgres
+ RECCOOM_POSTGRES_HOST: reccoom_postgres
+ image: vibetype/reccoom:development
+ secrets:
+ - postgres-db
+ - postgres-password
+ - postgres-user
+ - source: reccoom-ingest-api-key
+ target: /run/environment-variables/INGEST_API_KEY
+ - reccoom-openai-api-key
+ volumes:
+ - ../../../../reccoom/:/srv/app/ # dargstack:dev-only
+ - ../postgraphile/configurations/jwtES256.key.pub:/run/configurations/jwtES256.key.pub:ro
+ reccoom_postgres:
+ # You can access reccoom's database via `adminer`.
+ deploy:
+ labels:
+ - dargstack.profiles=recommendation
+ environment:
+ POSTGRES_DB_FILE: /run/secrets/postgres-db
+ POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
+ POSTGRES_USER_FILE: /run/secrets/postgres-user
+ image: pgvector/pgvector:0.8.2-pg18
+ ports: # dargstack:dev-only
+ - 5433:5432 # dargstack:dev-only
+ secrets:
+ - postgres-db
+ - postgres-password
+ - postgres-user
+ volumes:
+ - reccoom-postgres-data:/var/lib/postgresql/
+volumes:
+ reccoom-postgres-data:
+ # The recommendation database's data.
+ {}
+x-dargstack:
+ secrets:
+ reccoom-ingest-api-key:
+ type: third_party
+ reccoom-openai-api-key:
+ type: third_party
diff --git a/src/development/secrets/reccoom/ingest-api-key.secret.template b/src/development/reccoom/secrets/ingest-api-key.secret.template
similarity index 100%
rename from src/development/secrets/reccoom/ingest-api-key.secret.template
rename to src/development/reccoom/secrets/ingest-api-key.secret.template
diff --git a/src/development/secrets/reccoom/openai-api-key.secret.template b/src/development/reccoom/secrets/openai-api-key.secret.template
similarity index 100%
rename from src/development/secrets/reccoom/openai-api-key.secret.template
rename to src/development/reccoom/secrets/openai-api-key.secret.template
diff --git a/src/development/redis/compose.yaml b/src/development/redis/compose.yaml
new file mode 100644
index 00000000..4fe89a5b
--- /dev/null
+++ b/src/development/redis/compose.yaml
@@ -0,0 +1,13 @@
+services:
+ redis:
+ # You cannot access the caching system via a web interface.
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ image: redis:8.6.1-alpine
+ volumes:
+ - redis-data:/data
+volumes:
+ redis-data:
+ # The caching system's data.
+ {}
diff --git a/src/development/redpanda/compose.yaml b/src/development/redpanda/compose.yaml
new file mode 100644
index 00000000..a92a858b
--- /dev/null
+++ b/src/development/redpanda/compose.yaml
@@ -0,0 +1,45 @@
+services:
+ redpanda:
+ # You can access the event streaming platform's ui as described under `redpanda-console`.
+ command:
+ - redpanda start
+ - --mode dev-container # dargstack:dev-only
+ - --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092
+ - --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092
+ - --pandaproxy-addr internal://0.0.0.0:8082,external://0.0.0.0:18082
+ - --advertise-pandaproxy-addr internal://redpanda:8082,external://localhost:18082
+ - --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081
+ deploy:
+ labels:
+ - dargstack.profiles=event-streaming
+ # healthcheck:
+ # test: ["CMD-SHELL", "output=$(rpk cluster health --json); echo \"$output\" | grep -q '\"healthy\":true' || { echo \"$output\"; exit 1; }"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 10s
+ image: redpandadata/redpanda:v25.3.10
+ volumes:
+ - redpanda-data:/var/lib/redpanda/data
+ redpanda-console:
+ # You can access the event streaming platform's ui at [redpanda.app.localhost](https://redpanda.app.localhost/).
+ deploy:
+ labels:
+ - dargstack.profiles=event-streaming
+ - traefik.enable=true
+ - traefik.http.routers.redpanda.entryPoints=web
+ - traefik.http.routers.redpanda.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.redpanda.rule=Host(`redpanda.${STACK_DOMAIN}`)
+ - traefik.http.routers.redpanda-secure.entryPoints=web-secure
+ - traefik.http.routers.redpanda-secure.rule=Host(`redpanda.${STACK_DOMAIN}`)
+ - traefik.http.routers.redpanda-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.redpanda.loadbalancer.server.port=8080
+ environment:
+ CONFIG_FILEPATH: /srv/app/redpanda-config.yaml
+ image: redpandadata/console:v3.5.3
+ volumes:
+ - ./configurations/config.yaml:/srv/app/redpanda-config.yaml:ro
+volumes:
+ redpanda-data:
+ # The message queue's data.
+ {}
diff --git a/src/production/configurations/redpanda/config.yaml b/src/development/redpanda/configurations/config.yaml
similarity index 58%
rename from src/production/configurations/redpanda/config.yaml
rename to src/development/redpanda/configurations/config.yaml
index 26876a8a..93bf566c 100644
--- a/src/production/configurations/redpanda/config.yaml
+++ b/src/development/redpanda/configurations/config.yaml
@@ -1,12 +1,12 @@
kafka:
brokers:
- - redpanda:9092
+ - redpanda:9092
redpanda:
adminApi:
enabled: true
urls:
- - http://redpanda:9644
+ - http://redpanda:9644
schemaRegistry:
enabled: true
urls:
- - http://redpanda:8081
+ - http://redpanda:8081
diff --git a/src/development/secrets/elasticsearch/keystore_password.secret b/src/development/secrets/elasticsearch/keystore_password.secret
deleted file mode 100644
index f3f85cae..00000000
--- a/src/development/secrets/elasticsearch/keystore_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-elastic
\ No newline at end of file
diff --git a/src/development/secrets/elasticsearch/password.secret b/src/development/secrets/elasticsearch/password.secret
deleted file mode 100644
index f3f85cae..00000000
--- a/src/development/secrets/elasticsearch/password.secret
+++ /dev/null
@@ -1 +0,0 @@
-elastic
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_email.secret b/src/development/secrets/grafana/admin_email.secret
deleted file mode 100644
index 06474a56..00000000
--- a/src/development/secrets/grafana/admin_email.secret
+++ /dev/null
@@ -1 +0,0 @@
-admin@localhost
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_email.secret.template b/src/development/secrets/grafana/admin_email.secret.template
deleted file mode 100644
index a6bb01c1..00000000
--- a/src/development/secrets/grafana/admin_email.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_password.secret b/src/development/secrets/grafana/admin_password.secret
deleted file mode 100644
index 6da70038..00000000
--- a/src/development/secrets/grafana/admin_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-grafana
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_password.secret.template b/src/development/secrets/grafana/admin_password.secret.template
deleted file mode 100644
index a6bb01c1..00000000
--- a/src/development/secrets/grafana/admin_password.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_user.secret b/src/development/secrets/grafana/admin_user.secret
deleted file mode 100644
index 6da70038..00000000
--- a/src/development/secrets/grafana/admin_user.secret
+++ /dev/null
@@ -1 +0,0 @@
-grafana
\ No newline at end of file
diff --git a/src/development/secrets/grafana/admin_user.secret.template b/src/development/secrets/grafana/admin_user.secret.template
deleted file mode 100644
index a6bb01c1..00000000
--- a/src/development/secrets/grafana/admin_user.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/development/secrets/grafana/discord_webhook.secret b/src/development/secrets/grafana/discord_webhook.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/grafana/discord_webhook.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/grafana/discord_webhook.secret.template b/src/development/secrets/grafana/discord_webhook.secret.template
deleted file mode 100644
index 3ad15b2a..00000000
--- a/src/development/secrets/grafana/discord_webhook.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-https://discord.com/api/webhooks//
\ No newline at end of file
diff --git a/src/development/secrets/jobber/aliases.secret b/src/development/secrets/jobber/aliases.secret
deleted file mode 100644
index 20df8a23..00000000
--- a/src/development/secrets/jobber/aliases.secret
+++ /dev/null
@@ -1 +0,0 @@
-default: mail@localhost
diff --git a/src/development/secrets/jobber/aws-bucket.secret b/src/development/secrets/jobber/aws-bucket.secret
deleted file mode 100644
index dc9cb35b..00000000
--- a/src/development/secrets/jobber/aws-bucket.secret
+++ /dev/null
@@ -1 +0,0 @@
-vibetype-backup
\ No newline at end of file
diff --git a/src/development/secrets/jobber/aws-configuration.secret b/src/development/secrets/jobber/aws-configuration.secret
deleted file mode 100644
index 20ea0b02..00000000
--- a/src/development/secrets/jobber/aws-configuration.secret
+++ /dev/null
@@ -1,16 +0,0 @@
-[default]
-region = auto
-
-s3 =
- endpoint_url = http://minio:9000
- signature_version = s3v4
- max_concurrent_requests = 100
- max_queue_size = 1000
- multipart_threshold = 50MB
- # Edit the multipart_chunksize value according to the file sizes that you want to upload. The present configuration allows to upload files up to 10 GB (100 requests * 10MB). For example setting it to 5GB allows you to upload files up to 5TB.
- multipart_chunksize = 10MB
-s3api =
- endpoint_url = http://minio:9000
-
-[plugins]
-endpoint = awscli_plugin_endpoint
\ No newline at end of file
diff --git a/src/development/secrets/jobber/aws-credentials.secret b/src/development/secrets/jobber/aws-credentials.secret
deleted file mode 100644
index a28cae87..00000000
--- a/src/development/secrets/jobber/aws-credentials.secret
+++ /dev/null
@@ -1,3 +0,0 @@
-[default]
-aws_access_key_id = s3user
-aws_secret_access_key = s3password
diff --git a/src/development/secrets/jobber/msmtprc.secret b/src/development/secrets/jobber/msmtprc.secret
deleted file mode 100644
index 84ceec08..00000000
--- a/src/development/secrets/jobber/msmtprc.secret
+++ /dev/null
@@ -1,17 +0,0 @@
-# Set default values for all following accounts.
-defaults
-auth off
-tls off
-tls_trust_file /etc/ssl/certs/ca-certificates.crt
-syslog on
-
-# localhost
-account localhost
-host localhost
-port 25
-from mail@localhost
-user mail@localhost
-
-# Set a default account
-account default : localhost
-aliases /etc/aliases
diff --git a/src/development/secrets/portainer/admin-password.secret b/src/development/secrets/portainer/admin-password.secret
deleted file mode 100644
index 45aee45f..00000000
--- a/src/development/secrets/portainer/admin-password.secret
+++ /dev/null
@@ -1 +0,0 @@
-123456123456
\ No newline at end of file
diff --git a/src/development/secrets/postgraphile/connection.secret b/src/development/secrets/postgraphile/connection.secret
deleted file mode 100644
index f94cfa39..00000000
--- a/src/development/secrets/postgraphile/connection.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgresql://postgraphile:postgraphile@postgres/vibetype
\ No newline at end of file
diff --git a/src/development/secrets/postgraphile/jwt-secret.secret b/src/development/secrets/postgraphile/jwt-secret.secret
deleted file mode 100644
index 8b5b34e0..00000000
--- a/src/development/secrets/postgraphile/jwt-secret.secret
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAtBuHX2uH5GviLbocSUBKaRE4iKEjjEoB1eh7VQdBoKi1Wd+D
-NUilVyCtq0ootPSDR/8yOTa8W396Wu1xm07+xDAyFzsilIppu8DNcJo28Gb3PZCm
-4nXmITPkknVSKf80hosgauoe7itqDxgMASYTU8CgBH8zXPaowhqzjz0M/T9RqD1m
-RzMn3NEprDnaVAsh11r3DSandHjsnlgKCf1dlh4ixCZ6zUhtb0sT6GxuJaGjNVev
-LbPLuugMTu3d484FwbND+AmpAjIgdnX5lJQneT7HxgnaiwLDazSwLM0jmiyEvnrm
-SPJZ2sgp87XS0VTVwMYk3M3RCy/3RiamJG5v7qZuVr4L87cXWvLHCwV5dGaPu0Dc
-3/75lcKcWy+BtBQUI+n+om1EitLtUo+lxE9aSyG6bhYQNu+XMRwY768TrzrvBwYt
-5JxoO9y3ybIFzoi/mufkp2NY7XB7CHfMcrn3XzCBbXJwt0Zlu2K1R8FPVN0Slsjt
-OVQun1al9cjC808hihjpiiGpKURoaFsxkh4B8n2Qli/fl5BQVAPClmFbsvToSzy+
-ENEDpXc53eve5Dhzx5SB/qe0DwlljDdc2W8nhozYHaOtnLnhG/TU9mmOliw5jmsH
-b5m1OMdBXMEhrGv4hkHJNg9+hCSJDzvbFRkNY95lZj/fbtFrSHR5WwdsgI8CAwEA
-AQKCAgEAjxyMvbJpAYUD7MfEcCQovEHVxSMdZvzrZnhbf53LdQh5SZeD35QA5TFv
-Lfs4S0k7A7twweuPUbkClTu1GO51G5kcRD9V4+fzyh+SXpX7b5yxenb1VF7QZLOi
-PQoCJqLFrt7f/HRZ7XALz0CRUVxa4SLfQ5N7UbQhNlMXOIsPRi/JB8D6AztPwnNl
-BJfXtw49bqy2P/nl93OauNtF5tgvQ/hgMbJNw854PoXOpNF72GUOlXU+GjeSe8qk
-9RanSLtM8bQrHu02ISuJhfeKQJhUoU/UV7U+tVSVyRrNnlvGnVwggmaPk4kXAvQn
-+aIRiQo66vnHErhsEdKkTlapj6s9PnMmtwNJcv/Bp8/621Pr3mqG4WtZrYxMYFzN
-5tXwjkQQRpLRyi0pwu6IHj9w+y83oJKi6HTo//tJbKEzqx1jjhl4FiNwKMDfxlpp
-eN52c723DELgc9AhRCXP50z2OnjByeI296bj+Vyv0noDDSLK5pq4Hm9Ck62NCfsV
-YqCmvVu5JwFP+MYUECNRH6d98wsWhgKvAJe37JH9BEjxvW3oLB4XofSqGrFePNEM
-jRdnLdJxFC0AfWVMu4JW1MvcZct7nkFd91YGKzZRlasbnRVQ4qHTYhojwiM2LF8E
-aLxKOKegxfRFBkfHSzxzXAA2o4r2pJo2WZI+lBuBd6TmTX21ZLkCggEBAOiIkB9k
-oOOe0UyVDkEJTk62y5LdrEG3KpEjaW12qFP1IGgqP5gDqhDQQ4WB4Pqzl1uoqy2L
-WafpfEH2lBTeYMV4Wg5WkgZIrCRthhdwoDqluUttN612VuT4QlLvnB37zdDzkzfL
-asnCKmXfaOSU/qvHcUvS6SgnwKVWBqFSB2VWBgLGVH2Ty/Yc9TpMraSZA2ATnieR
-7aZy1zegwp7n3sO3mmY0w7A+7YoUms1+Ibe5aNmyw/ThDJBkx+UG0nv9qpoA4yNH
-+S355EJyYdUNoh0d8D3COk72YjcODmiB+6W0qoPQ3SeQ2X/6+xvFNkx2/34+nhcy
-tNNqBkeKe2IpkzUCggEBAMZIjpAPiT/7rb0/ea8DZAmdOhjER5NOic3gz6RN7oqj
-MQ2ktzxfGJez+wnjaqv1xF+qwZi69JwflK3FWIZR3G1wlO5pKMkef5l1N/VLvW2k
-opfx+82sVXi/Cx7w8o6IAS60ZjyxTWhnYQ695QIKP79+poWJ3zi9sBpsj7hHbPco
-tu4kJKVpXOVcmMluSqrn+3kT7Xlpqy6qnFBggRHLJD9okM3TLU3znHRUFhViova3
-kyD65qViITUCIMDmigfCbFYLVGEdNyMDBH0OGSUaSwY0d/KS+43JxLeh84ylHPYZ
-tfPiQxCxn2VyD2h4XkNIdgoY7f/NbkzjkLEdSdc0GTMCggEBAJzgdQsY4opt/RpD
-fUhXNONZ42GD99Cl+CvOzjOxV8K8n05nIlw2LKgHOWZ6xwOb4cNOuZ2SY7wqg1Al
-QKYLmRHgLjF6Ki3fHXO+CDcMHq0yXR4L4wI90kXLT0OQr6xy0tnjWjDMJZFUUzJD
-VQrRkjbl6QOUmQQkPY3Nyc9P/flZ3dhFYX8PFQ1HYBIi5Qskx+grlAlyI/ilhZjb
-9jEqkVlNJvdJJbRj3/HGEOIN9EV06s3kEtvEcKuBsnJK9fn8mvonGxYUWoGwE1TY
-wjPwbKxkJE4mGRxokL4/12yeNN4IUvl3EZy91l7HPl3v4MAZkCjlqdZQuTngT7g4
-LyF8lvkCggEAQJIUSvmkOn/dPknTeJjkFPVsm/AfVus2mSLiu6DdU6x9JvJC8ZgO
-TCjCUaALduBcCMN0tCX9znHCWyxu/Z7e54zIEzOPop8Z8oFnravyjigVAuI8m+fJ
-Fb8xAex5MM09hVYeDRm4GY3A36obT6TCybuWwtn5JWMwXAqKavpnk71ghQCkJnG/
-XLngz4fpLOrKy80fgnBU3KeWq94hagf7T+LfdQeWM1Jn2sIfRuuOIkX51b2fKrBg
-HAELZYYt4QUBfqvF2LJI6E/tQEQ9EAYV9HlVrlsLLEtOknZc96o1WjdZN4ixSlht
-jf2s4tp/5+1K81LW/nyJtOROlD7zcu92XQKCAQAUgxlfDbjBz64DrpyJDhHQq89X
-WH0+zXhwuWiQwzlbSQUJnKnVwPwcnKD/zxK601fWT26C01l3senX49zy/KZI1BtD
-mco+Mr+wKGNPcOoVhhzYTDk6R+jfsyel0uXcky6LPncCLgsq7UpVylONaDO5m+fL
-2wUg67tJu13zHMSWml5+o51jY/Qn/UjsSyEj7gQHq4xM2ottb6fh3CgmMvJKjrAP
-juM36ePNpeQMBHf9Djt7a/tuN0OZdGo4sjBSJ9fEAoMGtxZ1nQyu06ncBQMtlqeD
-+pzL73569phIJDX7E11wczzx/QObJ4dMznCgqEfpzlSNOhPl+bqyzAdVXO4V
------END RSA PRIVATE KEY-----
diff --git a/src/development/secrets/postgraphile/owner-connection.secret b/src/development/secrets/postgraphile/owner-connection.secret
deleted file mode 100644
index 093bbed2..00000000
--- a/src/development/secrets/postgraphile/owner-connection.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgresql://postgres:postgres@postgres/vibetype
\ No newline at end of file
diff --git a/src/development/secrets/postgres/db.secret.template b/src/development/secrets/postgres/db.secret.template
deleted file mode 100644
index a6bb01c1..00000000
--- a/src/development/secrets/postgres/db.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/development/secrets/postgres/password.secret b/src/development/secrets/postgres/password.secret
deleted file mode 100644
index f1349944..00000000
--- a/src/development/secrets/postgres/password.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgres
diff --git a/src/development/secrets/postgres/password.secret.template b/src/development/secrets/postgres/password.secret.template
deleted file mode 100644
index a6bb01c1..00000000
--- a/src/development/secrets/postgres/password.secret.template
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_grafana_password.secret b/src/development/secrets/postgres/role_service_grafana_password.secret
deleted file mode 100644
index 6da70038..00000000
--- a/src/development/secrets/postgres/role_service_grafana_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-grafana
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_grafana_username.secret b/src/development/secrets/postgres/role_service_grafana_username.secret
deleted file mode 100644
index 6da70038..00000000
--- a/src/development/secrets/postgres/role_service_grafana_username.secret
+++ /dev/null
@@ -1 +0,0 @@
-grafana
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_postgraphile_password.secret b/src/development/secrets/postgres/role_service_postgraphile_password.secret
deleted file mode 100644
index a4da12ec..00000000
--- a/src/development/secrets/postgres/role_service_postgraphile_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgraphile
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_postgraphile_username.secret b/src/development/secrets/postgres/role_service_postgraphile_username.secret
deleted file mode 100644
index a4da12ec..00000000
--- a/src/development/secrets/postgres/role_service_postgraphile_username.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgraphile
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_vibetype_password.secret b/src/development/secrets/postgres/role_service_vibetype_password.secret
deleted file mode 100644
index 5e84b8c8..00000000
--- a/src/development/secrets/postgres/role_service_vibetype_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-tusd
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_vibetype_username.secret b/src/development/secrets/postgres/role_service_vibetype_username.secret
deleted file mode 100644
index 9294c3d9..00000000
--- a/src/development/secrets/postgres/role_service_vibetype_username.secret
+++ /dev/null
@@ -1 +0,0 @@
-vibetype
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_zammad_password.secret b/src/development/secrets/postgres/role_service_zammad_password.secret
deleted file mode 100644
index 70699eae..00000000
--- a/src/development/secrets/postgres/role_service_zammad_password.secret
+++ /dev/null
@@ -1 +0,0 @@
-zammad
\ No newline at end of file
diff --git a/src/development/secrets/postgres/role_service_zammad_username.secret b/src/development/secrets/postgres/role_service_zammad_username.secret
deleted file mode 100644
index 70699eae..00000000
--- a/src/development/secrets/postgres/role_service_zammad_username.secret
+++ /dev/null
@@ -1 +0,0 @@
-zammad
\ No newline at end of file
diff --git a/src/development/secrets/postgres/user.secret b/src/development/secrets/postgres/user.secret
deleted file mode 100644
index f1349944..00000000
--- a/src/development/secrets/postgres/user.secret
+++ /dev/null
@@ -1 +0,0 @@
-postgres
diff --git a/src/development/secrets/reccoom/ingest-api-key.secret b/src/development/secrets/reccoom/ingest-api-key.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/reccoom/ingest-api-key.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/reccoom/openai-api-key.secret b/src/development/secrets/reccoom/openai-api-key.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/reccoom/openai-api-key.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/sqitch/target.secret b/src/development/secrets/sqitch/target.secret
deleted file mode 100644
index 12789f3c..00000000
--- a/src/development/secrets/sqitch/target.secret
+++ /dev/null
@@ -1 +0,0 @@
-db:pg://postgres:postgres@postgres/vibetype
\ No newline at end of file
diff --git a/src/development/secrets/tusd/aws.secret b/src/development/secrets/tusd/aws.secret
deleted file mode 100644
index eed88684..00000000
--- a/src/development/secrets/tusd/aws.secret
+++ /dev/null
@@ -1,3 +0,0 @@
-[default]
-aws_access_key_id = s3user
-aws_secret_access_key = s3password
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/api-notification.secret b/src/development/secrets/vibetype/api-notification.secret
deleted file mode 100644
index 9294c3d9..00000000
--- a/src/development/secrets/vibetype/api-notification.secret
+++ /dev/null
@@ -1 +0,0 @@
-vibetype
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/aws-credentials.secret b/src/development/secrets/vibetype/aws-credentials.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/vibetype/aws-credentials.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/firebase-service-account-credentials.secret b/src/development/secrets/vibetype/firebase-service-account-credentials.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/vibetype/firebase-service-account-credentials.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/monday.secret b/src/development/secrets/vibetype/monday.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/vibetype/monday.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/openai-api-key.secret b/src/development/secrets/vibetype/openai-api-key.secret
deleted file mode 100644
index 6075c4fb..00000000
--- a/src/development/secrets/vibetype/openai-api-key.secret
+++ /dev/null
@@ -1 +0,0 @@
-UNSET THIRD PARTY SECRET
\ No newline at end of file
diff --git a/src/development/secrets/vibetype/turnstile-key.secret b/src/development/secrets/vibetype/turnstile-key.secret
deleted file mode 100644
index d8c28c70..00000000
--- a/src/development/secrets/vibetype/turnstile-key.secret
+++ /dev/null
@@ -1 +0,0 @@
-1x0000000000000000000000000000000AA
\ No newline at end of file
diff --git a/src/development/sqitch/compose.yaml b/src/development/sqitch/compose.yaml
new file mode 100644
index 00000000..0771a323
--- /dev/null
+++ b/src/development/sqitch/compose.yaml
@@ -0,0 +1,29 @@
+secrets:
+ sqitch-target:
+ # The database change management application's database connection string.
+ file: ../../../artifacts/secrets/sqitch-target.secret
+services:
+ sqitch:
+ # You cannot access the database migrations directly.
+ deploy:
+ labels:
+ - dargstack.development.build=../../../../sqitch
+ - dargstack.profiles=default
+ image: vibetype/sqitch:development
+ secrets:
+ - postgres-role-service-grafana-password
+ - postgres-role-service-grafana-username
+ - postgres-role-service-postgraphile-password
+ - postgres-role-service-postgraphile-username
+ - postgres-role-service-vibetype-password
+ - postgres-role-service-vibetype-username
+ - postgres-role-service-zammad-username
+ - postgres-role-service-zammad-password
+ - sqitch-target
+ volumes:
+ - ../../../../sqitch/:/srv/app/
+x-dargstack:
+ secrets:
+ sqitch-target:
+ type: template
+ template: postgres://{{secret:postgres-user}}:{{secret:postgres-password}}@postgres:5432/{{secret:postgres-db}}
diff --git a/src/development/secrets/sqitch/target.secret.template b/src/development/sqitch/secrets/target.secret.template
similarity index 100%
rename from src/development/secrets/sqitch/target.secret.template
rename to src/development/sqitch/secrets/target.secret.template
diff --git a/src/development/stack.env.template b/src/development/stack.env.template
deleted file mode 100644
index 261fdee5..00000000
--- a/src/development/stack.env.template
+++ /dev/null
@@ -1,8 +0,0 @@
-TUSD_BUCKET=vibetype-images
-TUSD_ENDPOINT=http://minio:9000
-TUSD_MAX_SIZE=10485760
-TUSD_REGION=eu-central-1
-VIBETYPE_AWS_REGION=eu-central-1
-VIBETYPE_NUXT_PUBLIC_GTAG_ID=G-WMQ1JY99XH
-VIBETYPE_NUXT_PUBLIC_TURNSTILE_SITE_KEY=1x00000000000000000000AA
-VIBETYPE_NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H=100
\ No newline at end of file
diff --git a/src/development/stack.yml b/src/development/stack.yml
deleted file mode 100644
index 893fafe1..00000000
--- a/src/development/stack.yml
+++ /dev/null
@@ -1,745 +0,0 @@
-# vibetype.app
-# https://vibetype.app/
-# Vibetype
-# https://github.com/maevsi/vibetype/
----
-x-shared:
- zammad-service:
- &zammad-service # You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
- environment: &zammad-environment
- ELASTICSEARCH_HOST: elasticsearch
- ELASTICSEARCH_SCHEMA: https
- ELASTICSEARCH_USER: elastic
- MEMCACHE_SERVERS: memcached:11211
- NGINX_SERVER_SCHEME: https
- POSTGRESQL_DB: zammad
- POSTGRESQL_DB_CREATE: "false"
- POSTGRESQL_HOST: postgres
- POSTGRESQL_OPTIONS: ?pool=50
- REDIS_URL: redis://redis:6379
- image: ghcr.io/zammad/zammad:6.5.2-90
- secrets:
- - source: elasticsearch-password
- target: /run/environment-variables/ELASTICSEARCH_PASS
- - source: postgres_role_service_zammad_username
- target: /run/environment-variables/POSTGRESQL_USER
- - source: postgres_role_service_zammad_password
- target: /run/environment-variables/POSTGRESQL_PASS
- volumes:
- - zammad_data:/opt/zammad/storage
- - ../production/configurations/zammad/docker-entrypoint.sh:/docker-entrypoint.sh:ro
-secrets:
- elasticsearch-keystore_password:
- # The search engine's password for the keystore.
- file: ./secrets/elasticsearch/keystore_password.secret
- elasticsearch-password:
- # The search engine's password for the default user.
- file: ./secrets/elasticsearch/password.secret
- grafana_admin_email:
- # The observation dashboard's admin email.
- file: ./secrets/grafana/admin_email.secret
- grafana_admin_password:
- # The observation dashboard's admin password.
- file: ./secrets/grafana/admin_password.secret
- grafana_admin_user:
- # The observation dashboard's admin user.
- file: ./secrets/grafana/admin_user.secret
- grafana_discord_webhook:
- # The observation dashboard's contact point for Discord.
- file: ./secrets/grafana/discord_webhook.secret
- jobber_aliases:
- # The job scheduler's SMTP client mail alias.
- file: ./secrets/jobber/aliases.secret
- jobber_aws-bucket:
- # The job scheduler's AWS bucket name.
- file: ./secrets/jobber/aws-bucket.secret
- jobber_aws-credentials:
- # The job scheduler's AWS credentials.
- file: ./secrets/jobber/aws-credentials.secret
- jobber_aws-configuration:
- # The job scheduler's AWS configuration.
- file: ./secrets/jobber/aws-configuration.secret
- jobber_msmtprc:
- # The job scheduler's SMTP client configuration.
- file: ./secrets/jobber/msmtprc.secret
- portainer_admin-password:
- # The container manager's admin password.
- file: ./secrets/portainer/admin-password.secret
- postgraphile_connection:
- # The GraphQL API's database URI.
- file: ./secrets/postgraphile/connection.secret
- postgraphile_jwt-secret:
- # The GraphQL API's JWT secret.
- file: ./secrets/postgraphile/jwt-secret.secret
- postgraphile_owner-connection:
- # The GraphQL API's database owner URI.
- file: ./secrets/postgraphile/owner-connection.secret
- postgres_db:
- # The database's name.
- file: ./secrets/postgres/db.secret
- postgres_password:
- # The database's password.
- file: ./secrets/postgres/password.secret
- postgres_role_service_grafana_password:
- # The password of the observation dashboard's database role.
- file: ./secrets/postgres/role_service_grafana_password.secret
- postgres_role_service_grafana_username:
- # The username of the observation dashboard's database role.
- file: ./secrets/postgres/role_service_grafana_username.secret
- postgres_role_service_postgraphile_password:
- # The password of the GraphQL API database wrapper's database role.
- file: ./secrets/postgres/role_service_postgraphile_password.secret
- postgres_role_service_postgraphile_username:
- # The username of the GraphQL API database wrapper's database role.
- file: ./secrets/postgres/role_service_postgraphile_username.secret
- postgres_role_service_vibetype_password:
- # The `tusd` database role's password.
- file: ./secrets/postgres/role_service_vibetype_password.secret
- postgres_role_service_vibetype_username:
- # The `tusd` database role's password.
- file: ./secrets/postgres/role_service_vibetype_username.secret
- postgres_role_service_zammad_password:
- # The password of the customer service database role.
- file: ./secrets/postgres/role_service_zammad_password.secret
- postgres_role_service_zammad_username:
- # The username of the customer service database role.
- file: ./secrets/postgres/role_service_zammad_username.secret
- postgres_user:
- # The database's default user.
- file: ./secrets/postgres/user.secret
- reccoom_ingest-api-key:
- # The AI provider's API key for the recommendation engine.
- file: ./secrets/reccoom/ingest-api-key.secret
- reccoom_openai-api-key:
- # The AI provider's API key for the recommendation engine.
- file: ./secrets/reccoom/openai-api-key.secret
- sqitch_target:
- # The database change management application's database connection string.
- file: ./secrets/sqitch/target.secret
- tusd_aws:
- # The upload service's s3 credentials file.
- file: ./secrets/tusd/aws.secret
- vibetype_api-notification-secret:
- # The notification endpoint's secret.
- file: ./secrets/vibetype/api-notification.secret
- vibetype_aws-credentials:
- # The cloud computing provider's user credentials.
- file: ./secrets/vibetype/aws-credentials.secret
- vibetype_firebase-service-account-credentials:
- # The notification provider's service account credentials.
- file: ./secrets/vibetype/firebase-service-account-credentials.secret
- vibetype_monday:
- # The project management software's configuration.
- file: ./secrets/vibetype/monday.secret
- vibetype_openai-api-key:
- # The AI provider's API key for the frontend.
- file: ./secrets/vibetype/openai-api-key.secret
- vibetype_turnstile-key:
- # The captcha provider's application key.
- file: ./secrets/vibetype/turnstile-key.secret
-services:
- adminer:
- # You can access the database's frontend at [adminer.app.localhost](https://adminer.app.localhost/).
- # This information is required for login:
- #
- # | | |
- # | -------- | ------------------- |
- # | System | PostgreSQL |
- # | Server | postgres |
- # | Username | [postgres_user] |
- # | Password | [postgres_password] |
- # | Database | [postgres_db] |
- #
- # Values in square brackets are [Docker secrets](https://docs.docker.com/engine/swarm/secrets/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.adminer.entryPoints=web
- - traefik.http.routers.adminer.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.adminer.rule=Host(`adminer.${STACK_DOMAIN}`)
- - traefik.http.routers.adminer_secure.entryPoints=web-secure
- - traefik.http.routers.adminer_secure.rule=Host(`adminer.${STACK_DOMAIN}`)
- - traefik.http.routers.adminer_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.adminer.loadbalancer.server.port=8080
- image: adminer:5.4.2-standalone
- volumes:
- - ../production/configurations/adminer/adminer.css:/var/www/html/adminer.css:ro
- debezium:
- # You can see how changes in the database end up in the event stream using `redpanda-console`.
- environment:
- BOOTSTRAP_SERVERS: redpanda:9092
- CONFIG_STORAGE_TOPIC: connect_configs
- GROUP_ID: 1
- OFFSET_STORAGE_TOPIC: connect_offsets
- STATUS_STORAGE_TOPIC: connect_statuses
- # healthcheck:
- # test: ["CMD", "curl", "--fail", "--silent", "--show-error", "http://localhost:8083/connectors"]
- # interval: 30s
- # timeout: 10s
- # retries: 3
- # start_period: 20s
- image: quay.io/debezium/connect:3.5
- volumes:
- - debezium_kafka_configuration:/kafka/config
- - debezium_kafka_data:/kafka/data
- - debezium_kafka_logs:/kafka/logs
- debezium-postgres-connector:
- # You can check the database connector's setup logs using `portainer`.
- command: /entrypoint.sh
- deploy:
- restart_policy:
- condition: on-failure
- entrypoint: sh
- image: curlimages/curl:8.18.0
- secrets:
- - postgres_db
- - postgres_password
- - postgres_user
- volumes:
- - ../production/configurations/debezium-postgres-connector/entrypoint.sh:/entrypoint.sh:ro
- elasticsearch:
- # You cannot access the search engine via a web interface.
- environment:
- bootstrap.memory_lock: "true"
- discovery.type: single-node
- ELASTIC_PASSWORD_FILE: /run/secrets/elasticsearch-password
- ES_JAVA_OPTS: -Xms1g -Xmx1g
- KEYSTORE_PASSWORD_FILE: /run/secrets/elasticsearch-keystore_password
- network.publish_host: elasticsearch
- image: elasticsearch:8.19.12
- secrets:
- - source: elasticsearch-keystore_password
- uid: "1000"
- gid: "1000"
- mode: 0o400
- - source: elasticsearch-password
- uid: "1000"
- gid: "1000"
- mode: 0o400
- ulimits:
- nofile:
- soft: 65535
- hard: 65535
- memlock:
- soft: -1
- hard: -1
- volumes:
- - elasticsearch-configuration:/usr/share/elasticsearch/config
- - elasticsearch_data:/usr/share/elasticsearch/data
- geoip:
- # You cannot access the ip geolocator via a web interface.
- image: ghcr.io/observabilitystack/geoip-api:2026-02
- grafana:
- # You can access the observation dashboard at [grafana.app.localhost](https://grafana.app.localhost/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.grafana.entryPoints=web
- - traefik.http.routers.grafana.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.grafana.rule=Host(`grafana.${STACK_DOMAIN}`)
- - traefik.http.routers.grafana_secure.entryPoints=web-secure
- - traefik.http.routers.grafana_secure.rule=Host(`grafana.${STACK_DOMAIN}`)
- - traefik.http.routers.grafana_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.grafana.loadbalancer.server.port=3000
- environment:
- GF_DATABASE_HOST: postgres:5432
- GF_DATABASE_PASSWORD__FILE: /run/secrets/postgres_role_service_grafana_password
- GF_DATABASE_TYPE: postgres
- GF_DATABASE_USER__FILE: /run/secrets/postgres_role_service_grafana_username
- GF_SECURITY_ADMIN_EMAIL__FILE: /run/secrets/grafana_admin_email
- GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana_admin_password
- GF_SECURITY_ADMIN_USER__FILE: /run/secrets/grafana_admin_user
- GF_SERVER_ROOT_URL: https://grafana.${STACK_DOMAIN}/
- image: grafana/grafana:12.4.1
- secrets:
- - grafana_admin_email
- - grafana_admin_password
- - grafana_admin_user
- - grafana_discord_webhook
- - postgres_db
- - postgres_role_service_grafana_password
- - postgres_role_service_grafana_username
- volumes:
- - ../production/configurations/grafana/dashboards:/var/lib/grafana/dashboards:ro
- - ../production/configurations/grafana/provisioning:/etc/grafana/provisioning:ro
- - grafana_data:/var/lib/grafana
- jobber:
- # You cannot access the jobber via a web interface.
- environment:
- AWS_SHARED_CREDENTIALS_FILE: /run/secrets/jobber_aws-credentials
- image: ghcr.io/dargmuesli/jobber-aws-msmtp:1.3.0
- secrets:
- - source: jobber_aliases
- target: /etc/aliases
- - jobber_aws-bucket
- - jobber_aws-credentials
- - source: jobber_aws-configuration
- target: /home/jobberuser/.aws/config
- - source: jobber_msmtprc
- target: /etc/msmtprc
- volumes:
- - ../production/backups/postgres/:/backups/
- - ./configurations/jobber/.jobber:/home/jobberuser/.jobber:ro
- memcached:
- # You cannot access the caching system via a web interface.
- image: memcached:1.6.41-alpine
- # command: memcached -m 256M
- minio: #DARGSTACK-REMOVE
- # You can access the s3 console at [minio.app.localhost](https://minio.app.localhost/).
- # You can access the s3 api service at [s3.app.localhost](https://s3.app.localhost/) if you want to access via cli from outside the stack.
- entrypoint: /patched-entrypoint.sh #DARGSTACK-REMOVE
- command: server /data --console-address ":9001" #DARGSTACK-REMOVE
- deploy: #DARGSTACK-REMOVE
- labels: #DARGSTACK-REMOVE
- - traefik.enable=true #DARGSTACK-REMOVE
- # Minio Console
- - traefik.http.routers.minio.entryPoints=web #DARGSTACK-REMOVE
- - traefik.http.routers.minio.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.minio.rule=Host(`minio.${STACK_DOMAIN}`) #DARGSTACK-REMOVE
- - traefik.http.routers.minio.service=minio #DARGSTACK-REMOVE
- - traefik.http.routers.minio_secure.entryPoints=web-secure #DARGSTACK-REMOVE
- - traefik.http.routers.minio_secure.rule=Host(`minio.${STACK_DOMAIN}`) #DARGSTACK-REMOVE
- - traefik.http.routers.minio_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.routers.minio_secure.service=minio #DARGSTACK-REMOVE
- - traefik.http.services.minio.loadbalancer.server.port=9001 #DARGSTACK-REMOVE
- - traefik.http.services.minio.loadbalancer.passhostheader=true #DARGSTACK-REMOVE
- # Minio itself
- - traefik.http.routers.s3.entryPoints=web #DARGSTACK-REMOVE
- - traefik.http.routers.s3.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.s3.rule=Host(`s3.${STACK_DOMAIN}`) #DARGSTACK-REMOVE
- - traefik.http.routers.s3.service=s3 #DARGSTACK-REMOVE
- - traefik.http.routers.s3_secure.entryPoints=web-secure #DARGSTACK-REMOVE
- - traefik.http.routers.s3_secure.rule=Host(`s3.${STACK_DOMAIN}`) #DARGSTACK-REMOVE
- - traefik.http.routers.s3_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.routers.s3_secure.service=s3 #DARGSTACK-REMOVE
- - traefik.http.services.s3.loadbalancer.server.port=9000 #DARGSTACK-REMOVE
- - traefik.http.services.s3.loadbalancer.passhostheader=true #DARGSTACK-REMOVE
- image: minio/minio #DARGSTACK-REMOVE
- volumes: #DARGSTACK-REMOVE
- - minio_data:/data #DARGSTACK-REMOVE
- - ./configurations/minio/entrypoint.sh:/patched-entrypoint.sh #DARGSTACK-REMOVE
- environment: #DARGSTACK-REMOVE
- MINIO_ROOT_PASSWORD: s3password #DARGSTACK-REMOVE
- MINIO_ROOT_USER: s3user #DARGSTACK-REMOVE
- portainer:
- # You can access the container manager's frontend at [portainer.app.localhost](https://portainer.app.localhost/).
- command: -H tcp://tasks.portainer-agent:9001 --tlsskipverify --admin-password-file '/run/secrets/portainer_admin-password'
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.portainer.entryPoints=web
- - traefik.http.routers.portainer.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.portainer.rule=Host(`portainer.${STACK_DOMAIN}`)
- - traefik.http.routers.portainer_secure.entryPoints=web-secure
- - traefik.http.routers.portainer_secure.rule=Host(`portainer.${STACK_DOMAIN}`)
- - traefik.http.routers.portainer_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.portainer.loadbalancer.server.port=9000
- placement:
- constraints:
- - node.role == manager
- replicas: 1
- image: portainer/portainer-ce:2.39.0-alpine
- secrets:
- - portainer_admin-password
- volumes:
- - portainer_data:/data
- portainer-agent:
- # You cannot access the container manager's agent directly.
- deploy:
- mode: global
- placement:
- constraints:
- - node.platform.os == linux
- image: portainer/agent:2.39.0
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock
- - /var/lib/docker/volumes:/var/lib/docker/volumes
- postgraphile:
- # You can access the GraphQL API for the PostgreSQL database at [postgraphile.app.localhost](https://postgraphile.app.localhost/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.middlewares.postgraphile_auth.forwardauth.address=http://vibetype:3000/api/internal/service/postgraphile/authentication
- - traefik.http.middlewares.postgraphile_auth.forwardauth.forwardBody=true
- - traefik.http.middlewares.postgraphile_auth.forwardauth.preserveRequestMethod=true
- - traefik.http.middlewares.postgraphile_cors.headers.accessControlAllowCredentials=true
- - traefik.http.middlewares.postgraphile_cors.headers.accessControlAllowHeaders=authorization
- - traefik.http.middlewares.postgraphile_cors.headers.accessControlAllowOriginList=https://${STACK_DOMAIN},https://localhost:3000,https://app.localhost:3000
- - traefik.http.routers.postgraphile.entryPoints=web
- - traefik.http.routers.postgraphile.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.postgraphile.rule=Host(`postgraphile.${STACK_DOMAIN}`)
- - traefik.http.routers.postgraphile_secure.entryPoints=web-secure
- - traefik.http.routers.postgraphile_secure.middlewares=postgraphile_auth,postgraphile_cors
- - traefik.http.routers.postgraphile_secure.rule=Host(`postgraphile.${STACK_DOMAIN}`) && Path(`/graphql`)
- - traefik.http.routers.postgraphile_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.routers.postgraphile_secure_graphiql.entryPoints=web-secure
- - traefik.http.routers.postgraphile_secure_graphiql.rule=Host(`postgraphile.${STACK_DOMAIN}`)
- - traefik.http.routers.postgraphile_secure_graphiql.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.postgraphile.loadbalancer.server.port=5678
- # # Use the DEBUG environment variable for extended debugging.
- # environment:
- # DEBUG: graphile-build:warn,graphile-build-pg:sql
- image: maevsi/postgraphile:dev
- secrets:
- - source: postgraphile_connection
- target: /run/environment-variables/POSTGRAPHILE_CONNECTION
- - source: postgraphile_jwt-secret
- target: /run/environment-variables/POSTGRAPHILE_JWT_SECRET_KEY
- - source: postgraphile_owner-connection
- target: /run/environment-variables/POSTGRAPHILE_OWNER_CONNECTION
- volumes:
- - ../../../postgraphile/:/srv/app/ #DARGSTACK-REMOVE
- - ./configurations/postgraphile/jwtRS256.key.pub:/run/environment-variables/POSTGRAPHILE_JWT_PUBLIC_KEY:ro
- - pnpm_data:/srv/.pnpm-store/ #DARGSTACK-REMOVE
- - postgraphile_data:/srv/app/node_modules #DARGSTACK-REMOVE
- postgres:
- # You can access the database via `adminer`.
- command: -c vibetype.jwt_expiry_duration='1 month' -c wal_level=logical
- environment:
- POSTGRES_DB_FILE: /run/secrets/postgres_db
- POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
- POSTGRES_USER_FILE: /run/secrets/postgres_user
- image: postgis/postgis:18-3.6-alpine
- ports: #DARGSTACK-REMOVE
- - 5432:5432 #DARGSTACK-REMOVE
- secrets:
- - postgres_db
- - postgres_password
- - postgres_user
- # sysctls:
- # # Prevent Docker Swarm from killing connections (https://github.com/moby/moby/issues/31208)
- # - net.ipv4.tcp_keepalive_time=600
- # - net.ipv4.tcp_keepalive_intvl=30
- # - net.ipv4.tcp_keepalive_probes=10
- volumes:
- - postgres_data:/var/lib/postgresql/
- prometheus:
- # You can access the metrics monitoring at [prometheus.app.localhost](https://prometheus.app.localhost/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.prometheus.entryPoints=web
- - traefik.http.routers.prometheus.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.prometheus.rule=Host(`prometheus.${STACK_DOMAIN}`)
- - traefik.http.routers.prometheus_secure.entryPoints=web-secure
- - traefik.http.routers.prometheus_secure.rule=Host(`prometheus.${STACK_DOMAIN}`)
- - traefik.http.routers.prometheus_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.prometheus.loadbalancer.server.port=9090
- image: prom/prometheus:v3.10.0
- volumes:
- - ../production/configurations/prometheus/prometheus.yaml:/etc/prometheus/prometheus.yml:ro
- - prometheus_data:/prometheus
- reccoom:
- # You cannot access the recommendation service directly.
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.reccoom.entryPoints=web
- - traefik.http.routers.reccoom.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.reccoom.rule=Host(`reccoom.${STACK_DOMAIN}`)
- - traefik.http.routers.reccoom_secure.entryPoints=web-secure
- - traefik.http.routers.reccoom_secure.rule=Host(`reccoom.${STACK_DOMAIN}`)
- - traefik.http.routers.reccoom_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.reccoom.loadbalancer.server.port=5245
- environment:
- POSTGRES_HOST: postgres
- RECCOOM_POSTGRES_HOST: reccoom_postgres
- image: maevsi/reccoom:dev
- secrets:
- - postgres_db
- - postgres_password
- - postgres_user
- - source: reccoom_ingest-api-key
- target: /run/environment-variables/INGEST_API_KEY
- - reccoom_openai-api-key
- volumes:
- - ../../../reccoom/:/srv/app/ #DARGSTACK-REMOVE
- - ./configurations/postgraphile/jwtRS256.key.pub:/run/configurations/jwtRS256.key.pub:ro
- reccoom_postgres:
- # You can access reccoom's database via `adminer`.
- environment:
- POSTGRES_DB_FILE: /run/secrets/postgres_db
- POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
- POSTGRES_USER_FILE: /run/secrets/postgres_user
- image: pgvector/pgvector:0.8.2-pg18
- ports: #DARGSTACK-REMOVE
- - 5433:5432 #DARGSTACK-REMOVE
- secrets:
- - postgres_db
- - postgres_password
- - postgres_user
- volumes:
- - reccoom_postgres_data:/var/lib/postgresql/
- redis:
- # You cannot access the caching system via a web interface.
- image: redis:8.6.1-alpine
- volumes:
- - redis_data:/data
- redpanda:
- # You can access the event streaming platform's ui as described under `redpanda-console`.
- command:
- - redpanda start
- - --mode dev-container #DARGSTACK-REMOVE
- - --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092
- - --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092
- - --pandaproxy-addr internal://0.0.0.0:8082,external://0.0.0.0:18082
- - --advertise-pandaproxy-addr internal://redpanda:8082,external://localhost:18082
- - --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081
- # healthcheck:
- # test: ["CMD-SHELL", "output=$(rpk cluster health --json); echo \"$output\" | grep -q '\"healthy\":true' || { echo \"$output\"; exit 1; }"]
- # interval: 30s
- # timeout: 10s
- # retries: 3
- # start_period: 10s
- image: redpandadata/redpanda:v25.3.10
- volumes:
- - redpanda_data:/var/lib/redpanda/data
- redpanda-console:
- # You can access the event streaming platform's ui at [redpanda.app.localhost](https://redpanda.app.localhost/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.redpanda.entryPoints=web
- - traefik.http.routers.redpanda.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.redpanda.rule=Host(`redpanda.${STACK_DOMAIN}`)
- - traefik.http.routers.redpanda_secure.entryPoints=web-secure
- - traefik.http.routers.redpanda_secure.rule=Host(`redpanda.${STACK_DOMAIN}`)
- - traefik.http.routers.redpanda_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.redpanda.loadbalancer.server.port=8080
- environment:
- CONFIG_FILEPATH: /srv/app/redpanda-config.yaml
- image: redpandadata/console:v3.5.3
- volumes:
- - ../production/configurations/redpanda/config.yaml:/srv/app/redpanda-config.yaml:ro
- sqitch:
- # You cannot access the database migrations directly.
- image: maevsi/sqitch:dev
- secrets:
- - postgres_role_service_grafana_password
- - postgres_role_service_grafana_username
- - postgres_role_service_postgraphile_password
- - postgres_role_service_postgraphile_username
- - postgres_role_service_vibetype_password
- - postgres_role_service_vibetype_username
- - postgres_role_service_zammad_username
- - postgres_role_service_zammad_password
- - sqitch_target
- volumes:
- - ../../../sqitch/:/srv/app/
- traefik:
- # You can access the reverse proxy's dashboard at [traefik.app.localhost](https://traefik.app.localhost/).
- command:
- - --api=true
- - --entryPoints.web.address=:80
- - --entryPoints.web-secure.address=:443
- - --entryPoints.web-secure.http.encodedCharacters.allowEncodedSlash=true #DARGSTACK-REMOVE # required for Nuxt's virtual imports
- - --providers.swarm=true
- - --providers.swarm.endpoint=unix:///var/run/docker.sock
- - --providers.swarm.exposedByDefault=false
- - --providers.file.filename=/dynamic.yml #DARGSTACK-REMOVE
- - --providers.file.watch=true #DARGSTACK-REMOVE
- - --log.level=DEBUG #DARGSTACK-REMOVE
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.middlewares.redirectscheme.redirectscheme.scheme=https #DARGSTACK-REMOVE
- - traefik.http.routers.traefik.entryPoints=web
- - traefik.http.routers.traefik.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.traefik.rule=Host(`traefik.${STACK_DOMAIN}`)
- - traefik.http.routers.traefik.service=api@internal
- - traefik.http.routers.traefik_secure.entryPoints=web-secure
- - traefik.http.routers.traefik_secure.rule=Host(`traefik.${STACK_DOMAIN}`)
- - traefik.http.routers.traefik_secure.service=api@internal
- - traefik.http.routers.traefik_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.traefik.loadbalancer.server.port=8080
- mode: global
- placement:
- constraints:
- - node.role == manager
- image: traefik:v3.6.10
- ports: #DARGSTACK-REMOVE
- - mode: host #DARGSTACK-REMOVE
- protocol: tcp #DARGSTACK-REMOVE
- published: 80 #DARGSTACK-REMOVE
- target: 80 #DARGSTACK-REMOVE
- - mode: host #DARGSTACK-REMOVE
- protocol: tcp #DARGSTACK-REMOVE
- published: 443 #DARGSTACK-REMOVE
- target: 443 #DARGSTACK-REMOVE
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock
- - ./certificates/:/etc/traefik/acme/
- - ./configurations/traefik/dynamic.yml:/dynamic.yml:ro #DARGSTACK-REMOVE
- tusd:
- # You can access the upload service at [tusd.app.localhost](https://tusd.app.localhost/).
- command: -behind-proxy --hooks-enabled-events pre-create,pre-finish,pre-terminate --hooks-http http://vibetype:3000/api/internal/service/tusd -max-size ${TUSD_MAX_SIZE} -s3-bucket ${TUSD_BUCKET} -s3-endpoint ${TUSD_ENDPOINT}
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.middlewares.tusd_cors.headers.customresponseheaders.Cross-Origin-Resource-Policy=cross-origin
- - traefik.http.routers.tusd.entryPoints=web
- - traefik.http.routers.tusd.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.tusd.rule=Host(`tusd.${STACK_DOMAIN}`)
- - traefik.http.routers.tusd_secure.entryPoints=web-secure
- - traefik.http.routers.tusd_secure.middlewares=tusd_cors
- - traefik.http.routers.tusd_secure.rule=Host(`tusd.${STACK_DOMAIN}`) && (Method(`GET`) || Method(`HEAD`) || Method(`OPTIONS`) || Method(`POST`) || Method(`PUT`) || Method(`PATCH`))
- - traefik.http.routers.tusd_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.tusd.loadbalancer.server.port=8080
- environment:
- AWS_REGION: ${TUSD_REGION}
- image: tusproject/tusd:v2.9.1
- secrets:
- - source: tusd_aws
- target: /home/tusd/.aws/credentials
- vibetype:
- # You can access the main project's frontend at [app.localhost](https://app.localhost/).
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.middlewares.vibetype_cors.headers.accessControlAllowHeaders=authorization,content-type,hook-name,x-turnstile-key
- - traefik.http.middlewares.vibetype_cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE
- - traefik.http.middlewares.vibetype_cors.headers.accessControlAllowOriginList=https://localhost:3000,https://app.localhost:3000
- - traefik.http.middlewares.vibetype_redirectregex.redirectregex.regex=^https?:\/\/www\.${STACK_DOMAIN}\/(.*)
- - traefik.http.middlewares.vibetype_redirectregex.redirectregex.replacement=https://${STACK_DOMAIN}/$${2}
- - traefik.http.routers.vibetype.entryPoints=web
- - traefik.http.routers.vibetype.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.vibetype.rule=(Host(`${STACK_DOMAIN}`) || Host(`www.${STACK_DOMAIN}`)) && !PathPrefix(`/api/internal`)
- - traefik.http.routers.vibetype_secure.entryPoints=web-secure
- - traefik.http.routers.vibetype_secure.middlewares=vibetype_cors,vibetype_redirectregex
- - traefik.http.routers.vibetype_secure.rule=(Host(`${STACK_DOMAIN}`) || Host(`www.${STACK_DOMAIN}`)) && !PathPrefix(`/api/internal`)
- - traefik.http.routers.vibetype_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.vibetype.loadbalancer.server.port=3000
- environment:
- AWS_REGION: ${VIBETYPE_AWS_REGION}
- NUXT_PUBLIC_GTAG_ID: ${VIBETYPE_NUXT_PUBLIC_GTAG_ID}
- NUXT_PUBLIC_I18N_BASE_URL: https://${STACK_DOMAIN}
- NUXT_PUBLIC_SITE_URL: https://${STACK_DOMAIN}
- NUXT_PUBLIC_TURNSTILE_SITE_KEY: ${VIBETYPE_NUXT_PUBLIC_TURNSTILE_SITE_KEY}
- NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H: ${VIBETYPE_NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H}
- PGHOST: postgres
- image: maevsi/vibetype:dev
- secrets:
- - source: vibetype_api-notification-secret
- target: /run/environment-variables/NUXT_PRIVATE_API_NOTIFICATION_SECRET
- - source: vibetype_aws-credentials
- target: /home/node/.aws/credentials
- - source: vibetype_firebase-service-account-credentials
- target: /run/environment-variables/FIREBASE_SERVICE_ACCOUNT_CREDENTIALS
- - source: vibetype_monday
- target: /run/environment-variables/NUXT_PRIVATE_MONDAY
- - source: vibetype_openai-api-key
- target: /run/environment-variables/NUXT_PRIVATE_OPENAI_API_KEY
- - source: vibetype_turnstile-key
- target: /run/environment-variables/NUXT_TURNSTILE_SECRET_KEY
- - source: postgres_db
- target: /run/environment-variables/PGDATABASE
- - source: postgres_role_service_vibetype_password
- target: /run/environment-variables/PGPASSWORD
- - source: postgres_role_service_vibetype_username
- target: /run/environment-variables/PGUSER
- user: node:node # files created inside a docker container, like node_modules by pnpm, gain correct permissions by setting the user to `node`
- volumes:
- - pnpm_data:/srv/.pnpm-store/ #DARGSTACK-REMOVE
- - ./certificates/:/srv/certificates/ #DARGSTACK-REMOVE
- - ../../../vibetype/:/srv/app/ #DARGSTACK-REMOVE
- - vibetype_data:/srv/app/node_modules #DARGSTACK-REMOVE
- - ./configurations/postgraphile/jwtRS256.key.pub:/run/environment-variables/NUXT_PUBLIC_VIO_AUTH_JWT_PUBLIC_KEY:ro
- zammad-backup:
- # You cannot access the helpdesk backup service via a web interface.
- <<: *zammad-service
- command: ["zammad-backup"]
- user: 0:0
- volumes:
- - zammad-backup_data:/var/tmp/zammad
- - zammad_data:/opt/zammad/storage:ro
- - ../production/configurations/zammad/docker-entrypoint.sh:/docker-entrypoint.sh:ro
- zammad-init:
- # You cannot access the helpdesk initialization service via a web interface.
- <<: *zammad-service
- command: ["zammad-init"]
- deploy:
- restart_policy:
- condition: on-failure
- user: 0:0
- zammad-nginx:
- # You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
- <<: *zammad-service
- command: ["zammad-nginx"]
- deploy:
- labels:
- - traefik.enable=true
- - traefik.http.routers.zammad.entryPoints=web
- - traefik.http.routers.zammad.middlewares=redirectscheme #DARGSTACK-REMOVE
- - traefik.http.routers.zammad.rule=Host(`zammad.${STACK_DOMAIN}`)
- - traefik.http.routers.zammad_secure.entryPoints=web-secure
- - traefik.http.routers.zammad_secure.rule=Host(`zammad.${STACK_DOMAIN}`)
- - traefik.http.routers.zammad_secure.tls.options=mintls13@file #DARGSTACK-REMOVE
- - traefik.http.services.zammad.loadbalancer.server.port=8080
- zammad-railsserver:
- # You cannot access the helpdesk application server directly.
- <<: *zammad-service
- command: ["zammad-railsserver"]
- zammad-scheduler:
- # You cannot access the helpdesk scheduler directly.
- <<: *zammad-service
- command: ["zammad-scheduler"]
- zammad-websocket:
- # You cannot access the helpdesk websocket server directly.
- <<: *zammad-service
- command: ["zammad-websocket"]
-version: "3.7"
-volumes:
- debezium_kafka_configuration:
- # The change data capture's configuration.
- {}
- debezium_kafka_data:
- # The change data capture's data.
- {}
- debezium_kafka_logs:
- # The change data capture's logs.
- {}
- elasticsearch-configuration:
- # The search engine's configuration.
- {}
- elasticsearch_data:
- # The search engine's data.
- {}
- grafana_data:
- # The observation dashboard's data.
- {}
- minio_data:
- # The s3 server's data.
- {}
- pnpm_data:
- # The node package manager's data.
- {}
- portainer_data:
- # The container manager's data.
- {}
- postgraphile_data:
- # The GraphQL API's data.
- {}
- postgres_data:
- # The database's data.
- {}
- prometheus_data:
- # The metrics monitoring's data.
- {}
- reccoom_postgres_data:
- # The recommendation database's data.
- {}
- redis_data:
- # The caching system's data.
- {}
- redpanda_data:
- # The message queue's data.
- {}
- vibetype_data:
- # The frontend's data.
- {}
- zammad-backup_data:
- # The helpdesk backup's data.
- {}
- zammad_data:
- # The helpdesk's data.
- {}
diff --git a/src/development/traefik/compose.yaml b/src/development/traefik/compose.yaml
new file mode 100644
index 00000000..a93c1d99
--- /dev/null
+++ b/src/development/traefik/compose.yaml
@@ -0,0 +1,46 @@
+services:
+ traefik:
+ # You can access the reverse proxy's dashboard at [traefik.app.localhost](https://traefik.app.localhost/).
+ command:
+ - --api=true
+ - --entryPoints.web.address=:80
+ - --entryPoints.web-secure.address=:443
+ - --entryPoints.web-secure.http.encodedCharacters.allowEncodedSlash=true # dargstack:dev-only # required for Nuxt's virtual imports
+ - --providers.swarm=true
+ - --providers.swarm.endpoint=unix:///var/run/docker.sock
+ - --providers.swarm.exposedByDefault=false
+ - --providers.file.filename=/dynamic.yml # dargstack:dev-only
+ - --providers.file.watch=true # dargstack:dev-only
+ - --log.level=DEBUG # dargstack:dev-only
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ - traefik.enable=true
+ - traefik.http.middlewares.redirectscheme.redirectscheme.scheme=https # dargstack:dev-only
+ - traefik.http.routers.traefik.entryPoints=web
+ - traefik.http.routers.traefik.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.traefik.rule=Host(`traefik.${STACK_DOMAIN}`)
+ - traefik.http.routers.traefik.service=api@internal
+ - traefik.http.routers.traefik-secure.entryPoints=web-secure
+ - traefik.http.routers.traefik-secure.rule=Host(`traefik.${STACK_DOMAIN}`)
+ - traefik.http.routers.traefik-secure.service=api@internal
+ - traefik.http.routers.traefik-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.traefik.loadbalancer.server.port=8080
+ mode: global
+ placement:
+ constraints:
+ - node.role == manager
+ image: traefik:v3.6.10
+ ports: # dargstack:dev-only
+ - mode: host # dargstack:dev-only
+ protocol: tcp # dargstack:dev-only
+ published: 80 # dargstack:dev-only
+ target: 80 # dargstack:dev-only
+ - mode: host # dargstack:dev-only
+ protocol: tcp # dargstack:dev-only
+ published: 443 # dargstack:dev-only
+ target: 443 # dargstack:dev-only
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - ../../../artifacts/certificates/:/etc/traefik/acme/
+ - ./configurations/dynamic.yml:/dynamic.yml:ro # dargstack:dev-only
diff --git a/src/development/traefik/configurations/dynamic.yml b/src/development/traefik/configurations/dynamic.yml
new file mode 100644
index 00000000..705f4828
--- /dev/null
+++ b/src/development/traefik/configurations/dynamic.yml
@@ -0,0 +1,7 @@
+tls:
+ certificates:
+ - certFile: /etc/traefik/acme/localhost.pem
+ keyFile: /etc/traefik/acme/localhost-key.pem
+ options:
+ mintls13:
+ minVersion: VersionTLS13
diff --git a/src/development/tusd/compose.yaml b/src/development/tusd/compose.yaml
new file mode 100644
index 00000000..cf1e2233
--- /dev/null
+++ b/src/development/tusd/compose.yaml
@@ -0,0 +1,35 @@
+secrets:
+ tusd-aws:
+ # The upload service's s3 credentials file.
+ file: ../../../artifacts/secrets/tusd-aws.secret
+services:
+ tusd:
+ # You can access the upload service at [tusd.app.localhost](https://tusd.app.localhost/).
+ command: -behind-proxy --hooks-enabled-events pre-create,pre-finish,pre-terminate --hooks-http http://vibetype:3000/api/internal/service/tusd -max-size ${TUSD_MAX_SIZE} -s3-bucket ${TUSD_BUCKET} -s3-endpoint ${TUSD_ENDPOINT}
+ deploy:
+ labels:
+ - dargstack.profiles=upload
+ - traefik.enable=true
+ - traefik.http.middlewares.tusd-cors.headers.customresponseheaders.Cross-Origin-Resource-Policy=cross-origin
+ - traefik.http.routers.tusd.entryPoints=web
+ - traefik.http.routers.tusd.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.tusd.rule=Host(`tusd.${STACK_DOMAIN}`)
+ - traefik.http.routers.tusd-secure.entryPoints=web-secure
+ - traefik.http.routers.tusd-secure.middlewares=tusd-cors
+ - traefik.http.routers.tusd-secure.rule=Host(`tusd.${STACK_DOMAIN}`) && (Method(`GET`) || Method(`HEAD`) || Method(`OPTIONS`) || Method(`POST`) || Method(`PUT`) || Method(`PATCH`))
+ - traefik.http.routers.tusd-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.tusd.loadbalancer.server.port=8080
+ environment:
+ AWS_REGION: ${TUSD_REGION}
+ image: tusproject/tusd:v2.9.1
+ secrets:
+ - source: tusd-aws
+ target: /home/tusd/.aws/credentials
+x-dargstack:
+ secrets:
+ tusd-aws:
+ insecure_default: |
+ [default]
+ aws_access_key_id = s3user
+ aws_secret_access_key = s3password
+ type: insecure_default
diff --git a/src/development/secrets/tusd/aws.secret.template b/src/development/tusd/secrets/aws.secret.template
similarity index 100%
rename from src/development/secrets/tusd/aws.secret.template
rename to src/development/tusd/secrets/aws.secret.template
diff --git a/src/development/vibetype/compose.yaml b/src/development/vibetype/compose.yaml
new file mode 100644
index 00000000..94c380c0
--- /dev/null
+++ b/src/development/vibetype/compose.yaml
@@ -0,0 +1,93 @@
+secrets:
+ vibetype-api-notification-secret:
+ # The notification endpoint's secret.
+ file: ../../../artifacts/secrets/vibetype-api-notification.secret
+ vibetype-aws-credentials:
+ # The cloud computing provider's user credentials.
+ file: ../../../artifacts/secrets/vibetype-aws-credentials.secret
+ vibetype-firebase-service-account-credentials:
+ # The notification provider's service account credentials.
+ file: ../../../artifacts/secrets/vibetype-firebase-service-account-credentials.secret
+ vibetype-monday:
+ # The project management software's configuration.
+ file: ../../../artifacts/secrets/vibetype-monday.secret
+ vibetype-openai-api-key:
+ # The AI provider's API key for the frontend.
+ file: ../../../artifacts/secrets/vibetype-openai-api-key.secret
+ vibetype-turnstile-key:
+ # The captcha provider's application key.
+ file: ../../../artifacts/secrets/vibetype-turnstile-key.secret
+services:
+ vibetype:
+ # You can access the main project's frontend at [app.localhost](https://app.localhost/).
+ deploy:
+ labels:
+ - dargstack.development.build=../../../../vibetype
+ - dargstack.profiles=default
+ - traefik.enable=true
+ - traefik.http.middlewares.vibetype-cors.headers.accessControlAllowHeaders=authorization,content-type,hook-name,x-turnstile-key
+ - traefik.http.middlewares.vibetype-cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE
+ - traefik.http.middlewares.vibetype-cors.headers.accessControlAllowOriginList=https://localhost:3000,https://app.localhost:3000
+ - traefik.http.middlewares.vibetype-redirectregex.redirectregex.regex=^https?:\/\/www\.${STACK_DOMAIN}\/(.*)
+ - traefik.http.middlewares.vibetype-redirectregex.redirectregex.replacement=https://${STACK_DOMAIN}/$${1}
+ - traefik.http.routers.vibetype.entryPoints=web
+ - traefik.http.routers.vibetype.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.vibetype.rule=(Host(`${STACK_DOMAIN}`) || Host(`www.${STACK_DOMAIN}`)) && !PathPrefix(`/api/internal`)
+ - traefik.http.routers.vibetype-secure.entryPoints=web-secure
+ - traefik.http.routers.vibetype-secure.middlewares=vibetype-cors,vibetype-redirectregex
+ - traefik.http.routers.vibetype-secure.rule=(Host(`${STACK_DOMAIN}`) || Host(`www.${STACK_DOMAIN}`)) && !PathPrefix(`/api/internal`)
+ - traefik.http.routers.vibetype-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.vibetype.loadbalancer.server.port=3000
+ environment:
+ AWS_REGION: ${VIBETYPE_AWS_REGION}
+ NUXT_PUBLIC_GTAG_ID: ${VIBETYPE_NUXT_PUBLIC_GTAG_ID}
+ NUXT_PUBLIC_I18N_BASE_URL: https://${STACK_DOMAIN}
+ NUXT_PUBLIC_SITE_URL: https://${STACK_DOMAIN}
+ NUXT_PUBLIC_TURNSTILE_SITE_KEY: ${VIBETYPE_NUXT_PUBLIC_TURNSTILE_SITE_KEY}
+ NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H: ${VIBETYPE_NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H}
+ PGHOST: postgres
+ image: vibetype/vibetype:development
+ secrets:
+ - source: vibetype-api-notification-secret
+ target: /run/environment-variables/NUXT_PRIVATE_API_NOTIFICATION_SECRET
+ - source: vibetype-aws-credentials
+ target: /home/node/.aws/credentials
+ - source: vibetype-firebase-service-account-credentials
+ target: /run/environment-variables/FIREBASE_SERVICE_ACCOUNT_CREDENTIALS
+ - source: vibetype-monday
+ target: /run/environment-variables/NUXT_PRIVATE_MONDAY
+ - source: vibetype-openai-api-key
+ target: /run/environment-variables/NUXT_PRIVATE_OPENAI_API_KEY
+ - source: vibetype-turnstile-key
+ target: /run/environment-variables/NUXT_TURNSTILE_SECRET_KEY
+ - source: postgres-db
+ target: /run/environment-variables/PGDATABASE
+ - source: postgres-role-service-vibetype-password
+ target: /run/environment-variables/PGPASSWORD
+ - source: postgres-role-service-vibetype-username
+ target: /run/environment-variables/PGUSER
+ user: node:node # files created inside a docker container, like node_modules by pnpm, gain correct permissions by setting the user to `node`
+ volumes:
+ - pnpm-data:/srv/.pnpm-store/ # dargstack:dev-only
+ - ../../../artifacts/certificates/:/srv/certificates/ # dargstack:dev-only
+ - ../../../../vibetype/:/srv/app/ # dargstack:dev-only
+ - vibetype-data:/srv/app/node_modules # dargstack:dev-only
+ - ../postgraphile/configurations/jwtES256.key.pub:/run/environment-variables/NUXT_PUBLIC_VIO_AUTH_JWT_PUBLIC_KEY:ro
+volumes:
+ vibetype-data:
+ # The frontend's data.
+ {}
+x-dargstack:
+ secrets:
+ vibetype-api-notification-secret:
+ type: random_string
+ vibetype-aws-credentials:
+ type: third_party
+ vibetype-firebase-service-account-credentials:
+ type: third_party
+ vibetype-monday:
+ type: third_party
+ vibetype-openai-api-key:
+ type: third_party
+ vibetype-turnstile-key:
+ type: third_party
diff --git a/src/development/secrets/vibetype/api-notification.secret.template b/src/development/vibetype/secrets/api-notification.secret.template
similarity index 100%
rename from src/development/secrets/vibetype/api-notification.secret.template
rename to src/development/vibetype/secrets/api-notification.secret.template
diff --git a/src/development/secrets/vibetype/aws-credentials.secret.template b/src/development/vibetype/secrets/aws-credentials.secret.template
similarity index 100%
rename from src/development/secrets/vibetype/aws-credentials.secret.template
rename to src/development/vibetype/secrets/aws-credentials.secret.template
diff --git a/src/development/secrets/vibetype/firebase-service-account-credentials.secret.template b/src/development/vibetype/secrets/firebase-service-account-credentials.secret.template
similarity index 100%
rename from src/development/secrets/vibetype/firebase-service-account-credentials.secret.template
rename to src/development/vibetype/secrets/firebase-service-account-credentials.secret.template
diff --git a/src/development/secrets/vibetype/monday.template b/src/development/vibetype/secrets/monday.template
similarity index 100%
rename from src/development/secrets/vibetype/monday.template
rename to src/development/vibetype/secrets/monday.template
diff --git a/src/development/secrets/vibetype/openai-api-key.secret.template b/src/development/vibetype/secrets/openai-api-key.secret.template
similarity index 100%
rename from src/development/secrets/vibetype/openai-api-key.secret.template
rename to src/development/vibetype/secrets/openai-api-key.secret.template
diff --git a/src/development/secrets/vibetype/turnstile-key.secret.template b/src/development/vibetype/secrets/turnstile-key.secret.template
similarity index 100%
rename from src/development/secrets/vibetype/turnstile-key.secret.template
rename to src/development/vibetype/secrets/turnstile-key.secret.template
diff --git a/src/development/zammad/compose.yaml b/src/development/zammad/compose.yaml
new file mode 100644
index 00000000..e3f1f6d7
--- /dev/null
+++ b/src/development/zammad/compose.yaml
@@ -0,0 +1,82 @@
+x-shared:
+ zammad-service:
+ &zammad-service # You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ environment: &zammad-environment
+ ELASTICSEARCH_HOST: elasticsearch
+ ELASTICSEARCH_SCHEMA: https
+ ELASTICSEARCH_USER: elastic
+ MEMCACHE_SERVERS: memcached:11211
+ NGINX_SERVER_SCHEME: https
+ POSTGRESQL_DB: zammad
+ POSTGRESQL_DB_CREATE: "false"
+ POSTGRESQL_HOST: postgres
+ POSTGRESQL_OPTIONS: ?pool=50
+ REDIS_URL: redis://redis:6379
+ image: ghcr.io/zammad/zammad:6.5.2-90
+ secrets:
+ - source: elasticsearch-password
+ target: /run/environment-variables/ELASTICSEARCH_PASS
+ - source: postgres-role-service-zammad-username
+ target: /run/environment-variables/POSTGRESQL_USER
+ - source: postgres-role-service-zammad-password
+ target: /run/environment-variables/POSTGRESQL_PASS
+ volumes:
+ - zammad-data:/opt/zammad/storage
+ - ./configurations/docker-entrypoint.sh:/docker-entrypoint.sh:ro
+services:
+ zammad-backup:
+ # You cannot access the helpdesk backup service via a web interface.
+ <<: *zammad-service
+ command: ["zammad-backup"]
+ user: 0:0
+ volumes:
+ - zammad-backup-data:/var/tmp/zammad
+ - zammad-data:/opt/zammad/storage:ro
+ - ./configurations/docker-entrypoint.sh:/docker-entrypoint.sh:ro
+ zammad-init:
+ # You cannot access the helpdesk initialization service via a web interface.
+ <<: *zammad-service
+ command: ["zammad-init"]
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ restart_policy:
+ condition: on-failure
+ user: 0:0
+ zammad-nginx:
+ # You can access the helpdesk at [zammad.app.localhost](https://zammad.app.localhost/).
+ <<: *zammad-service
+ command: ["zammad-nginx"]
+ deploy:
+ labels:
+ - dargstack.profiles=zammad
+ - traefik.enable=true
+ - traefik.http.routers.zammad.entryPoints=web
+ - traefik.http.routers.zammad.middlewares=redirectscheme # dargstack:dev-only
+ - traefik.http.routers.zammad.rule=Host(`zammad.${STACK_DOMAIN}`)
+ - traefik.http.routers.zammad-secure.entryPoints=web-secure
+ - traefik.http.routers.zammad-secure.rule=Host(`zammad.${STACK_DOMAIN}`)
+ - traefik.http.routers.zammad-secure.tls.options=mintls13@file # dargstack:dev-only
+ - traefik.http.services.zammad.loadbalancer.server.port=8080
+ zammad-railsserver:
+ # You cannot access the helpdesk application server directly.
+ <<: *zammad-service
+ command: ["zammad-railsserver"]
+ zammad-scheduler:
+ # You cannot access the helpdesk scheduler directly.
+ <<: *zammad-service
+ command: ["zammad-scheduler"]
+ zammad-websocket:
+ # You cannot access the helpdesk websocket server directly.
+ <<: *zammad-service
+ command: ["zammad-websocket"]
+volumes:
+ zammad-backup-data:
+ # The helpdesk backup's data.
+ {}
+ zammad-data:
+ # The helpdesk's data.
+ {}
diff --git a/src/production/configurations/zammad/docker-entrypoint.sh b/src/development/zammad/configurations/docker-entrypoint.sh
similarity index 100%
rename from src/production/configurations/zammad/docker-entrypoint.sh
rename to src/development/zammad/configurations/docker-entrypoint.sh
diff --git a/src/production/adminer/compose.yaml b/src/production/adminer/compose.yaml
new file mode 100644
index 00000000..cbe52b06
--- /dev/null
+++ b/src/production/adminer/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ adminer:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.adminer-secure.tls.certresolver=default
diff --git a/src/production/backups/postgres/README.md b/src/production/backups/postgres/README.md
deleted file mode 100644
index a78acebf..00000000
--- a/src/production/backups/postgres/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-This directory contains backups created by [prodrigestivill/postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local).
diff --git a/src/production/cloudflared/compose.yaml b/src/production/cloudflared/compose.yaml
new file mode 100644
index 00000000..9fddd7ed
--- /dev/null
+++ b/src/production/cloudflared/compose.yaml
@@ -0,0 +1,10 @@
+services:
+ cloudflared:
+ # You can configure the secure tunnel at [dash.cloudflare.com](https://dash.cloudflare.com/).
+ command: tunnel run
+ deploy:
+ labels:
+ - dargstack.profiles=default
+ environment:
+ TUNNEL_TOKEN: ${CLOUDFLARED_TUNNEL_TOKEN}
+ image: cloudflare/cloudflared
diff --git a/src/production/compose.yaml b/src/production/compose.yaml
new file mode 100644
index 00000000..adefef00
--- /dev/null
+++ b/src/production/compose.yaml
@@ -0,0 +1,2 @@
+volumes:
+ pnpm-data: (( prune ))
diff --git a/src/production/configurations/adminer/adminer.css b/src/production/configurations/adminer/adminer.css
deleted file mode 100755
index c77609cb..00000000
--- a/src/production/configurations/adminer/adminer.css
+++ /dev/null
@@ -1,7 +0,0 @@
-a {
- color: blue;
-}
-
-a:visited {
- color: blue;
-}
diff --git a/src/production/configurations/grafana/provisioning/datasources/postgres.yaml b/src/production/configurations/grafana/provisioning/datasources/postgres.yaml
deleted file mode 100644
index f39d522b..00000000
--- a/src/production/configurations/grafana/provisioning/datasources/postgres.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: 1
-
-datasources:
- - access: proxy
- jsonData:
- database: $__file{/run/secrets/postgres_db}
- postgresVersion: 1500
- sslmode: 'disable'
- name: PostgreSQL
- secureJsonData:
- password: $__file{/run/secrets/postgres_role_service_grafana_password}
- type: grafana-postgresql-datasource
- url: postgres:5432
- user: $__file{/run/secrets/postgres_role_service_grafana_username}
diff --git a/src/production/grafana/compose.yaml b/src/production/grafana/compose.yaml
new file mode 100644
index 00000000..703cdaa0
--- /dev/null
+++ b/src/production/grafana/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ grafana:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.grafana-secure.tls.certresolver=default
diff --git a/src/production/jobber/compose.yaml b/src/production/jobber/compose.yaml
new file mode 100644
index 00000000..df5db9ff
--- /dev/null
+++ b/src/production/jobber/compose.yaml
@@ -0,0 +1,7 @@
+services:
+ jobber:
+ environment:
+ SENTRY_CRONS: ${SENTRY_CRONS}
+ volumes:
+ - (( append ))
+ - postgres-backup-data:/backups/
diff --git a/src/production/configurations/jobber/.jobber b/src/production/jobber/configurations/.jobber
similarity index 100%
rename from src/production/configurations/jobber/.jobber
rename to src/production/jobber/configurations/.jobber
diff --git a/src/production/minio/compose.yaml b/src/production/minio/compose.yaml
new file mode 100644
index 00000000..afb70a8c
--- /dev/null
+++ b/src/production/minio/compose.yaml
@@ -0,0 +1,4 @@
+# services:
+# minio: (( prune )) # breaks renovate
+volumes:
+ minio_data: (( prune ))
diff --git a/src/production/portainer/compose.yaml b/src/production/portainer/compose.yaml
new file mode 100644
index 00000000..4d42fef0
--- /dev/null
+++ b/src/production/portainer/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ portainer:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.portainer-secure.tls.certresolver=default
diff --git a/src/production/postgraphile/compose.yaml b/src/production/postgraphile/compose.yaml
new file mode 100644
index 00000000..abc134da
--- /dev/null
+++ b/src/production/postgraphile/compose.yaml
@@ -0,0 +1,8 @@
+services:
+ postgraphile:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.postgraphile.middlewares=postgraphile-auth,postgraphile-cors
+ - traefik.http.routers.postgraphile-secure.tls.certresolver=default
+ image: maevsi/postgraphile:2.0.0-beta.1
diff --git a/src/production/configurations/postgraphile/jwtRS256.key.pub b/src/production/postgraphile/configurations/jwtRS256.key.pub
similarity index 100%
rename from src/production/configurations/postgraphile/jwtRS256.key.pub
rename to src/production/postgraphile/configurations/jwtRS256.key.pub
diff --git a/src/production/postgres/compose.yaml b/src/production/postgres/compose.yaml
new file mode 100644
index 00000000..a85f6aad
--- /dev/null
+++ b/src/production/postgres/compose.yaml
@@ -0,0 +1,24 @@
+secrets:
+ postgres-backup-db:
+ # The database's name.
+ external: true
+services:
+ postgres-backup:
+ # You cannot access the database backup directly.
+ environment:
+ POSTGRES_DB_FILE: /run/secrets/postgres-backup-db
+ POSTGRES_HOST: postgres
+ POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
+ POSTGRES_USER_FILE: /run/secrets/postgres-user
+ image: prodrigestivill/postgres-backup-local:18-alpine
+ secrets:
+ - postgres-backup-db
+ - postgres-password
+ - postgres-user
+ volumes:
+ - postgres-data:/var/lib/postgresql/
+ - postgres-backup-data:/backups/
+volumes:
+ postgres-backup-data:
+ # The database backup's data.
+ {}
diff --git a/src/production/production.env.template b/src/production/production.env.template
deleted file mode 100644
index 8ffc032b..00000000
--- a/src/production/production.env.template
+++ /dev/null
@@ -1,5 +0,0 @@
-CLOUDFLARED_TUNNEL_TOKEN=
-SENTRY_CRONS=
-STACK_DOMAIN=
-TRAEFIK_ACME_EMAIL=
-TRAEFIK_ACME_PROVIDER=
\ No newline at end of file
diff --git a/src/production/production.yml b/src/production/production.yml
deleted file mode 100644
index beca404e..00000000
--- a/src/production/production.yml
+++ /dev/null
@@ -1,177 +0,0 @@
-secrets:
- postgres-backup_db:
- # The database's name.
- external: true
- traefik_cf-dns-api-token:
- # The DNS provider's DNS API token.
- external: true
- traefik_cf-zone-api-token:
- # The DNS provider's zone API token.
- external: true
-services:
- adminer:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.adminer_secure.tls.certresolver=default
- cloudflared:
- # You can configure the secure tunnel at [dash.cloudflare.com](https://dash.cloudflare.com/).
- command: tunnel run
- environment:
- TUNNEL_TOKEN: ${CLOUDFLARED_TUNNEL_TOKEN}
- image: cloudflare/cloudflared
- grafana:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.grafana_secure.tls.certresolver=default
- jobber:
- environment:
- SENTRY_CRONS: ${SENTRY_CRONS}
- volumes:
- - (( append ))
- - ./configurations/jobber/sinks:/srv/sinks:ro
- # minio: (( prune )) # breaks renovate
- portainer:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.portainer_secure.tls.certresolver=default
- postgraphile:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.postgraphile.middlewares=postgraphile_auth,postgraphile_cors
- - traefik.http.routers.postgraphile_secure.tls.certresolver=default
- image: maevsi/postgraphile:2.0.0-beta.1
- postgres_backup:
- # You cannot access the database backup directly.
- environment:
- POSTGRES_DB_FILE: /run/secrets/postgres-backup_db
- POSTGRES_HOST: postgres
- POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
- POSTGRES_USER_FILE: /run/secrets/postgres_user
- image: prodrigestivill/postgres-backup-local:18-alpine
- secrets:
- - postgres-backup_db
- - postgres_password
- - postgres_user
- volumes:
- - postgres_data:/var/lib/postgresql/
- - ../production/backups/postgres/:/backups/
- prometheus:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.prometheus_secure.tls.certresolver=default
- reccoom:
- deploy: (( prune ))
- image: ghcr.io/maevsi/reccoom:0.8.1
- redpanda-console:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.redpanda_secure.tls.certresolver=default
- sqitch:
- image: ghcr.io/maevsi/sqitch:10.0.6
- volumes: (( prune ))
- traefik:
- command:
- - (( prepend ))
- - --certificatesResolvers.default.acme.email=${TRAEFIK_ACME_EMAIL}
- - --certificatesResolvers.default.acme.storage=/etc/traefik/acme/acme.json
- - --certificatesResolvers.default.acme.dnsChallenge.provider=${TRAEFIK_ACME_PROVIDER}
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.traefik_secure.tls.certresolver=default
- environment:
- CF_DNS_API_TOKEN_FILE: /run/secrets/traefik_cf-dns-api-token
- CF_ZONE_API_TOKEN_FILE: /run/secrets/traefik_cf-zone-api-token
- secrets:
- - traefik_cf-dns-api-token
- - traefik_cf-zone-api-token
- traefik_certs-dumper:
- # You cannot access the reverse proxy's certificate helper directly.
- command:
- - file
- - --clean=false
- - --crt-name="$STACK_DOMAIN"
- - --dest=/etc/traefik/acme/
- - --key-name="$STACK_DOMAIN"
- - --source=/etc/traefik/acme/acme.json
- - --version=v2
- - --watch
- environment:
- STACK_DOMAIN: ${STACK_DOMAIN}
- image: ldez/traefik-certs-dumper:v2.11.0
- volumes:
- - acme_data:/etc/traefik/acme/
- tusd:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.tusd.middlewares=tusd_cors
- - traefik.http.routers.tusd_secure.tls.certresolver=default
- vibetype:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.vibetype.middlewares=vibetype_cors,vibetype_redirectregex
- - traefik.http.routers.vibetype_secure.tls.certresolver=default
- image: ghcr.io/maevsi/vibetype:13.3.3
- user: (( prune ))
- # vibetype_beta:
- # # You can access the main project frontend's beta version at [beta.app.localhost](https://beta.app.localhost/).
- # deploy:
- # labels:
- # - traefik.enable=true
- # - traefik.http.routers.vibetype_beta.entryPoints=web
- # - traefik.http.routers.vibetype_beta.middlewares=vibetype_cors,vibetype_redirectregex
- # - traefik.http.routers.vibetype_beta.rule=Host(`beta.${STACK_DOMAIN}`)
- # - traefik.http.routers.vibetype_beta_secure.entryPoints=web-secure
- # - traefik.http.routers.vibetype_beta_secure.middlewares=vibetype_cors,vibetype_redirectregex
- # - traefik.http.routers.vibetype_beta_secure.rule=Host(`beta.${STACK_DOMAIN}`)
- # - traefik.http.services.vibetype_beta.loadbalancer.server.port=3000
- # - traefik.http.routers.vibetype_beta_secure.tls.certresolver=default
- # environment:
- # AWS_REGION: ${VIBETYPE_AWS_REGION}
- # NUXT_PUBLIC_GTAG_ID: ${VIBETYPE_NUXT_PUBLIC_GTAG_ID}
- # NUXT_PUBLIC_I18N_BASE_URL: https://${STACK_DOMAIN}
- # NUXT_PUBLIC_SITE_URL: https://${STACK_DOMAIN}
- # NUXT_PUBLIC_TURNSTILE_SITE_KEY: ${VIBETYPE_NUXT_PUBLIC_TURNSTILE_SITE_KEY}
- # NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H: ${VIBETYPE_NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H}
- # NUXT_PUBLIC_VIO_ENVIRONMENT: beta
- # PGHOST: postgres
- # image: ghcr.io/maevsi/vibetype:11.0.2
- # secrets:
- # - source: vibetype_api-notification-secret
- # target: /run/environment-variables/NUXT_PRIVATE_API_NOTIFICATION_SECRET
- # - source: vibetype_aws-credentials
- # target: /home/node/.aws/credentials # TODO: switch to user `node`
- # - source: vibetype_firebase-service-account-credentials
- # target: /run/environment-variables/FIREBASE_SERVICE_ACCOUNT_CREDENTIALS
- # - source: vibetype_openai-api-key
- # target: /run/environment-variables/NUXT_PRIVATE_OPENAI_API_KEY
- # - source: vibetype_turnstile-key
- # target: /run/environment-variables/NUXT_TURNSTILE_SECRET_KEY
- # - source: postgres_db
- # target: /run/environment-variables/PGDATABASE
- # - source: postgres_role_service_vibetype_password
- # target: /run/environment-variables/PGPASSWORD
- # - source: postgres_role_service_vibetype_username
- # target: /run/environment-variables/PGUSER
- # volumes:
- # - ./configurations/postgraphile/jwtRS256.key.pub:/run/environment-variables/NUXT_PUBLIC_VIO_AUTH_JWT_PUBLIC_KEY:ro
- zammad-nginx:
- deploy:
- labels:
- - (( append ))
- - traefik.http.routers.zammad_secure.tls.certresolver=default
-version: "3.7"
-volumes:
- acme_data:
- # The reverse proxy's certificate data.
- {}
- minio_data: (( prune ))
- vibetype_data: (( prune ))
diff --git a/src/production/prometheus/compose.yaml b/src/production/prometheus/compose.yaml
new file mode 100644
index 00000000..f899c1f5
--- /dev/null
+++ b/src/production/prometheus/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ prometheus:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.prometheus-secure.tls.certresolver=default
diff --git a/src/production/reccoom/compose.yaml b/src/production/reccoom/compose.yaml
new file mode 100644
index 00000000..0690e333
--- /dev/null
+++ b/src/production/reccoom/compose.yaml
@@ -0,0 +1,4 @@
+services:
+ reccoom:
+ deploy: (( prune ))
+ image: ghcr.io/maevsi/reccoom:0.8.1
diff --git a/src/production/redpanda/compose.yaml b/src/production/redpanda/compose.yaml
new file mode 100644
index 00000000..224787c6
--- /dev/null
+++ b/src/production/redpanda/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ redpanda-console:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.redpanda-secure.tls.certresolver=default
diff --git a/src/production/sqitch/compose.yaml b/src/production/sqitch/compose.yaml
new file mode 100644
index 00000000..e1a9dc91
--- /dev/null
+++ b/src/production/sqitch/compose.yaml
@@ -0,0 +1,4 @@
+services:
+ sqitch:
+ image: ghcr.io/maevsi/sqitch:10.0.6
+ volumes: (( prune ))
diff --git a/src/production/traefik/compose.yaml b/src/production/traefik/compose.yaml
new file mode 100644
index 00000000..a7f41d9c
--- /dev/null
+++ b/src/production/traefik/compose.yaml
@@ -0,0 +1,44 @@
+secrets:
+ traefik-cf-dns-api-token:
+ # The DNS provider's DNS API token.
+ external: true
+ traefik-cf-zone-api-token:
+ # The DNS provider's zone API token.
+ external: true
+services:
+ traefik:
+ command:
+ - (( prepend ))
+ - --certificatesResolvers.default.acme.email=${TRAEFIK_ACME_EMAIL}
+ - --certificatesResolvers.default.acme.storage=/etc/traefik/acme/acme.json
+ - --certificatesResolvers.default.acme.dnsChallenge.provider=${TRAEFIK_ACME_PROVIDER}
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.traefik-secure.tls.certresolver=default
+ environment:
+ CF_DNS_API_TOKEN_FILE: /run/secrets/traefik-cf-dns-api-token
+ CF_ZONE_API_TOKEN_FILE: /run/secrets/traefik-cf-zone-api-token
+ secrets:
+ - traefik-cf-dns-api-token
+ - traefik-cf-zone-api-token
+ traefik-certs-dumper:
+ # You cannot access the reverse proxy's certificate helper directly.
+ command:
+ - file
+ - --clean=false
+ - --crt-name="$STACK_DOMAIN"
+ - --dest=/etc/traefik/acme/
+ - --key-name="$STACK_DOMAIN"
+ - --source=/etc/traefik/acme/acme.json
+ - --version=v2
+ - --watch
+ environment:
+ STACK_DOMAIN: ${STACK_DOMAIN}
+ image: ldez/traefik-certs-dumper:v2.11.0
+ volumes:
+ - acme-data:/etc/traefik/acme/
+volumes:
+ acme-data:
+ # The reverse proxy's certificate data.
+ {}
diff --git a/src/production/tusd/compose.yaml b/src/production/tusd/compose.yaml
new file mode 100644
index 00000000..6e97d0cc
--- /dev/null
+++ b/src/production/tusd/compose.yaml
@@ -0,0 +1,7 @@
+services:
+ tusd:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.tusd.middlewares=tusd-cors
+ - traefik.http.routers.tusd-secure.tls.certresolver=default
diff --git a/src/production/vibetype/compose.yaml b/src/production/vibetype/compose.yaml
new file mode 100644
index 00000000..164fe583
--- /dev/null
+++ b/src/production/vibetype/compose.yaml
@@ -0,0 +1,53 @@
+services:
+ vibetype:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.vibetype.middlewares=vibetype_cors,vibetype_redirectregex
+ - traefik.http.routers.vibetype-secure.tls.certresolver=default
+ image: ghcr.io/maevsi/vibetype:13.3.3
+ user: (( prune ))
+ # vibetype-beta:
+ # # You can access the main project frontend's beta version at [beta.app.localhost](https://beta.app.localhost/).
+ # deploy:
+ # labels:
+ # - traefik.enable=true
+ # - traefik.http.routers.vibetype-beta.entryPoints=web
+ # - traefik.http.routers.vibetype-beta.middlewares=vibetype_cors,vibetype_redirectregex
+ # - traefik.http.routers.vibetype-beta.rule=Host(`beta.${STACK_DOMAIN}`)
+ # - traefik.http.routers.vibetype-beta-secure.entryPoints=web-secure
+ # - traefik.http.routers.vibetype-beta-secure.middlewares=vibetype_cors,vibetype_redirectregex
+ # - traefik.http.routers.vibetype-beta-secure.rule=Host(`beta.${STACK_DOMAIN}`)
+ # - traefik.http.services.vibetype-beta.loadbalancer.server.port=3000
+ # - traefik.http.routers.vibetype-beta-secure.tls.certresolver=default
+ # environment:
+ # AWS_REGION: ${VIBETYPE_AWS_REGION}
+ # NUXT_PUBLIC_GTAG_ID: ${VIBETYPE_NUXT_PUBLIC_GTAG_ID}
+ # NUXT_PUBLIC_I18N_BASE_URL: https://${STACK_DOMAIN}
+ # NUXT_PUBLIC_SITE_URL: https://${STACK_DOMAIN}
+ # NUXT_PUBLIC_TURNSTILE_SITE_KEY: ${VIBETYPE_NUXT_PUBLIC_TURNSTILE_SITE_KEY}
+ # NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H: ${VIBETYPE_NUXT_PUBLIC_VIBETYPE_EMAIL_LIMIT24H}
+ # NUXT_PUBLIC_VIO_ENVIRONMENT: beta
+ # PGHOST: postgres
+ # image: ghcr.io/maevsi/vibetype:11.0.2
+ # secrets:
+ # - source: vibetype-api-notification-secret
+ # target: /run/environment-variables/NUXT_PRIVATE_API_NOTIFICATION_SECRET
+ # - source: vibetype-aws-credentials
+ # target: /home/node/.aws/credentials # TODO: switch to user `node`
+ # - source: vibetype-firebase-service-account-credentials
+ # target: /run/environment-variables/FIREBASE_SERVICE_ACCOUNT_CREDENTIALS
+ # - source: vibetype-openai-api-key
+ # target: /run/environment-variables/NUXT_PRIVATE_OPENAI_API_KEY
+ # - source: vibetype-turnstile-key
+ # target: /run/environment-variables/NUXT_TURNSTILE_SECRET_KEY
+ # - source: postgres-db
+ # target: /run/environment-variables/PGDATABASE
+ # - source: postgres-role-service-vibetype-password
+ # target: /run/environment-variables/PGPASSWORD
+ # - source: postgres-role-service-vibetype-username
+ # target: /run/environment-variables/PGUSER
+ # volumes:
+ # - ./configurations/postgraphile/jwtES256.key.pub:/run/environment-variables/NUXT_PUBLIC_VIO_AUTH_JWT_PUBLIC_KEY:ro
+volumes:
+ vibetype_data: (( prune ))
diff --git a/src/production/zammad/compose.yaml b/src/production/zammad/compose.yaml
new file mode 100644
index 00000000..60f892ef
--- /dev/null
+++ b/src/production/zammad/compose.yaml
@@ -0,0 +1,6 @@
+services:
+ zammad-nginx:
+ deploy:
+ labels:
+ - (( append ))
+ - traefik.http.routers.zammad-secure.tls.certresolver=default