commit 088ff80ef38325cdc3b4e23594c861dcc73cafb5 Author: Cassowary Date: Sat Oct 7 13:33:12 2023 -0700 Copy from hometown recipe. Make glitch-soc diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..142372f --- /dev/null +++ b/.drone.yml @@ -0,0 +1,44 @@ +--- +kind: pipeline +name: deploy to swarm-test.autonomic.zone +steps: + - name: deployment + image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest + settings: + host: swarm-test.autonomic.zone + stack: mastodon + generate_secrets: true + networks: + - proxy + purge: true + deploy_key: + from_secret: drone_ssh_swarm_test + environment: + DOMAIN: mastodon.swarm-test.autonomic.zone + STACK_NAME: mastodon + LETS_ENCRYPT_ENV: production + ENTRYPOINT_CONF_VERSION: v1 + SECRET_SECRET_KEY_BASE_VERSION: v1 + SECRET_OTP_SECRET_VERSION: v1 + SECRET_VAPID_PRIVATE_KEY_VERSION: v1 + SECRET_DB_PASSWORD_VERSION: v1 + SECRET_SMTP_PASSWORD_VERSION: v1 +trigger: + branch: + - main +--- +kind: pipeline +name: generate recipe catalogue +steps: + - name: release a new version + image: plugins/downstream + settings: + server: https://build.coopcloud.tech + token: + from_secret: drone_abra-bot_token + fork: true + repositories: + - coop-cloud/auto-recipes-catalogue-json + +trigger: + event: tag diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..fa066a5 --- /dev/null +++ b/.env.sample @@ -0,0 +1,202 @@ +TYPE=hometown + +DOMAIN={{ .Domain }} +# Enables WEB_DOMAIN if set (FOR FUTURE USE) +# USER_DOMAIN= + +## Domain aliases +# EXTRA_DOMAINS=', `www.mastodon.example.com`' +LETS_ENCRYPT_ENV=production + +# Please look at https://docs.joinmastodon.org/admin/config/ for the full documentation. +# This example will exclude explanations to make the file simple. +# Variables you *need* to change will me marked as such. +# Most optional features are commented out/disabled and will need to be enabled by you after checking the documentation. + +# Federation +# ---------- +# DO NOT CHANGE DOMAIN VARIABLES AFTER DEPLOYMENT! WILL BREAK FEDERATION!! + +# if [ -z "$USER_DOMAIN" ] +# then +# LOCAL_DOMAIN=$DOMAIN +# else +# LOCAL_DOMAIN=$USER_DOMAIN +# WEB_DOMAIN=$DOMAIN +# fi + +LOCAL_DOMAIN=$DOMAIN +# WEB_DOMAIN=$DOMAIN + +# ALTERNATE_DOMAINS=$EXTRA_DOMAINS +AUTHORIZED_FETCH=false +LIMITED_FEDERATION_MODE=false + +# Deployment +# ---------- +RAILS_ENV=production +RAILS_SERVE_STATIC_FILES=true # might need this for traefik, need to test +# TRUSTED_PROXY_IP= + +# External Services +# ================= + +# PostgreSQL +# ---------- +DB_HOST=db +DB_USER=mastodon +DB_NAME=mastodon_production +DB_PORT=5432 + +# Redis +# ----- +REDIS_HOST=redis +REDIS_PORT=6379 +# REDIS_URL= +# REDIS_NAMESPACE= +# CACHE_REDIS_HOST= +# CACHE_REDIS_PORT= +# CACHE_REDIS_URL= +# CACHE_REDIS_NAMESPACE= + +# ElasticSearch +# -------------------------------------- +ES_ENABLED=true +ES_HOST=es +ES_PORT=9200 + +# StatsD (CURRENTLY NOT SUPPORTED) +# ------------------------------- +# STATSD_ADDR +# STATSD_NAMESPACE + +# Secrets +# ======= +SECRET_SECRET_KEY_BASE_VERSION=v1 +SECRET_OTP_SECRET_VERSION=v1 +SECRET_VAPID_PRIVATE_KEY_VERSION=v1 +SECRET_DB_PASSWORD_VERSION=v1 +SECRET_SMTP_PASSWORD_VERSION=v1 + +# Web Push +# ======== +# VAPID_PUBLIC_KEY= + +# Limits +# ====== +SINGLE_USER_MODE=false +# EMAIL_DOMAIN_ALLOWLIST= +# EMAIL_DOMAIN_DENYLIST= +DEFAULT_LOCALE=en +# MAX_SESSION_ACTIVATIONS= +# USER_ACTIVE_DAYS= +# MAX_TOOT_CHARS=500 + +# Sending mail +# ============ +# SMTP_SERVER= +# SMTP_PORT= +# SMTP_LOGIN= +# SMTP_FROM_ADDRESS= +# SMTP_DOMAIN= +# SMTP_DELIVERY_METHOD= +# SMTP_AUTH_METHOD= +# SMTP_CA_FILE= +# SMTP_OPENSSL_VERIFY_MODEv +# SMTP_ENABLE_STARTTLS_AUTO= +# SMTP_TLS= +# SMTP_SSL= + +# File storage (optional) +# ======================= +# CDN_HOST= + +# Papercllp (CURRENTLY NOT SUPPORTED) +# ---------------------------------- +# PAPERCLIP_ROOT_PATH= +# PAPERCLIP_ROOT_URL= + +# S3 and AWS +# ---------- +# S3_ENABLED= +# S3_BUCKET= +# AWS_ACCESS_KEY_ID= +# AWS_SECRET_ACCESS_KEY= +# S3_REGION= +# S3_PROTOCOL= +# S3_HOSTNAME= +# S3_ENDPOINT= +# S3_SIGNATURE_VERSION= +# S3_OVERRIDE_PATH_STYLE= +# S3_OPEN_TIMEOUT= +# S3_READ_TIMEOUT= + +# External Authentication +# ======================= +# OAUTH_REDIRECT_AT_SIGN_IN= + +# LDAP +# ---- +# LDAP_ENABLED= +# LDAP_HOST= +# LDAP_PORT= +# LDAP_METHOD= +# LDAP_BASE= +# LDAP_BIND_DN= +# LDAP_PASSWORDv +# LDAP_UID= +# LDAP_SEARCH_FILTER= +# LDAP_MAIL= +# LDAP_UID_CONVERSTION_ENABLED= + +# SAML +# ---- +# SAML_ENABLED= +# SAML_ACS_URL= +# SAML_ISSUER= +# SAML_IDP_SSO_TARGET_URL= +# SAML_IDP_CERT= +# SAML_IDP_CERT_FINGERPRINT= +# SAML_NAME_IDENTIFIER_FORMAT= +# SAML_CERT= +# SAML_SECURITY_WANT_ASSERTION_SIGNED= +# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED= +# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED= +# SAML_ATTRIBUTES_STATEMENTS_UID= +# SAML_ATTRIBUTES_STATEMENTS_EMAIL= +# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME= +# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME= +# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME= +# SAML_UID_ATTRIBUTE= +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED= +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL= + +# OpenID Connect +# -------------- +# COMPOSE_FILE="compose.yml:compose.oidc.yml" +# OIDC_ENABLED=true +# OIDC_DISPLAY_NAME= +# OIDC_ISSUER= +# OIDC_DISCOVERY= +# OIDC_CLIENT_AUTH_METHOD +# OIDC_SCOPE= +# OIDC_RESPONSE_TYPE= +# OIDC_RESPONSE_MODE= +# OIDC_DISPLAY= +# OIDC_PROMPT= +# OIDC_SEND_NONCE= +# OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT= +# OIDC_IDP_LOGOUT_REDIRECT_URI= +# OIDC_UID_FIELD= +# OIDC_CLIENT_ID= +# OIDC_REDIRECT_URI= +# OIDC_HTTP_SCHEME= +# OIDC_HOST= +# OIDC_PORT= +# OIDC_AUTH_ENDPOINT= +# OIDC_TOKEN_ENDPOINT= +# OIDC_USER_INFO_ENDPOINT= +# OIDC_JWKS_URI= +# OIDC_END_SESSION_ENDPOINT= +# OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED= +# SECRET_OIDC_CLIENT_SECRET_VERSION=v1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..37b52cc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.envrc diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc80330 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# Hometown + +> A supported fork of Mastodon that provides local posting and a wider range of content types. + +The configuration aims to stay as close as possible to [coop-cloud/mastodon](https://git.autonomic.zone/coop-cloud/mastodon). +At some point, ideally, we could merge them. We don't have enough folks running +both Mastodon & Hometown to understand if that is a good idea right now. To be +discussed. + + + +* **Category**: Apps +* **Status**: 1 +* **Image**: [`decentral1se/hometown`](https://hub.docker.com/r/decentral1se/hometown) +* **Healthcheck**: No +* **Backups**: No +* **Email**: Yes +* **Tests**: No +* **SSO**: Yes + + + +## Basic usage + +See the [`coop-cloud/mastodon` `README.md`](https://git.coopcloud.tech/coop-cloud/mastodon#quick-start). + +Watch out in case the Mastodon recipe latest is not the same as the Hometown +latest version! You can switch back to a compatible tag on the Mastodon recipe +to compare docs, config etc. just to be sure. + +## Tips & Tricks + +See the [`coop-cloud/mastodon` `README.md`](https://git.coopcloud.tech/coop-cloud/mastodon#admin-tips-tricks). + +Please only gather tips & tricks that are specific to Hometown here. diff --git a/abra.sh b/abra.sh new file mode 100644 index 0000000..8d62c3f --- /dev/null +++ b/abra.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +export ENTRYPOINT_CONF_VERSION=v7 + +assets() { + set -x OTP_SECRET $(cat /run/secrets/otp_secret) + set -x SECRET_KEY_BASE $(cat /run/secrets/secret_key_base) + set -x DB_PASS $(cat /run/secrets/db_password) + + RAILS_ENV=production bundle exec rails assets:precompile +} + +setup() { + set -x OTP_SECRET $(cat /run/secrets/otp_secret) + set -x SECRET_KEY_BASE $(cat /run/secrets/secret_key_base) + set -x DB_PASS $(cat /run/secrets/db_password) + + RAILS_ENV=production bundle exec rake db:setup +} + +admin() { + set -x OTP_SECRET $(cat /run/secrets/otp_secret) + set -x SECRET_KEY_BASE $(cat /run/secrets/secret_key_base) + set -x DB_PASS $(cat /run/secrets/db_password) + + RAILS_ENV=production bin/tootctl accounts create "$1" --email "$2" --confirmed --role admin +} + +secrets() { + docker context use default > /dev/null 2>&1 + + echo "Generating secrets for new Hometown deployment..." + echo "" + + SECRET_KEY_BASE=$(docker run --rm tootsuite/mastodon:v3.4.0 bundle exec rake secret) + abra app secret insert "$APP_NAME" secret_key_base v1 "$SECRET_KEY_BASE" + echo "SECRET_KEY_BASE = $SECRET_KEY_BASE" + echo "" + + OTP_SECRET=$(docker run --rm tootsuite/mastodon:v3.4.0 bundle exec rake secret) + abra app secret insert "$APP_NAME" otp_secret v1 "$OTP_SECRET" + echo "OTP_SECRET = $OTP_SECRET" + echo "" + + docker run \ + -e SECRET_KEY_BASE="$SECRET_KEY_BASE" \ + -e OTP_SECRET="$OTP_SECRET" \ + --rm tootsuite/mastodon:v3.4.0 \ + bundle exec rake mastodon:webpush:generate_vapid_key \ + > /tmp/key.txt + + VAPID_PRIVATE_KEY=$(grep -oP "VAPID_PRIVATE_KEY=\K.+" "/tmp/key.txt") + VAPID_PUBLIC_KEY=$(grep -oP "VAPID_PUBLIC_KEY=\K.+" "/tmp/key.txt") + rm -rf /tmp/key.txt + + echo "VAPID_PUBLIC_KEY = $VAPID_PUBLIC_KEY" + echo "!IMPORTANT! you MUST insert this VAPID_PUBLIC_KEY into your app .env config !IMPORTANT!" + echo "" + + abra app secret insert "$APP_NAME" vapid_private_key v1 "$VAPID_PRIVATE_KEY" + echo "VAPID_PRIVATE_KEY = $VAPID_PRIVATE_KEY" + echo "" + + abra app secret generate "$APP_NAME" db_password v1 + echo "" + + echo "don't forget to insert your smtp_password! your deployment won't work without it" + echo "run \"abra app secret insert $APP_NAME smtp_password v1 YOURSMTPPASSWORD\"" + echo "" +} diff --git a/compose.oidc.yml b/compose.oidc.yml new file mode 100644 index 0000000..18f252e --- /dev/null +++ b/compose.oidc.yml @@ -0,0 +1,35 @@ +--- +version: "3.8" + +services: + app: + secrets: + - db_password + - otp_secret + - secret_key_base + - smtp_password + - vapid_private_key + - oidc_client_secret + + streaming: + secrets: + - db_password + - otp_secret + - secret_key_base + - smtp_password + - vapid_private_key + - oidc_client_secret + + sidekiq: + secrets: + - db_password + - otp_secret + - secret_key_base + - smtp_password + - vapid_private_key + - oidc_client_secret + +secrets: + oidc_client_secret: + name: ${STACK_NAME}_oidc_client_secret_${SECRET_OIDC_CLIENT_SECRET_VERSION} + external: true diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..1b2615e --- /dev/null +++ b/compose.yml @@ -0,0 +1,254 @@ +--- +version: "3.8" + +services: + app: + image: yakumosaki/glitch-soc:20230927_13 + command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" + networks: &bothNetworks + - proxy + - internal_network + deploy: + update_config: + failure_action: rollback + order: start-first + labels: + - "traefik.enable=true" + - "traefik.docker.network=proxy" + - "traefik.http.services.${STACK_NAME}_web.loadbalancer.server.port=3000" + - "traefik.http.routers.${STACK_NAME}_web.rule=Host(`${DOMAIN}`)" + - "traefik.http.routers.${STACK_NAME}_web.entrypoints=web-secure" + - "traefik.http.routers.${STACK_NAME}_web.tls.certresolver=${LETS_ENCRYPT_ENV}" + - "coop-cloud.${STACK_NAME}.version=0.2.3+v3.5.10-hometown-1.0.8" + configs: &configs + - source: entrypoint_sh + target: /usr/local/bin/entrypoint.sh + mode: 0555 + entrypoint: &entrypoint /usr/local/bin/entrypoint.sh + volumes: &appVolume + - app:/opt/mastodon/public/system + healthcheck: + test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy=off localhost:3000/api/v1/instance || exit 1"] + secrets: &secrets + - db_password + - otp_secret + - secret_key_base + - smtp_password + - vapid_private_key + environment: &env + - ALLOW_ACCESS_TO_HIDDEN_SERVICE + - ALTERNATE_DOMAINS + - AUTHORIZED_FETCH + - CACHE_REDIS_HOST + - CACHE_REDIS_NAMESPACE + - CACHE_REDIS_PORT + - CACHE_REDIS_URL + - DB_HOST + - DB_NAME + - DB_PORT + - DB_USER + - DB_PASS_FILE=/run/secrets/db_password + - DEFAULT_LOCALE + - EMAIL_DOMAIN_ALLOWLIST + - EMAIL_DOMAIN_DENYLIST + - ES_ENABLED + - ES_HOST + - ES_PORT + - LDAP_BASE + - LDAP_BIND_DN + - LDAP_ENABLED + - LDAP_HOST + - LDAP_MAIL + - LDAP_METHOD + - LDAP_PASSWORD + - LDAP_PORT + - LDAP_SEARCH_FILTER + - LDAP_UID + - LDAP_UID_CONVERSTION_ENABLED + - LIMITED_FEDERATION_MODE + - LOCAL_DOMAIN + - MAX_SESSION_ACTIVATIONS + - MAX_TOOT_CHARS + - OAUTH_REDIRECT_AT_SIGN_IN + - OTP_SECRET_FILE=/run/secrets/otp_secret + - OIDC_AUTH_ENDPOINT + - OIDC_CLIENT_AUTH_METHOD + - OIDC_CLIENT_ID + - OIDC_CLIENT_SECRET_FILE=/run/secrets/oidc_client_secret + - OIDC_DISCOVERY + - OIDC_DISPLAY + - OIDC_DISPLAY_NAME + - OIDC_ENABLED + - OIDC_END_SESSION_ENDPOINT + - OIDC_HOST + - OIDC_IDP_LOGOUT_REDIRECT_URI + - OIDC_ISSUER + - OIDC_JWKS_URI + - OIDC_PORT + - OIDC_PROMPT + - OIDC_REDIRECT_URI + - OIDC_RESPONSE_MODE + - OIDC_RESPONSE_TYPE + - OIDC_SCOPE + - OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED + - OIDC_SEND_NONCE + - OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT + - OIDC_TOKEN_ENDPOINT + - OIDC_UID_FIELD + - OIDC_USER_INFO_ENDPOINT + - PAPERCLIP_ROOT_PATH + - PAPERCLIP_ROOT_URL + - RAILS_ENV + - RAILS_SERVE_STATIC_FILES + - REDIS_HOST + - REDIS_NAMESPACE + - REDIS_PORT + - REDIS_URL + - SAML_ACS_URL + - SAML_ATTRIBUTES_STATEMENTS_EMAIL + - SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME + - SAML_ATTRIBUTES_STATEMENTS_FULL_NAME + - SAML_ATTRIBUTES_STATEMENTS_LAST_NAME + - SAML_ATTRIBUTES_STATEMENTS_UID + - SAML_ATTRIBUTES_STATEMENTS_VERIFIED + - SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL + - SAML_CERT + - SAML_ENABLED + - SAML_IDP_CERT + - SAML_IDP_CERT_FINGERPRINT + - SAML_IDP_SSO_TARGET_URL + - SAML_ISSUER + - SAML_NAME_IDENTIFIER_FORMAT + - SAML_PRIVATE_KEY + - SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED + - SAML_SECURITY_WANT_ASSERTION_ENCRYPTED + - SAML_SECURITY_WANT_ASSERTION_SIGNED + - SAML_UID_ATTRIBUTE + - SECRET_KEY_BASE_FILE=/run/secrets/secret_key_base + - SINGLE_USER_MODE + - SMTP_AUTH_METHOD + - SMTP_CA_FILE + - SMTP_DELIVERY_METHOD + - SMTP_DOMAIN + - SMTP_ENABLE_STARTTLS_AUTO + - SMTP_FROM_ADDRESS + - SMTP_LOGIN + - SMTP_OPENSSL_VERIFY_MODE + - SMTP_PASSWORD_FILE=/run/secrets/smtp_password + - SMTP_PORT + - SMTP_SERVER + - SMTP_SSL + - SMTP_TLS + - STATSD_ADDR + - STATSD_NAMESPACE + - USER_ACTIVE_DAYS + - VAPID_PRIVATE_KEY_FILE=/run/secrets/vapid_private_key + - VAPID_PUBLIC_KEY + - WEB_DOMAIN + + streaming: + image: yakumosaki/glitch-soc:20230927_13 + command: node ./streaming + configs: *configs + entrypoint: *entrypoint + secrets: *secrets + networks: *bothNetworks + deploy: + update_config: + failure_action: rollback + order: start-first + labels: + - "traefik.enable=true" + - "traefik.docker.network=proxy" + - "traefik.http.services.${STACK_NAME}_streaming.loadbalancer.server.port=4000" + - "traefik.http.routers.${STACK_NAME}_streaming.rule=(Host(`${DOMAIN}`) && PathPrefix(`/api/v1/streaming`))" + - "traefik.http.routers.${STACK_NAME}_streaming.entrypoints=web-secure" + - "traefik.http.routers.${STACK_NAME}_streaming.tls.certresolver=${LETS_ENCRYPT_ENV}" + environment: *env + volumes: *appVolume # used to make sure this volume is created + + sidekiq: + image: yakumosaki/glitch-soc:20230927_13 + secrets: *secrets + command: bundle exec sidekiq + configs: *configs + entrypoint: *entrypoint + deploy: + update_config: + failure_action: rollback + order: start-first + networks: *bothNetworks + volumes: *appVolume + environment: *env + + db: + image: postgres:14.5-alpine + networks: &internalNetwork + - internal_network + volumes: + - postgres:/var/lib/postgresql/data + secrets: + - db_password + environment: + - POSTGRES_DB=${DB_NAME} + - POSTGRES_PASSWORD_FILE=/run/secrets/db_password + - POSTGRES_USER=${DB_USER} + + redis: + image: redis:7.0-alpine + networks: *internalNetwork + healthcheck: + test: ["CMD", "redis-cli", "ping"] + volumes: + - redis:/data + + es: + image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2 + environment: + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - "cluster.name=es-mastodon" + - "discovery.type=single-node" + - "bootstrap.memory_lock=true" + networks: + - internal_network + volumes: + - es:/usr/share/elasticsearch/data + ulimits: + memlock: + soft: -1 + hard: -1 + +secrets: + secret_key_base: + name: ${STACK_NAME}_secret_key_base_${SECRET_SECRET_KEY_BASE_VERSION} + external: true + otp_secret: + name: ${STACK_NAME}_otp_secret_${SECRET_OTP_SECRET_VERSION} + external: true + vapid_private_key: + name: ${STACK_NAME}_vapid_private_key_${SECRET_VAPID_PRIVATE_KEY_VERSION} + external: true + db_password: + name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} + external: true + smtp_password: + name: ${STACK_NAME}_smtp_password_${SECRET_SMTP_PASSWORD_VERSION} + external: true + +volumes: + app: + redis: + postgres: + es: + +networks: + proxy: + external: true + internal_network: + internal: true + +configs: + entrypoint_sh: + name: ${STACK_NAME}_entrypoint_conf_${ENTRYPOINT_CONF_VERSION} + file: entrypoint.sh.tmpl + template_driver: golang diff --git a/entrypoint.sh.tmpl b/entrypoint.sh.tmpl new file mode 100644 index 0000000..4f218e2 --- /dev/null +++ b/entrypoint.sh.tmpl @@ -0,0 +1,37 @@ +#!/bin/bash + +set -eu + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + + export "$var"="$val" + unset "$fileVar" +} + +# for sidekiq service bundle exec env var threading +file_env "OTP_SECRET" +file_env "SECRET_KEY_BASE" +file_env "DB_PASS" +file_env "SMTP_PASSWORD" +file_env "VAPID_PRIVATE_KEY" + +{{ if eq (env "OIDC_ENABLED") "true" }} +file_env "OIDC_CLIENT_SECRET" +{{ end }} + +/usr/bin/tini -s -- "$@"