--- version: "3.8" services: db: image: postgres:9.6-alpine networks: &internalNetwork - internal_network healthcheck: test: ["CMD", "pg_isready", "-U", "postgres"] volumes: - postgres:/var/lib/postgresql/data secrets: - db_password environment: - POSTGRES_DB=${DB_NAME} - POSTGRES_PASSWORD=${DB_PASS} - POSTGRES_PASSWORD_FILE=/run/secrets/db_password - POSTGRES_USER=${DB_USER} redis: image: redis:6.0-alpine networks: *internalNetwork healthcheck: test: ["CMD", "redis-cli", "ping"] volumes: - redis:/data es: image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10 environment: - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - "cluster.name=es-mastodon" - "discovery.type=single-node" - "bootstrap.memory_lock=true" networks: - internal_network healthcheck: test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] volumes: - es:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 web: image: &image tootsuite/mastodon:v3.3.0 command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" networks: &bothNetworks - proxy - internal_network healthcheck: test: [ "CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1", ] 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}" # WEB_DOMAIN redirect #- "traefik.http.routers.${STACK_NAME}_web.rule=(Host(`${DOMAIN}`) || (Host(`${LOCAL_DOMAIN}`) && Path(`/.well-known/webfinger`)))" # - "traefik.http.middlewares.mastodon-webfinger.redirectregex.regex=^https?://${LOCAL_DOMAIN}/.*" #^(http|https)://${LOCAL_DOMAIN}/.well-known/webfinger" # # - "traefik.http.middlewares.mastodon-webfinger.redirectregex.permanent=true" # - "traefik.http.middlewares.mastodon-webfinger.redirectregex.replacement=https://${WEB_DOMAIN}/.well-known/webfinger" # - "traefik.http.routers.${STACK_NAME}_hack.rule=(Host(`${LOCAL_DOMAIN}`) && Path(`/.well-known/`))" # - "traefik.http.routers.${STACK_NAME}_hack.entrypoints=websecure" # - "traefik.http.routers.${STACK_NAME}_hack.middlewares=mastodon-webfinger@docker" configs: &configs - source: entrypoint_sh target: /usr/local/bin/entrypoint.sh mode: 0555 entrypoint: &entrypoint /usr/local/bin/entrypoint.sh volumes: &appVolume - app:/mastodon secrets: &secrets - db_password - otp_secret - secret_key_base - smtp_password - vapid_private_key environment: &env - DB_HOST - DB_USER - DB_NAME - DB_PASS_FILE=/run/secrets/db_password - DB_PORT - REDIS_HOST - REDIS_PORT - REDIS_URL - REDIS_NAMESPACE - CACHE_REDIS_HOST - CACHE_REDIS_PORT - CACHE_REDIS_URL - CACHE_REDIS_NAMESPACE - ES_ENABLED - ES_HOST - ES_PORT - ES_PREFIX - STATSD_ADDR - STATSD_NAMESPACE - VAPID_PRIVATE_KEY_FILE=/run/secrets/vapid_private_key - VAPID_PUBLIC_KEY - OTP_SECRET_FILE=/run/secrets/otp_secret - SECRET_KEY_BASE_FILE=/run/secrets/secret_key_base - LOCAL_DOMAIN - WEB_DOMAIN - ALTERNATE_DOMAINS - AUTHORIZED_FETCH - LIMITED_FEDERATION_MODE - RAILS_ENV - RAILS_SERVE_STATIC_FILES - SINGLE_USER_MODE - EMAIL_DOMAIN_ALLOWLIST - EMAIL_DOMAIN_DENYLIST - DEFAULT_LOCALE - MAX_SESSION_ACTIVATIONS - USER_ACTIVE_DAYS - SMTP_SERVER - SMTP_PORT - SMTP_LOGIN - SMTP_PASSWORD_FILE=/run/secrets/smtp_password - SMTP_FROM_ADDRESS - SMTP_DOMAIN - SMTP_DELIVERY_METHOD - SMTP_AUTH_METHOD - SMTP_CA_FILE - SMTP_OPENSSL_VERIFY_MODE - SMTP_ENABLE_STARTTLS_AUTO - SMTP_TLS - SMTP_SSL - PAPERCLIP_ROOT_PATH - PAPERCLIP_ROOT_URL - OAUTH_REDIRECT_AT_SIGN_IN - LDAP_ENABLED - LDAP_HOST - LDAP_PORT - LDAP_METHOD - LDAP_BASE - LDAP_BIND_DN - LDAP_PASSWORD - LDAP_UID - LDAP_SEARCH_FILTER - LDAP_MAIL - LDAP_UID_CONVERSTION_ENABLED - 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_PRIVATE_KEY - 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 - http_proxy # yes, this should be lowercase - ALLOW_ACCESS_TO_HIDDEN_SERVICE streaming: image: *image command: node ./streaming configs: *configs entrypoint: *entrypoint secrets: *secrets networks: *bothNetworks healthcheck: test: [ "CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1", ] 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}" ## Redirect from EXTRA_DOMAINS to DOMAIN #- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true" #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}" environment: *env volumes: *appVolume # used to make sure this volume is created sidekiq: image: *image 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 secrets: secret_key_base: name: ${STACK_NAME}_secret_key_base_${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