Taiga
Taiga is a free and open-source project management platform for agile developers, designers and project managers.
Configuration
version: "3.8"
x-environment: &default-back-environment
POSTGRES_DB: taiga
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: taiga-db
TAIGA_SECRET_KEY: ${SECRET_KEY}
TAIGA_SITES_SCHEME: ${TAIGA_SCHEME}
TAIGA_SITES_DOMAIN: ${TAIGA_DOMAIN}
TAIGA_SUBPATH: ${SUBPATH}
EMAIL_BACKEND: django.core.mail.backends.${EMAIL_BACKEND}.EmailBackend
DEFAULT_FROM_EMAIL: ${EMAIL_DEFAULT_FROM}
EMAIL_USE_TLS: ${EMAIL_USE_TLS}
EMAIL_USE_SSL: ${EMAIL_USE_SSL}
EMAIL_HOST: ${EMAIL_HOST}
EMAIL_PORT: ${EMAIL_PORT}
EMAIL_HOST_USER: ${EMAIL_HOST_USER}
EMAIL_HOST_PASSWORD: ${EMAIL_HOST_PASSWORD}
RABBITMQ_USER: ${RABBITMQ_USER}
RABBITMQ_PASS: ${RABBITMQ_PASS}
RABBITMQ_VHOST: ${RABBITMQ_VHOST}
ENABLE_TELEMETRY: ${ENABLE_TELEMETRY}
PUBLIC_REGISTER_ENABLED: ${PUBLIC_REGISTER_ENABLED}
x-back-volumes: &default-back-volumes
- taiga-static-data:/taiga-back/static
- taiga-media-data:/taiga-back/media
services:
taiga-db:
image: postgres:12.3
restart: unless-stopped
environment:
POSTGRES_DB: taiga
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 2s
timeout: 15s
retries: 5
start_period: 3s
volumes:
- taiga-db-data:/var/lib/postgresql/data
taiga-back:
image: taigaio/taiga-back:latest
restart: unless-stopped
environment: *default-back-environment
volumes: *default-back-volumes
depends_on:
taiga-db:
condition: service_healthy
taiga-events-rabbitmq:
condition: service_started
taiga-async-rabbitmq:
condition: service_started
taiga-async:
image: taigaio/taiga-back:latest
restart: unless-stopped
entrypoint: ["/taiga-back/docker/async_entrypoint.sh"]
environment: *default-back-environment
volumes: *default-back-volumes
depends_on:
taiga-db:
condition: service_healthy
taiga-events-rabbitmq:
condition: service_started
taiga-async-rabbitmq:
condition: service_started
taiga-async-rabbitmq:
image: rabbitmq:3.8-management-alpine
restart: unless-stopped
hostname: taiga-async-rabbitmq
environment:
RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE}
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS}
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST}
volumes:
- taiga-async-rabbitmq-data:/var/lib/rabbitmq
taiga-front:
image: taigaio/taiga-front:latest
restart: unless-stopped
environment:
TAIGA_URL: ${TAIGA_SCHEME}://${TAIGA_DOMAIN}
TAIGA_WEBSOCKETS_URL: ${WEBSOCKETS_SCHEME}://${TAIGA_DOMAIN}
TAIGA_SUBPATH: ${SUBPATH}
PUBLIC_REGISTER_ENABLED: ${PUBLIC_REGISTER_ENABLED_FRONT}
taiga-events:
image: taigaio/taiga-events:latest
restart: unless-stopped
environment:
RABBITMQ_USER: ${RABBITMQ_USER}
RABBITMQ_PASS: ${RABBITMQ_PASS}
RABBITMQ_VHOST: ${RABBITMQ_VHOST}
TAIGA_SECRET_KEY: ${SECRET_KEY}
depends_on:
taiga-events-rabbitmq:
condition: service_started
taiga-events-rabbitmq:
image: rabbitmq:3.8-management-alpine
restart: unless-stopped
hostname: taiga-events-rabbitmq
environment:
RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE}
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS}
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST}
volumes:
- taiga-events-rabbitmq-data:/var/lib/rabbitmq
taiga-protected:
image: taigaio/taiga-protected:latest
restart: unless-stopped
environment:
MAX_AGE: ${ATTACHMENTS_MAX_AGE}
SECRET_KEY: ${SECRET_KEY}
taiga-gateway:
image: nginx:1.19-alpine
restart: unless-stopped
expose:
- 80
volumes:
- ../files/volumes/nginx/taiga.conf:/etc/nginx/conf.d/default.conf:ro
- taiga-static-data:/taiga/static:ro
- taiga-media-data:/taiga/media:ro
depends_on:
- taiga-front
- taiga-back
- taiga-events
volumes:
taiga-static-data:
taiga-media-data:
taiga-db-data:
taiga-async-rabbitmq-data:
taiga-events-rabbitmq-data:[variables]
main_domain = "${domain}"
postgres_user = "taiga"
postgres_password = "${password:32}"
secret_key = "${password:64}"
rabbitmq_user = "taiga"
rabbitmq_password = "${password:32}"
rabbitmq_erlang_cookie = "${password:32}"
[config]
env = [
"TAIGA_SCHEME=https",
"TAIGA_DOMAIN=${main_domain}",
"WEBSOCKETS_SCHEME=wss",
"SUBPATH=",
"SECRET_KEY=${secret_key}",
"POSTGRES_USER=${postgres_user}",
"POSTGRES_PASSWORD=${postgres_password}",
"EMAIL_BACKEND=console",
"EMAIL_HOST=smtp.example.com",
"EMAIL_PORT=587",
"EMAIL_HOST_USER=user",
"EMAIL_HOST_PASSWORD=password",
"[email protected]",
"EMAIL_USE_TLS=False",
"EMAIL_USE_SSL=False",
"RABBITMQ_USER=${rabbitmq_user}",
"RABBITMQ_PASS=${rabbitmq_password}",
"RABBITMQ_VHOST=taiga",
"RABBITMQ_ERLANG_COOKIE=${rabbitmq_erlang_cookie}",
"ATTACHMENTS_MAX_AGE=360",
"ENABLE_TELEMETRY=False",
"PUBLIC_REGISTER_ENABLED=False",
"PUBLIC_REGISTER_ENABLED_FRONT=false",
]
[[config.domains]]
serviceName = "taiga-gateway"
port = 80
host = "${main_domain}"
path = "/"
[[config.mounts]]
filePath = "/volumes/nginx/taiga.conf"
content = """
server {
listen 80 default_server;
client_max_body_size 100M;
charset utf-8;
location / {
proxy_pass http://taiga-front/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
}
location /api/ {
proxy_pass http://taiga-back:8000/api/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
}
location /admin/ {
proxy_pass http://taiga-back:8000/admin/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
}
location /static/ {
alias /taiga/static/;
}
location /_protected/ {
internal;
alias /taiga/media/;
add_header Content-disposition "attachment";
}
location /media/exports/ {
alias /taiga/media/exports/;
add_header Content-disposition "attachment";
}
location /media/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://taiga-protected:8003/;
proxy_redirect off;
}
location /events {
proxy_pass http://taiga-events:8888/events;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
}
}
"""Base64
To import this template in Dokploy: create a Compose service → Advanced → Base64 import and paste the content below:
ewogICJjb21wb3NlIjogInZlcnNpb246IFwiMy44XCJcblxueC1lbnZpcm9ubWVudDogJmRlZmF1bHQtYmFjay1lbnZpcm9ubWVudFxuICBQT1NUR1JFU19EQjogdGFpZ2FcbiAgUE9TVEdSRVNfVVNFUjogJHtQT1NUR1JFU19VU0VSfVxuICBQT1NUR1JFU19QQVNTV09SRDogJHtQT1NUR1JFU19QQVNTV09SRH1cbiAgUE9TVEdSRVNfSE9TVDogdGFpZ2EtZGJcbiAgVEFJR0FfU0VDUkVUX0tFWTogJHtTRUNSRVRfS0VZfVxuICBUQUlHQV9TSVRFU19TQ0hFTUU6ICR7VEFJR0FfU0NIRU1FfVxuICBUQUlHQV9TSVRFU19ET01BSU46ICR7VEFJR0FfRE9NQUlOfVxuICBUQUlHQV9TVUJQQVRIOiAke1NVQlBBVEh9XG4gIEVNQUlMX0JBQ0tFTkQ6IGRqYW5nby5jb3JlLm1haWwuYmFja2VuZHMuJHtFTUFJTF9CQUNLRU5EfS5FbWFpbEJhY2tlbmRcbiAgREVGQVVMVF9GUk9NX0VNQUlMOiAke0VNQUlMX0RFRkFVTFRfRlJPTX1cbiAgRU1BSUxfVVNFX1RMUzogJHtFTUFJTF9VU0VfVExTfVxuICBFTUFJTF9VU0VfU1NMOiAke0VNQUlMX1VTRV9TU0x9XG4gIEVNQUlMX0hPU1Q6ICR7RU1BSUxfSE9TVH1cbiAgRU1BSUxfUE9SVDogJHtFTUFJTF9QT1JUfVxuICBFTUFJTF9IT1NUX1VTRVI6ICR7RU1BSUxfSE9TVF9VU0VSfVxuICBFTUFJTF9IT1NUX1BBU1NXT1JEOiAke0VNQUlMX0hPU1RfUEFTU1dPUkR9XG4gIFJBQkJJVE1RX1VTRVI6ICR7UkFCQklUTVFfVVNFUn1cbiAgUkFCQklUTVFfUEFTUzogJHtSQUJCSVRNUV9QQVNTfVxuICBSQUJCSVRNUV9WSE9TVDogJHtSQUJCSVRNUV9WSE9TVH1cbiAgRU5BQkxFX1RFTEVNRVRSWTogJHtFTkFCTEVfVEVMRU1FVFJZfVxuICBQVUJMSUNfUkVHSVNURVJfRU5BQkxFRDogJHtQVUJMSUNfUkVHSVNURVJfRU5BQkxFRH1cblxueC1iYWNrLXZvbHVtZXM6ICZkZWZhdWx0LWJhY2stdm9sdW1lc1xuICAtIHRhaWdhLXN0YXRpYy1kYXRhOi90YWlnYS1iYWNrL3N0YXRpY1xuICAtIHRhaWdhLW1lZGlhLWRhdGE6L3RhaWdhLWJhY2svbWVkaWFcblxuc2VydmljZXM6XG4gIHRhaWdhLWRiOlxuICAgIGltYWdlOiBwb3N0Z3JlczoxMi4zXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFBPU1RHUkVTX0RCOiB0YWlnYVxuICAgICAgUE9TVEdSRVNfVVNFUjogJHtQT1NUR1JFU19VU0VSfVxuICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICR7UE9TVEdSRVNfUEFTU1dPUkR9XG4gICAgaGVhbHRoY2hlY2s6XG4gICAgICB0ZXN0OiBbXCJDTUQtU0hFTExcIiwgXCJwZ19pc3JlYWR5IC1VICR7UE9TVEdSRVNfVVNFUn1cIl1cbiAgICAgIGludGVydmFsOiAyc1xuICAgICAgdGltZW91dDogMTVzXG4gICAgICByZXRyaWVzOiA1XG4gICAgICBzdGFydF9wZXJpb2Q6IDNzXG4gICAgdm9sdW1lczpcbiAgICAgIC0gdGFpZ2EtZGItZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGFcblxuICB0YWlnYS1iYWNrOlxuICAgIGltYWdlOiB0YWlnYWlvL3RhaWdhLWJhY2s6bGF0ZXN0XG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDogKmRlZmF1bHQtYmFjay1lbnZpcm9ubWVudFxuICAgIHZvbHVtZXM6ICpkZWZhdWx0LWJhY2stdm9sdW1lc1xuICAgIGRlcGVuZHNfb246XG4gICAgICB0YWlnYS1kYjpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHlcbiAgICAgIHRhaWdhLWV2ZW50cy1yYWJiaXRtcTpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWRcbiAgICAgIHRhaWdhLWFzeW5jLXJhYmJpdG1xOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZFxuXG4gIHRhaWdhLWFzeW5jOlxuICAgIGltYWdlOiB0YWlnYWlvL3RhaWdhLWJhY2s6bGF0ZXN0XG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnRyeXBvaW50OiBbXCIvdGFpZ2EtYmFjay9kb2NrZXIvYXN5bmNfZW50cnlwb2ludC5zaFwiXVxuICAgIGVudmlyb25tZW50OiAqZGVmYXVsdC1iYWNrLWVudmlyb25tZW50XG4gICAgdm9sdW1lczogKmRlZmF1bHQtYmFjay12b2x1bWVzXG4gICAgZGVwZW5kc19vbjpcbiAgICAgIHRhaWdhLWRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgdGFpZ2EtZXZlbnRzLXJhYmJpdG1xOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZFxuICAgICAgdGFpZ2EtYXN5bmMtcmFiYml0bXE6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkXG5cbiAgdGFpZ2EtYXN5bmMtcmFiYml0bXE6XG4gICAgaW1hZ2U6IHJhYmJpdG1xOjMuOC1tYW5hZ2VtZW50LWFscGluZVxuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG4gICAgaG9zdG5hbWU6IHRhaWdhLWFzeW5jLXJhYmJpdG1xXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICBSQUJCSVRNUV9FUkxBTkdfQ09PS0lFOiAke1JBQkJJVE1RX0VSTEFOR19DT09LSUV9XG4gICAgICBSQUJCSVRNUV9ERUZBVUxUX1VTRVI6ICR7UkFCQklUTVFfVVNFUn1cbiAgICAgIFJBQkJJVE1RX0RFRkFVTFRfUEFTUzogJHtSQUJCSVRNUV9QQVNTfVxuICAgICAgUkFCQklUTVFfREVGQVVMVF9WSE9TVDogJHtSQUJCSVRNUV9WSE9TVH1cbiAgICB2b2x1bWVzOlxuICAgICAgLSB0YWlnYS1hc3luYy1yYWJiaXRtcS1kYXRhOi92YXIvbGliL3JhYmJpdG1xXG5cbiAgdGFpZ2EtZnJvbnQ6XG4gICAgaW1hZ2U6IHRhaWdhaW8vdGFpZ2EtZnJvbnQ6bGF0ZXN0XG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFRBSUdBX1VSTDogJHtUQUlHQV9TQ0hFTUV9Oi8vJHtUQUlHQV9ET01BSU59XG4gICAgICBUQUlHQV9XRUJTT0NLRVRTX1VSTDogJHtXRUJTT0NLRVRTX1NDSEVNRX06Ly8ke1RBSUdBX0RPTUFJTn1cbiAgICAgIFRBSUdBX1NVQlBBVEg6ICR7U1VCUEFUSH1cbiAgICAgIFBVQkxJQ19SRUdJU1RFUl9FTkFCTEVEOiAke1BVQkxJQ19SRUdJU1RFUl9FTkFCTEVEX0ZST05UfVxuXG4gIHRhaWdhLWV2ZW50czpcbiAgICBpbWFnZTogdGFpZ2Fpby90YWlnYS1ldmVudHM6bGF0ZXN0XG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFJBQkJJVE1RX1VTRVI6ICR7UkFCQklUTVFfVVNFUn1cbiAgICAgIFJBQkJJVE1RX1BBU1M6ICR7UkFCQklUTVFfUEFTU31cbiAgICAgIFJBQkJJVE1RX1ZIT1NUOiAke1JBQkJJVE1RX1ZIT1NUfVxuICAgICAgVEFJR0FfU0VDUkVUX0tFWTogJHtTRUNSRVRfS0VZfVxuICAgIGRlcGVuZHNfb246XG4gICAgICB0YWlnYS1ldmVudHMtcmFiYml0bXE6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkXG5cbiAgdGFpZ2EtZXZlbnRzLXJhYmJpdG1xOlxuICAgIGltYWdlOiByYWJiaXRtcTozLjgtbWFuYWdlbWVudC1hbHBpbmVcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuICAgIGhvc3RuYW1lOiB0YWlnYS1ldmVudHMtcmFiYml0bXFcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFJBQkJJVE1RX0VSTEFOR19DT09LSUU6ICR7UkFCQklUTVFfRVJMQU5HX0NPT0tJRX1cbiAgICAgIFJBQkJJVE1RX0RFRkFVTFRfVVNFUjogJHtSQUJCSVRNUV9VU0VSfVxuICAgICAgUkFCQklUTVFfREVGQVVMVF9QQVNTOiAke1JBQkJJVE1RX1BBU1N9XG4gICAgICBSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUOiAke1JBQkJJVE1RX1ZIT1NUfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHRhaWdhLWV2ZW50cy1yYWJiaXRtcS1kYXRhOi92YXIvbGliL3JhYmJpdG1xXG5cbiAgdGFpZ2EtcHJvdGVjdGVkOlxuICAgIGltYWdlOiB0YWlnYWlvL3RhaWdhLXByb3RlY3RlZDpsYXRlc3RcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuICAgIGVudmlyb25tZW50OlxuICAgICAgTUFYX0FHRTogJHtBVFRBQ0hNRU5UU19NQVhfQUdFfVxuICAgICAgU0VDUkVUX0tFWTogJHtTRUNSRVRfS0VZfVxuXG4gIHRhaWdhLWdhdGV3YXk6XG4gICAgaW1hZ2U6IG5naW54OjEuMTktYWxwaW5lXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBleHBvc2U6XG4gICAgICAtIDgwXG4gICAgdm9sdW1lczpcbiAgICAgIC0gLi4vZmlsZXMvdm9sdW1lcy9uZ2lueC90YWlnYS5jb25mOi9ldGMvbmdpbngvY29uZi5kL2RlZmF1bHQuY29uZjpyb1xuICAgICAgLSB0YWlnYS1zdGF0aWMtZGF0YTovdGFpZ2Evc3RhdGljOnJvXG4gICAgICAtIHRhaWdhLW1lZGlhLWRhdGE6L3RhaWdhL21lZGlhOnJvXG4gICAgZGVwZW5kc19vbjpcbiAgICAgIC0gdGFpZ2EtZnJvbnRcbiAgICAgIC0gdGFpZ2EtYmFja1xuICAgICAgLSB0YWlnYS1ldmVudHNcblxudm9sdW1lczpcbiAgdGFpZ2Etc3RhdGljLWRhdGE6XG4gIHRhaWdhLW1lZGlhLWRhdGE6XG4gIHRhaWdhLWRiLWRhdGE6XG4gIHRhaWdhLWFzeW5jLXJhYmJpdG1xLWRhdGE6XG4gIHRhaWdhLWV2ZW50cy1yYWJiaXRtcS1kYXRhOlxuIiwKICAiY29uZmlnIjogIlt2YXJpYWJsZXNdXG5tYWluX2RvbWFpbiA9IFwiJHtkb21haW59XCJcbnBvc3RncmVzX3VzZXIgPSBcInRhaWdhXCJcbnBvc3RncmVzX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjMyfVwiXG5zZWNyZXRfa2V5ID0gXCIke3Bhc3N3b3JkOjY0fVwiXG5yYWJiaXRtcV91c2VyID0gXCJ0YWlnYVwiXG5yYWJiaXRtcV9wYXNzd29yZCA9IFwiJHtwYXNzd29yZDozMn1cIlxucmFiYml0bXFfZXJsYW5nX2Nvb2tpZSA9IFwiJHtwYXNzd29yZDozMn1cIlxuXG5bY29uZmlnXVxuZW52ID0gW1xuICBcIlRBSUdBX1NDSEVNRT1odHRwc1wiLFxuICBcIlRBSUdBX0RPTUFJTj0ke21haW5fZG9tYWlufVwiLFxuICBcIldFQlNPQ0tFVFNfU0NIRU1FPXdzc1wiLFxuICBcIlNVQlBBVEg9XCIsXG4gIFwiU0VDUkVUX0tFWT0ke3NlY3JldF9rZXl9XCIsXG4gIFwiUE9TVEdSRVNfVVNFUj0ke3Bvc3RncmVzX3VzZXJ9XCIsXG4gIFwiUE9TVEdSRVNfUEFTU1dPUkQ9JHtwb3N0Z3Jlc19wYXNzd29yZH1cIixcbiAgXCJFTUFJTF9CQUNLRU5EPWNvbnNvbGVcIixcbiAgXCJFTUFJTF9IT1NUPXNtdHAuZXhhbXBsZS5jb21cIixcbiAgXCJFTUFJTF9QT1JUPTU4N1wiLFxuICBcIkVNQUlMX0hPU1RfVVNFUj11c2VyXCIsXG4gIFwiRU1BSUxfSE9TVF9QQVNTV09SRD1wYXNzd29yZFwiLFxuICBcIkVNQUlMX0RFRkFVTFRfRlJPTT1jaGFuZ2VtZUBleGFtcGxlLmNvbVwiLFxuICBcIkVNQUlMX1VTRV9UTFM9RmFsc2VcIixcbiAgXCJFTUFJTF9VU0VfU1NMPUZhbHNlXCIsXG4gIFwiUkFCQklUTVFfVVNFUj0ke3JhYmJpdG1xX3VzZXJ9XCIsXG4gIFwiUkFCQklUTVFfUEFTUz0ke3JhYmJpdG1xX3Bhc3N3b3JkfVwiLFxuICBcIlJBQkJJVE1RX1ZIT1NUPXRhaWdhXCIsXG4gIFwiUkFCQklUTVFfRVJMQU5HX0NPT0tJRT0ke3JhYmJpdG1xX2VybGFuZ19jb29raWV9XCIsXG4gIFwiQVRUQUNITUVOVFNfTUFYX0FHRT0zNjBcIixcbiAgXCJFTkFCTEVfVEVMRU1FVFJZPUZhbHNlXCIsXG4gIFwiUFVCTElDX1JFR0lTVEVSX0VOQUJMRUQ9RmFsc2VcIixcbiAgXCJQVUJMSUNfUkVHSVNURVJfRU5BQkxFRF9GUk9OVD1mYWxzZVwiLFxuXVxuXG5bW2NvbmZpZy5kb21haW5zXV1cbnNlcnZpY2VOYW1lID0gXCJ0YWlnYS1nYXRld2F5XCJcbnBvcnQgPSA4MFxuaG9zdCA9IFwiJHttYWluX2RvbWFpbn1cIlxucGF0aCA9IFwiL1wiXG5cbltbY29uZmlnLm1vdW50c11dXG5maWxlUGF0aCA9IFwiL3ZvbHVtZXMvbmdpbngvdGFpZ2EuY29uZlwiXG5jb250ZW50ID0gXCJcIlwiXG5zZXJ2ZXIge1xuICAgIGxpc3RlbiA4MCBkZWZhdWx0X3NlcnZlcjtcblxuICAgIGNsaWVudF9tYXhfYm9keV9zaXplIDEwME07XG4gICAgY2hhcnNldCB1dGYtODtcblxuICAgIGxvY2F0aW9uIC8ge1xuICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly90YWlnYS1mcm9udC87XG4gICAgICAgIHByb3h5X3Bhc3NfaGVhZGVyIFNlcnZlcjtcbiAgICAgICAgcHJveHlfc2V0X2hlYWRlciBIb3N0ICRodHRwX2hvc3Q7XG4gICAgICAgIHByb3h5X3JlZGlyZWN0IG9mZjtcbiAgICAgICAgcHJveHlfc2V0X2hlYWRlciBYLVJlYWwtSVAgJHJlbW90ZV9hZGRyO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIFgtU2NoZW1lICRzY2hlbWU7XG4gICAgfVxuXG4gICAgbG9jYXRpb24gL2FwaS8ge1xuICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly90YWlnYS1iYWNrOjgwMDAvYXBpLztcbiAgICAgICAgcHJveHlfcGFzc19oZWFkZXIgU2VydmVyO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgJGh0dHBfaG9zdDtcbiAgICAgICAgcHJveHlfcmVkaXJlY3Qgb2ZmO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7XG4gICAgICAgIHByb3h5X3NldF9oZWFkZXIgWC1TY2hlbWUgJHNjaGVtZTtcbiAgICB9XG5cbiAgICBsb2NhdGlvbiAvYWRtaW4vIHtcbiAgICAgICAgcHJveHlfcGFzcyBodHRwOi8vdGFpZ2EtYmFjazo4MDAwL2FkbWluLztcbiAgICAgICAgcHJveHlfcGFzc19oZWFkZXIgU2VydmVyO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgJGh0dHBfaG9zdDtcbiAgICAgICAgcHJveHlfcmVkaXJlY3Qgb2ZmO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7XG4gICAgICAgIHByb3h5X3NldF9oZWFkZXIgWC1TY2hlbWUgJHNjaGVtZTtcbiAgICB9XG5cbiAgICBsb2NhdGlvbiAvc3RhdGljLyB7XG4gICAgICAgIGFsaWFzIC90YWlnYS9zdGF0aWMvO1xuICAgIH1cblxuICAgIGxvY2F0aW9uIC9fcHJvdGVjdGVkLyB7XG4gICAgICAgIGludGVybmFsO1xuICAgICAgICBhbGlhcyAvdGFpZ2EvbWVkaWEvO1xuICAgICAgICBhZGRfaGVhZGVyIENvbnRlbnQtZGlzcG9zaXRpb24gXCJhdHRhY2htZW50XCI7XG4gICAgfVxuXG4gICAgbG9jYXRpb24gL21lZGlhL2V4cG9ydHMvIHtcbiAgICAgICAgYWxpYXMgL3RhaWdhL21lZGlhL2V4cG9ydHMvO1xuICAgICAgICBhZGRfaGVhZGVyIENvbnRlbnQtZGlzcG9zaXRpb24gXCJhdHRhY2htZW50XCI7XG4gICAgfVxuXG4gICAgbG9jYXRpb24gL21lZGlhLyB7XG4gICAgICAgIHByb3h5X3NldF9oZWFkZXIgSG9zdCAkaHR0cF9ob3N0O1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7XG4gICAgICAgIHByb3h5X3NldF9oZWFkZXIgWC1TY2hlbWUgJHNjaGVtZTtcbiAgICAgICAgcHJveHlfc2V0X2hlYWRlciBYLUZvcndhcmRlZC1Qcm90byAkc2NoZW1lO1xuICAgICAgICBwcm94eV9zZXRfaGVhZGVyIFgtRm9yd2FyZGVkLUZvciAkcHJveHlfYWRkX3hfZm9yd2FyZGVkX2ZvcjtcbiAgICAgICAgcHJveHlfcGFzcyBodHRwOi8vdGFpZ2EtcHJvdGVjdGVkOjgwMDMvO1xuICAgICAgICBwcm94eV9yZWRpcmVjdCBvZmY7XG4gICAgfVxuXG4gICAgbG9jYXRpb24gL2V2ZW50cyB7XG4gICAgICAgIHByb3h5X3Bhc3MgaHR0cDovL3RhaWdhLWV2ZW50czo4ODg4L2V2ZW50cztcbiAgICAgICAgcHJveHlfaHR0cF92ZXJzaW9uIDEuMTtcbiAgICAgICAgcHJveHlfc2V0X2hlYWRlciBVcGdyYWRlICRodHRwX3VwZ3JhZGU7XG4gICAgICAgIHByb3h5X3NldF9oZWFkZXIgQ29ubmVjdGlvbiBcInVwZ3JhZGVcIjtcbiAgICAgICAgcHJveHlfY29ubmVjdF90aW1lb3V0IDdkO1xuICAgICAgICBwcm94eV9zZW5kX3RpbWVvdXQgN2Q7XG4gICAgICAgIHByb3h5X3JlYWRfdGltZW91dCA3ZDtcbiAgICB9XG59XG5cIlwiXCJcbiIKfQ==Links
Tags
project-management, agile, scrum, kanban
Version: latest
systemprompt
Self-owned AI control plane: governance gateway for Claude, OpenAI, and Gemini with policy checks, audit trails, rate limits, and MCP orchestration. Requires at least one AI provider API key.
Tailscale Exit nodes
Tailscale ExitNode is a feature that lets you route your internet traffic through a specific device in your Tailscale network.