From 599588d095726d3f08b163bdf63ac04f67bb19d8 Mon Sep 17 00:00:00 2001 From: rjnevins Date: Tue, 7 Jul 2026 17:44:20 -0400 Subject: [PATCH] feat: add Taiga template (#895) Adds a Dokploy template for Taiga (taigaio/taiga-back, taiga-front, taiga-events, taiga-protected) wired through an nginx gateway, with RabbitMQ and Postgres backing services. Diverges from prior PR #547 in two ways: - Strips trailing inline `# ...` comments from env values in template.toml. Those comments were captured as part of the value when Dokploy expanded them into docker-compose, polluting strings like TAIGA_SCHEME, EMAIL_BACKEND, etc. and breaking Django URL/email configuration at runtime. - Adds explicit SUBPATH= and RABBITMQ_VHOST env entries that PR #547 referenced but never set, so variable expansion no longer falls back to empty/undefined. Validated locally with build-scripts/validate-template.ts, build-scripts/validate-docker-compose.ts, and meta.json required-field + dedupe-and-sort checks. No runtime deploy was performed locally. Co-authored-by: Richard Nevins --- blueprints/taiga/docker-compose.yml | 145 ++++++++++++++++++++++++++++ blueprints/taiga/logo.png | Bin 0 -> 15955 bytes blueprints/taiga/template.toml | 114 ++++++++++++++++++++++ meta.json | 18 ++++ 4 files changed, 277 insertions(+) create mode 100644 blueprints/taiga/docker-compose.yml create mode 100644 blueprints/taiga/logo.png create mode 100644 blueprints/taiga/template.toml diff --git a/blueprints/taiga/docker-compose.yml b/blueprints/taiga/docker-compose.yml new file mode 100644 index 00000000..7649d283 --- /dev/null +++ b/blueprints/taiga/docker-compose.yml @@ -0,0 +1,145 @@ +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: diff --git a/blueprints/taiga/logo.png b/blueprints/taiga/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..064c83ef27f2fe493b7eacd3230fbe73012db41a GIT binary patch literal 15955 zcmV-ZKCHosP)(jyoDmSdBD_z&;@RAeX?a=T4^AjG=efIblN2L1f)|N4>749|`nK?s3ACNXcQo2ndGvj~vidJ%93NCypb4K1p0c zpCB#*Gnl#l=2u^T(?{NN2LJ%Z7+Y^3O#i<4l`nbO+|N(_EPE!Mr=)Say)Q=eZ4j4$ z8H^_mPmSF2ncuw&2tgaoDJIbX;Zo4Ryn^wE1B{trVpNcUU&;zpk!E`VVfe9LFw{hmu-cf}j_{4gLG znjJo1s3dpd!RMauN(1}YK%XF829*}Ce8+2E`5Pa3%N>Le*hzYvy}+_Z4&89cwR4Z1 zemJ|3&ULM^ee`XRZh~@Q{P4u^JO1i-?`nt~XRpH;VgB9!=WYK-WHix_k8}}z3DQOQ z!hY}V_k84UVq@_g?T(#bTI@k@bmp>sV~^bZ(0`DAe55Pr6Qojrfj&XHgzMk_>Kksl>$mT)|7_W1OYM<^*ByS@+|N%v zlkR%jSt=Oncw>}Ab{H;2eMTyhQ<85|Hu1285`;6YjqlZ3DRMB0$%=( zfBWcX<0FY_%wR_rBuWxbz!RCdeE-D5-+bUl&^JdqhCV?$j9Wkd2k$-di@D0=YPEK(}}S}w4bfzJo*x(1Mo)z-VgonkA5yb z8lOfTlpZ#)H{^>!-#$hdx0Z1j8`QtKRwASN-~*{-^&61fZ)a>IA{T>n^@#;qkeLGYhF~pCZnn zZ-Y1mj4`!4-u~%#-bD<8y1st{n~p91_y6v_pNNko;{E+2&Y&+roB&2B6c77v|JOS| z8y${McG7FLYcnuL-XOI{_KlhLh~BqH+C`rr&H%sb^Y6Ls@M|u;absV(ix}EBd;kon zJpa>U&$``~3mtuevx`NvON_DCNsqi=(> z1B}qb;i=J^KY8m%dxacmV?R6M-u-vCeIh=Zh`HUK3mJV0(gp&tpznkCeB^H;!_i5G zVR~w@vGg_kZ|0S=v>=L)zvKP#$V2wXUXGnu353Si}KyzmV$_a`MRZ=v_bh`2Xa6o{&>1 z?41NP+AG;|>d$`R!|y1r<|}Tt#as=oB@x@j@=Piq1P}>F1L0649tlU|BSYiE6JwJH z#zrRhN5at&59c9&@tF_5w_2@;bQ*N4yB?X$SlVNhh~NjO&p%Q`tlpEU>T0( z5P%|8q_S8RD`Hv5=azDFDN3G`>#MbVHDAeAa+PeksH-~Io9h50%$VKXCGz;f0ncq; z`{Pe=KK_Cr2eQ*&B7@P<_kQJ%?)=o7{^AZp(>vTxR1#PMz%EWReBzBb?$Sr~Z z0bI*h)<*V^yaY3t{%shlZqP~2`}lCg8wp1SBjck7$F98M#w%HdV;Eu(S+2=7sVWI# zS;(a4(sQZP>vOp?nN%%b%aqckOgU958uT_6>f+j>jT7X-7~S%@-@k42;P|DEbVL_H z)z^d9U-FB;`H{E0^_w62=l{o%d)hd=Fj;~=6byM1vE)!ZmK;vT2L~p`r)DO`ruN4o z@#%m+5cc^4A)m(=B0#WVPy!fq>`7g{(lk}AKf`o>7yy-8C8O(_6U}Z4?hph4N}o>6 z9lY-1U#1~k_G`{FoSKO({O6vtKapyS6%#&kq2cDFujbSl3(Tg{Es-UB#zkf$+`_BZgtP_4Va>Q_JqM zhV2SLXkV|NT%TuHh9x>_tej?@HntK=??DWr6NAuBV>mAtABQ=dM>qCT+OEotA*A4N`9@9tyInNvwGip5?DH1{qa+m&WyeN z)9?IqTQYU9b2zg8*kXFHvkaZbAo;T06Ul*8W|cG9#6&x zM}`K6$Hzw}XGey{_xXIjIL~>!9^T_c7;)6jG0Y^ivkRWCYexNVOf_NLnp22jS$1`O zdCm>{(;b3f#N?NA8J1;{oiEgOA%l%OBa?vUnuQGW{~6B1`RPv}8We$St<^%Us7Oi$W9;kbifpNE^}j5g$^d&+ z!wk!@9{MwK(P(`1;Mi5BPE9pCW8Ln7bMY z;y3+xF1qaCJHB-H*RJIkILt6CB>)9$YMgZ=&T=1`YK>tSdi{pobj6#)W#~e=Tr9q5 zR4n?XYx!zXEDGgdJmhsTHT#^g26J_U`Wuuyj5pw)3MFHcglwE`V}8=ULdOWJh(Q|0 zSfMK^##lubdFms%c|@K3o^Z}R&1NAE8OTEku<_d@1oqgUJLmcSE4){tDq27#hPE9M za#k{QN*c5PsMe~bs!%Pvkp}9P4T8k7C<_&_9Eb;pdUfjp!!Ud>9v$1Jef7{L56E1R zH*MnE7)1?Xi!c}=i!=svRv}&LcnpAP^%2hKKCvxU(@8MBY-^UDi}pBOuhzzE4A`EA%-ifsC$zW5Ts76&#@fabNOI& z)$)f!L!8Iscl5ppJdPNd2J$*8bVpGH?T2J9?qz2fhFe)(nsaNPjcWvx%Q7rZ zXV+71C9%4yV%74MoFXc<9>_o3KqwX+$JX8s=LZB3gP_eV2E=r%I6rQbA_2ssD`Bix zR4pns6jiR3%Ef|PZE#P;LV&8-YEG`nwO$wy)9#3bhHbl}L#q{FK+vA&5U2#{nA;Dd zQ4~f8NU}%HW(QFctCec0(0D?Svv5~}lxmt>mCJ7P!?Zj6zOXkCh<8-ovr<^RZ9D_a z_(mt=6PxW3mj{M&R1j;GnozB|rG>kyZ(@w0xL#bq*wwUgU|5z9Mk8b02#x`P_6%&& z7QyyL-5$9HO&|}r?Lfh$a%q)V=c>2@cMUQ?X#LdcoXegpCKQiNU@P9y>45+TB#5&v z-t9ms;zK;TirORYsag!nvg@gp({9FSTqOwY`_zf`CD#aI*&Rcihwqwu6A4K}48yLhFVDNVi_}$uFbspsxpLOd2JLny0Ppuje8FI%i_gSX zpSP&G0OAqgZb-VbFzpfIcYz|nU5Ze5N>x}7dZ=YyiDVyRrrBII6S47XJ*D5r}VMN}j=o-b8v-LE=`fdSHD zk|;qeYE?aJ6;!=ChB9tQ5J?h+LMfkhGmh-KkuFzcLlKms8-1XNQb`fTQg@$9S3~f% zpi)`}dN*eaebPykLm5Wse!?{%MUiUNT3LG0+91eYpz=$(1ve^$V2rU?sih1}m%BOf z0KnVQg_euAJ1_?Z3FtV^y0c#gGsRM2(d`hj>jW{gdgs>X-7292gpgXPv|8Um*NsPl zm2B9W1nI_9rQ}e-K#$>7E4tZzFbu;kuP@EHu?OUwcDVU)WQ_$*pITpGSa)jMQYm6+ zh9Z_L>s?%}IE0!^3N*LP;?BEx>n>eN4%vatT`huP7-n^C`Hb6ntgaITV~i@?b*oU!W-)fR?y>6xp`<9R71lLb zQ`}7bG3}9ZC1q%u(qWQdbFw#^)k{B5P-kNxbO5qQM8}z&o3)LowyUbDTqx#KZkL*M zoglOW3M++-rl_*pZK2Jn70au3S)0z11fk~kg+PbW+|S-0kb(^KIJG<6hoZ`IzK~77 z=m|ohN~$5(pdh-gh^1<(qoZP0TZLv^wt)1O4Esj!Zh?|RF*mTe4pmhvm0DSG zyB$425GqD83u#wez2^aAtVnWM6-|4jb7L z2trqk+){2GGc6m2byd~L9tELTS_J|fsTT!+Sbzpyz2-?N9jalbfQ}x=YYxXdz%U5Y z>Ub~=#%rmS(vP8678(r0fZ1-%#}woYq|G&axu-g?BYc|Ll8iyuu@pnHNB}=h?()3 zRR*P1WeRlg$ZP6^lv0Ml+JWZ8w64cToX*$62%zyvPY`1lYjAeLoUrq(oB?R6?#ZQ! zGm@ypse~-%D-)$cWdxcyKa{Ehx~^&2d}iJ4C_3sDg3wOMFXytlW@rua1BgagaY>$1 z3;F=APaKSpUeXidqBKoZ;&CGISdWkBn(nYi#jGpTn5!4e&pAtuEC}eNV|E9KH7Sx! z6=rqa@SS}bBcUqCv+3fDuIUYD0ce`8=JFZWV<4zk2tuJL8d0k9dIJ*ybU_aaXXIHT zli+!u#|RM>{IxUEKDDYxHlJ6~2BDtL ziZfzOj_q0S0uWQkl_yJu%CLE~gXAQ(B(8epERH>G! zN~I3k2Y&1|Wz6~<8dbT@NHd0NaP4-wDoJHU5R1-v%Nne3;+%^Y&~cP?Al^Y$s;I3} zc^j;HXnstnN{L*$IBlw2+l&Xs3|?7ZUg!yS^b$d6@8wr=>)Z4-Xrd7i7UfwYkwCL4 zLiF=Q1)q3Ep4BXstM$G&_m5Q5xHC6X#smdkF=Zyz_Kb2lxb3a6Ap=Ss}kzdZOY#ibOXT4PNvOI+hXvd2~ zCmAD|Dwkq;RazeaJ3i8OzLq`l_l$+KPY^TD%HH46MvFC7=X2@8j3`L)2BrAUO#;Le zbCvN@p*mu!z#GS_fKjRx*Lovl*+T@eJy|QnAf|3ibiztY@}!d22OaXXm?u-3D%X-c zV`!x1NoVMWB9tmA2imlE3VXXQ-i%DOsEL=x~0dot#+>CN22 zwntbG@8@{l*J@MDQlvWvjO(>{TbnJW-GK#k66ek1)|v!Wsfzj1gr+(sHMWI)I44`o zl_xx2R@61UH`vi~eWnf|KAaqU`yKE4n@BWrJ!WusiW6XjsWj1RMvx1#0%n^(r%zW@ z!Rz-$>*tI&c{yN=bcSK7J6@}z7$Ug&%8&K^9S`CqM4C2vO_i#UEl&~xo^I`(qJ5~V zhVSCpBZtqd&iz~vtJSVNco*~pK@PwC$kjLB@y;(t2Vw^>Mjp)KVAmc_)f@wOt*l2G zo>5t^dE#rsGlG~0MjN`v=L@$Y^QgwhuuK`9%?8+fZakgjNqaAP1yP<*;VpRRUVDQSrFMG2fR2SB>D~sK3!)CZj5SHiIUw-GC-u>FQ z-gqa+vH{DCMjU3bqe+Jig3)V67J=&DCFL&hA#b9_rRegQK~$rL{v zhNXv=qml85YzLvSNf5xz8R>LdKaa9#i77XsT7jnNo_xAACCh5qtsS>ukTM{US(fE5 z-hb&Y#UhE&!qUkn=qlt!dt4((d?Yz=^BwQ}t3y{_@@wWkkot&V#9$7`Txyo3atV5f z3$P+)&1m!9GX*0|RW07<4KXa+j9q8CpBV-hh)&RB|M>XW{eOM`j8G8y>FcJ;2oS~! z9VifFJ&E}dhIy7oLCj*5JDCfLS&^T9#Z(PRc(AGS`DD=1L(CE~8nZhH0aPwjM=GV-aEo@7 zlK{goa$ED~0{-CO6^CE;rkYqilgh1jRpsg`L3p2sf9*To@UCBa>o4EQ@?2ntiDV!S zC3|3ZA=ax#6bxY4ps8~0c>w`xkrB_@}R) zX6vu*-2iHLFe|8r8%gvtRjOiUL#1+?9A<|QLNZ%lrfp*wQ{{SnED{f#Svh@FH}tO5 z?CK6dFvhWw+gh23^Ro0G+m48I`|s&WaK!DP27L=7lI zH)Muk_`S{?G0CA5xbM&I^R7O=>fK5JlO(5dKCvjG>1(D5YJ?=mQ5G#T7|q zOOuABQuRdK8W7S5A%*R;f=!^&p^3{6%^taWadrOZqEzen9{SD`1S5R$D=xqKZ6Exd zFUFIxgAJ@ylsdt#xq9~iZLjI&s_0S7Gm7cuf}N)zMhL5W*dr!6Gy?a1%p?c5)BH3^ zayrL0M3M&W4j_Qbh3asnBn-EbOVvpLAtC@&c4?FOdcYqVy5jJ)Zx+Sc;#y|8qbgVD z2!avjy&mqhH~-4--T1a&zLRCyV557^F@t=V#et5strY;mM$L$V4lEmFMUx>rlZ4tM z;&%4PhUED3-N~_WFG`ZR94i)fA&HDM^dMf|E8d}NI-k#$CS^&DbmKh6WH0fVloja=QT1UKGogxU14{3NkZ+8hw(BJcCkAEAyJURgfIG)T7+%}7Grw^7BSHcm0Fk79%+>vo1eR_BzYcX(aO$thpAGP>ME7%j*neI zj13oWL$K!+1pL9_E04VVjiOjvTFa~~Ihp9_C_y-$V_*07U-`Y)-~5J;a-13XL#>H% z0L&oZ~o9NpE~@qOK+m9WqY0x z42VUE9&q*U4m&eguNk4;R4!GN#RvZSXCv*9W8;x^l4M0PCC@D2?d=W_YjT9DRE9x% zR;Ahu%foxVi?^wJAV8yolUH0kd*tdf%cp-XNVQtK?Q(=5hpxHg%9}s@t}n%hl85Zl z^=*#`W>Ew)uDg00f}P71V?4H(Ym?L@IzbP8?$LegPo> zwi|DK{X5?HF^=OxPWsb($<^Bsz*M=cz@nAQg@{J*&p!Xyf$X!nsMD*sNs@dnD2gIC zH8EYLf9txLOEsw|TEwM;p;`tIBH1opN5Hb2_mbJmZj6TF-i4);Pa4E%sUl6w1c?sB z;%~eCmQNnO_Q-EhRmkCB6ZE93w*e4|1av_UF&->D{Kd!jQF3(3nQD%6vMv)|ATC3_&pO<@wjX^~T@1k*ZWY7wq711=#L9JI%YE zqjX;67dCy~by&Go08iijthX>0t99OCBu{i2o`Z@umv*Z#`&{}}=7nt|Ix0E<3U z@L;Q~jwyMt2QyUanB?IxRp0OidA2(vy`h2ZC30+TQwt>7i3D_s)z2dV0R_{)5g5pl z7NnO*uouj|#h5{lKJ(yLe{lb||6WqWZHobJ`$Z@dA_MW{Z~m9J+%<7v>IOoHaUofL zJHVDXrpktGm5kXWd3;prU~JaGWzDU>XUT)Mn?Uw{4tVALI2Q&=0$1|b%hNq(rio|4xN=cUd)(I1KuJJVhkO~(|14P%`X&t ziX3%pmL%A!!DUeG0$F5Gfe^*4^$wuf1~SG3$DV%ZAHVn0d;YtsDW;ce!_6BWh{b;U_FF!A*E-(9_?3cBZgc4E1_9nJ(a3$*U*|JCqnMZTcSg#Uv&6LOp$c zVr2TNL;DV2HNSM~5lI#VlOVj$%iQ{B@A=!Y>CtP^1r}-QHZVr8@bH<@^<(K?@#yUd z+Rmy_3Hp5jIUI~ieNt?X`n(SXBV$JnUitDTpMB)ptUny!Kk$Fu_1#Fwzt8OkUI2jH zLOy!pzEd+jaK2>INafe#V}s)bp7*#?W9mYJ$LmcVm^pkgtE(DWpId%n_OgT5dc6Dv zm)g-~V1LXnD}ut;GD7e|>Lsc^9Gt#nc_=wj?vL-zux$}Mw{+sZZ~X7S|Cp&_71R0b zv7bHt?<2Dl)3JfrZ2d!SH?|i+`(<$7KuI=9QVm`RS+jIJFPc8IGCO%ux=)Us0bs=t zfAYxpKl|~~fMHo-^3e3v)?R`OVDvkWvvCkJ{AeC{!zO3q zl3Y~-Lbm4VWs*?Iv484dX?F6WOr0EddWYi~1s5<(_kK;RtbFr3UwQxI&p!Nl+2d=vK$gjTprjG~0fzcO<$_1PL4+Am}nPh+f2LK*Kzz2Xl_K8qD0{XfcXoOQg zo#)fXGkh=h5FO;%$&1u|3sGbBkAE}G=9@u9+mcYb2fG)cx~(`uQ~9OOnKt9FrHR)8n(coeRD3)|QW&3j#)F9b(=5 zjX^^QD;Qfpo5)i)?q3kmbO0a#VEp8fd%tl1qxb&5x}l#JBic0=i}P^oD{p%3+pc@# z4Y%1U*M*Ubh3a|0z#>4b^&323N&@iO2lHFx0K{TCNASkAbu^rdg=~_fo=@|=u#Q;d zIH*pK?K6X2O|)tId@PF~bdfXwAr&K3Cyr{9#@Iq0_d8*Cn2TghtgZd)z5nwgC(k^8 z%uJ)%1`TEN9=z)C6~Foizwwv8pns$nCcx%_q!Q950cVrIivYX;*kc}$X})J>_14ec z=twp%>JgII&b&{yaCJ#2%IIM3XPftjl%_`O1-~ak2YC@&7 zTgH2X`#}(jB%-mK-uITfCJ)ZMs!RJpP+c0>l7QL+^oK`;5&(ITwY}8L*rhfBwj$oH z?FT_FlcWvF(e|V5-S!z5=lBJ zIoicGTqBYgHGbeIz#-z0U)Sk#e8vDSObDcAQ3FwZTog9M$LuvY#tVtC* zBRrfpaG|;7sZC;^_Ui~JIV4F~|Hi+4<&PeF_Mso|wfB4{v{g6`2*AR#b5F0GS$p)r z<%eFud-za0_uCAj8w0&|j{9yfbfV{%s;fd?F5-=|1uzc8DM@rr73H9l+8`b7p$&4J zg{mu}W~ic<^9C8r^u#H~4T3O?dD?HA0E97vmsaL~{MEa^_{ZznmF0Hs=12z?*7NCO z4;}s9_<_lN(ZSdZ5NM^M`#B&Q8FJ$o;#QyvnwVXvEa{@5Z2jK!Z%@D@Rdba%BF@!9 z<~U9n92{QbIL_GmJOd0}RK*gI98pwX!Aq3~< zQd0;JV@i2wzt0(lRe6rnB~c88!jTfgY`c!wDi;C|=jnNs3lLxiGX*yt47#lgDYmHwAu zF=f{-PvZP4I9y)q29u!>uNQY-$Y0R5!72QUaC)F zgsYa9Y88xK%47l{O;Nr1Gnt94c9bPankR`VIkwmv_4`SZ81VapwXOEZ)>ds%xlk{~ zkZi~d!$^&MkoKRfNa_Fe@BjFLN1wj`KGI_K_Px+iF9*>LSa{~t(bP)ziT#&d^m2}6 z8q$SHueo>ufnlmt)sx!rkBoaPEU6lU2y~E z*Rt!!9)9M#;}=cMMibGgJ@%MDFS&T>6jnt|$}LovR8c?AOLZPFg5pYcM6vCT9Y59} zNlb&B<@CLl6+#SF(=<;g6yDJuv7d_x7@DL>y{K~0$zR%OZq)1j{`BWR_`6l2&B%qK>7_F5s6DO$ zBou1VYPvMoh@`BOgcyXX72d54z!(>J-qX-2QS@G_s(KlQHN0M*yw~H+K$<32C_O!_ zH-NWn8gU5>#yG#jydaV+roZ`}fB2I}pMKy6gcu!@8k^D8KoT(snSc7!(e!fq@dH;J zypCnr^HnYY9t=pjJy=HFOO=-k4cShBkS1%M{F%%oZi3wO)`n)Bw#EVnH*SW|3PL!= zv0TH4ncDV9Fc1h-S(Y>Q7Iqk^h9auEB6&GqF9a4bl^|POy{5LYw7T%quif+I53Hq^ z7Q5LXS2`rWmQ6kP@H5|?I5c%25|2)9eh&zE!GO3M?W#i&H8DGHs#H=VwnPC}uX>H+wfBe>${;1n3)mFHz zbDA(!u1B8v?&L*N2ZE8%rQLS%Dxxms=F3*#ugOWS$yU4rx41Wj7(^rls(2ehVyd?> zOo(9^Z?pHNQcaS?kl!B=IF4^PI&G<3h9+rZnP+&P3o4iL^C#~A)HlET)lbWc)OD3= zD|&(;$W*x`>F5Jbeed9rOMfj8@r`st#8U;gmX`|D7&mjNn!TO?&dyW2!;E*d(q3#B zq--BvdH(g-Ou+E44BJYUw0XaJe1u_`rc@Nm%O#oFwH~%RDwj?SZ7IEQ|J~pF+MRBx zR9n$gxj77GkdW6@|U#i9^xJFOo;*+u$b0J7WrjQ|Tm zEmE$O60P*4Y0ns{n5$*x6-{>X9CH(txD~0KE{cT}K!jk1^@TzaSG|~<(Mtru;b?RM zGnOx&7+~ZUD$C`Rm;qB6YV+>){>y4s%4biP&lnnMc|}wu)mvK0kF=|E*auwhRcYOz zpKIqibdneHxgkZC{jJ`E05S4nZmB9)vbHp8dqi}iYXu>VA@>S z&2s@8m}q8hL7NlObReYC>*I!Dv^?f?JSag5LVnpG#-1f}c7S<}tjRU1QYnUVPOJ%I z%tb=6@h+8>+7rD*5D13DBU|&%Xy>UlP0E}sEyy*^67fwAiy~=q=2U53Dyh{rRU#;@ z=0P(Q<2J|F|(~PiLt42Wf#gzb(L!`r3>mRRgS7ul{1D4db{?5kgvp~ zq7ZY)ql1ZMfbU+o44Wr0Yfcc7wptKtk#f1zmX2@jF(F1?$Tp>N=|tD_mP(b|sSoMB z;<4mD_tU~G^bA30heZ>KeY>q37-4LyTuVgX-G%_FQY}_jN~=Q3iS}ud>M5<}N1V9V z1_&q(s1g_~L*5aX_DCT&BuSF5T{FTw+D)ls3!>@e+SN|7RI2Q}sw?7d3k(2|L^Qc? zySR`W=ox~r9LspT-VwCNo@7(R*EAu0sS(=y1rb^ZJcO=BLJ0=h~ z+FzJ7=Aptsc8HU-4knYK_6TYF`_M&8(UiK%b)J{Y_EJ%mYRU9c?Ja%5uU7*vv&Dwi#F03oVU6|!@tN~JlZ3PEWpH=-$R#yhs&l>SQ^ z+g=KosNk@(o7y9pOnS_T+gf`}&QrONK@2S~WETaswxde5&AkxIa^6TNn(PHnR!?k7 zqMZ_qM8_G1X)3M3+~uE^a*Ciy@$ukDIW1=(MGm}oICJe)1dZzmUP$V21c0Pxq zdGrQBFhZrsFX8mFGsN1nH0(Yg@@Fa6HF)c+Y^_?XdQhE0*2S*|Dj|HX43Nv!8FeK^Q}!kROsH$=?ek z@p`?(EW`E*LPsVPi43tE=XJX`%y`G58Sm)m!8~^IWi#pgRD|pqb#D{q_swKdQyij8D%-PQ~G|RFzpUq)>_^C)bMiddu0GARZ7D?;_c##|Fyw}TdJnzb3Io*hNYy(V4OA{RfkhYH$YwCekDbsMNRBX8X zsgvM6o&lccU7e%u5(Hx$2!#fDp6~iuAaqd_a+P?uML1ZtN2@yob*Hm>8$q>Nj=La4 zu!r{qf`QP0n_0cC5`@|xflz3e<9UC#Cn|kje0p#lVccca4y?@FR<5Mib;(fQ{Mf<4 zkySUwhvz)OfIl?gW<=dpf>7Ny5Dd^2!W9><$LEz}W35L{nM3 z=Ut4=>pPa!y9vPaygD>AyzXWso6d_wVsO^YHn^=~p{-5*tsh zLuV&n(^#T_UA* z1~}dm>Ve`F_341);{z$)=TSPMY5{6HpQ^!fr7hi>=Xq^#aCpt_4B9$OHx};=`}~2V zTYfC}R4f1zh=d0aKvTzybrjepVLo2pD;v}eCB6gL;c5b4B^ER9LU5AEDyTkQe zotuCG0Ur#62i$UGxoU&N6Ulupd$7)f8KClcRMQ@DcG;p9wuajuX@c4$*;Y^^IFT4g z`+PpvPjuP}LcmBwlhbZJ-%T3?$CAnY-SX=<2^>g9%7H|<KBp7TA1hDKKGct`KC!>;}7^ZDaE@A0Ub z(oq-pc5sCtbgA+M{Bf_}A8~nLHV&^ci(Ff4D7J#QL}kEETw_WDK$q0-7Y%bq$>S(_|8LWswh@%g;or+A*{4Ppct%jKMMOzP$=`dU&2-QEl{y?1LxQJmGj_K1oKhEw`tJFIs0z*}K z`fU0`3`3|@DvRYpVWC_oE(*13TBuZ4s+IDpSgldR6)w5xijOAaL%+6JGW10JW^dHn zNK7@)4pbJ)*&iM|`NSP&(F}h$7zsxw!r|CNC>S1&#gfypNMc_o7@lGn*3WXBhhNz{XEfotQ(ddvpaUH3^ezw57*{3XK7)kQHLwi_v|$LJdnnAQg=2pm41{0e z_4r)P4Qd|%imI-int%4=cCSHAtW;}a^*GL~oTzsKHo>5vKNJatB4goDWHcO%4#i{1 zeX&?_*5?b1^BnKzSkBL~te2Q47Lm=BSFl6m!2}2!4o8PFx%E?ybU_nviy$~QFtEQ# z7cXp%aN8uHY6C+E5p_)yHB}WAEHzKYjF$%MV}sb%emziyof_U^)*@%sqXFsww63-r96(m$hCPs4A38HL+4o zWzcajlcKO?7+?m1flxdc3=anbp^<1PHWZ5w>`z1o_WOLkVV?5@d5?#xZj?O4CeOxr z+x_2A9|9qIJUXxsA@rc5z0m;NAqd7OnuzbGUmTx%QVMLW-1Ha59My{{5r7a$Q`L&9 zC^cD@(v$$@VsWloETu$I$V!5km1?yzB|&|(H<18sHJV#VC#eaQGYd;6KQTLf=r0`T zg|36n@1@nb|5m9MpKtQI4QX2UPMGAWm5Vi@QbGuwuBa9x!||&U@xfoekW?+&7o~FHzU8%rZ#sP2bEJ;xVl#A9t(FV5TDb@SC+QqF z`w9?dIS%`Mfq1|lOa%O)L_D6HO2h{CM?%qkUY~!!>-9&eQ4WB30K*`}^w{YEe{kFk ztasVp>k2_Q5AQV$y_(Nt9v3Rr#Znc#_xU>Rd%<&wf zYg#?;XTvbufdoB=U?4hk`QfX-hB4#sWl3UBQ}x*skNsY`T0HJ{dl~@Vq!FO{9OXEk z)pf1wSr@JqDJF#UJPCG#rYTg)rQ@-I*Yq+$FhFP|I&pZm3t9=g0zWpweUnTIeb0Oafx1X{aSX1 zx^nE~6So_N(ba-;FC_E{(k2KYdbL`5d}v_&SE;Jp3+k5TBS-r4r;ff~lxnMPx937e zpCArErS^znWD>E#*YrSkGGK(+rPaC5X7X!4aj_jQ2=oc!5NbmCRKOP+2n0e$T-NuQ zqGfmdZQt%_AAN#2h;p^~R5Ct%9nbNu6nmynRe9yPlTUugF!a9N;Q;ysaS((UTD4Yw zd}v_o%@|{@%c>RtfOh=!)9)9g>PlaFID<#fut!8>9;`3|&5P`skkmfaJg~ zM*sxciTP(gtm&%YP!s#u0euP5C8(NO(R6Js86SLIoB3MI!t&`)~8CrFo3t`wgfNDRM%=eT4uo-K2KhpH?+ zck+o38l)fZ=ob0}=`siqy;dtfF*Gpt#zyy#*mjHd{HdotAj-mecUsy9>J!8rSovC7 zIuRdy9qe6JoxabUSw8jYY$5$XU$yEk`UG(af>@mo_(JiZwSQzsQ2rFl`R^?(o%rtv zb>?isK6XZ*AnpN*mBJIr_{b}Go*UTCsRal?Rh7l(PCjwFLG-@e;R5;uaS;GSuTXm= zIravIF^?rU_Y4w()aOr|c1NnOTDgNhL0pEWDP>JpRul1|*KJ}400QRB%BfFf^Qi~> z*24bOLApY1nCi!D)~o!-asti4;@w%>CCZ{ zPkgYSXVpg^TX4-4zwq@)D0aZ@cJyK4{|^8F|Ns32nXAKec!B@`002ovPDHLkV1niO Bx9I=? literal 0 HcmV?d00001 diff --git a/blueprints/taiga/template.toml b/blueprints/taiga/template.toml new file mode 100644 index 00000000..c528fd32 --- /dev/null +++ b/blueprints/taiga/template.toml @@ -0,0 +1,114 @@ +[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_DEFAULT_FROM=changeme@example.com", + "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; + } +} +""" diff --git a/meta.json b/meta.json index 9e132a03..80889bb6 100644 --- a/meta.json +++ b/meta.json @@ -6654,6 +6654,24 @@ "backup" ] }, + { + "id": "taiga", + "name": "Taiga", + "version": "latest", + "description": "Taiga is a free and open-source project management platform for agile developers, designers and project managers.", + "logo": "logo.png", + "links": { + "github": "https://github.com/taigaio/taiga-docker", + "website": "https://taiga.io/", + "docs": "https://docs.taiga.io/" + }, + "tags": [ + "project-management", + "agile", + "scrum", + "kanban" + ] + }, { "id": "tailscale-exitnode", "name": "Tailscale Exit nodes",