Last active
September 26, 2023 02:04
-
-
Save keiya/45c97e9f201e258fa7cd190be31b739c to your computer and use it in GitHub Desktop.
Mastodon for fly.io with SendGrid + Cloudflare R2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| app = "don-example-com-rails" | |
| kill_signal = "SIGTERM" | |
| kill_timeout = 60 | |
| primary_region = "nrt" | |
| [build] | |
| image = "tootsuite/mastodon:v4.2.0-rc1" | |
| [build.args] | |
| RAILS_ENV = "production" | |
| [deploy] | |
| release_command = "bundle exec rails db:prepare" | |
| [env] | |
| DB_HOST = "don-example-com-postgres.internal" | |
| DB_PORT = 5432 | |
| DB_NAME= "mastodon_production" | |
| DEFAULT_LOCALE = "ja" | |
| LOCAL_DOMAIN = "don.example.com" | |
| RAILS_ENV = "production" | |
| RAILS_SERVE_STATIC_FILES = "true" | |
| REDIS_HOST = "fly-don-example-com-redis.upstash.io" | |
| REDIS_PORT = 6379 | |
| RUBY_YJIT_ENABLE = 1 | |
| S3_ALIAS_HOST = "don-files.example.com" | |
| S3_BUCKET = "donexamplecom" | |
| S3_ENABLED = "true" | |
| S3_ENDPOINT = "https://xxxxx.r2.cloudflarestorage.com" # Cloudflare R2 is cheap than AWS S3 | |
| #S3_FORCE_SINGLE_REQUEST=true | |
| S3_HOSTNAME = "xxxxx.r2.cloudflarestorage.com" | |
| S3_PERMISSION = "private" | |
| S3_PROTOCOL = "https" | |
| S3_REGION = "auto" | |
| #SIDEKIQ_CONCURRENCY=2 | |
| SINGLE_USER_MODE = "false" | |
| SMTP_AUTH_METHOD = "plain" | |
| SMTP_FROM_ADDRESS = "don.example.com Mastodon <[email protected]>" | |
| SMTP_OPENSSL_VERIFY_MODE = "peer" | |
| SMTP_PORT = 587 | |
| SMTP_SERVER = "smtp.sendgrid.net" | |
| STREAMING_API_BASE_URL = "wss://don-stream.example.com" | |
| TRUSTED_PROXY_IP = "66.241.112.0/20,2a09:8280::/29" | |
| [processes] | |
| sidekiq = "bundle exec sidekiq" | |
| app = "bundle exec rails s -p 3000" | |
| [http_service] | |
| processes = ["app"] | |
| internal_port = 3000 | |
| # force_https = true | |
| # auto_stop_machines = true | |
| auto_start_machines = true | |
| min_machines_running = 1 | |
| [http_service.concurrency] | |
| type = "requests" | |
| soft_limit = 200 | |
| hard_limit = 250 | |
| [[http_service.checks]] | |
| grace_period = "15s" | |
| interval = "10s" | |
| method = "GET" | |
| timeout = "5s" | |
| path = "/health" | |
| [[statics]] | |
| guest_path = "/opt/mastodon/public" | |
| url_prefix = "/" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| app = "don-example-com-stream" | |
| kill_signal = "SIGINT" | |
| kill_timeout = 5 | |
| primary_region = "nrt" | |
| [build] | |
| image = "tootsuite/mastodon:v4.2.0-rc1" | |
| [build.args] | |
| NODE_ENV = "production" | |
| [env] | |
| DB_HOST = "xxx-postgres.internal" | |
| DB_PORT = 5432 | |
| DB_NAME= "mastodon_production" | |
| LOCAL_DOMAIN = "don.example.com" | |
| NODE_ENV = "production" | |
| REDIS_HOST = "xxx.upstash.io" # hostname or local ipv6 | |
| REDIS_PORT = 6379 | |
| STREAMING_API_BASE_URL = "wss://don-stream.example.com" | |
| TRUSTED_PROXY_IP = "66.241.112.0/20,2a09:8280::/29" # fly.io's reverse proxies | |
| [processes] | |
| streaming = "node ./streaming" | |
| [http_service] | |
| processes = ["streaming"] | |
| internal_port = 4000 | |
| # auto_stop_machines = true | |
| auto_start_machines = true | |
| min_machines_running = 1 | |
| [http_service.concurrency] | |
| type = "connections" | |
| soft_limit = 100 | |
| hard_limit = 150 | |
| [[http_service.checks]] | |
| grace_period = "5s" | |
| interval = "10s" | |
| method = "GET" | |
| timeout = "5s" | |
| path = "/api/v1/streaming/health" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| AWS_ACCESS_KEY_ID= | |
| AWS_SECRET_ACCESS_KEY= | |
| DB_USER=postgres | |
| DB_PASS=[copy from `flyctl postgres create`] | |
| OTP_SECRET= | |
| REDIS_PASSWORD=[copy from `flyctl redis create`] | |
| SECRET_KEY_BASE= | |
| SMTP_LOGIN=apikey | |
| SMTP_PASSWORD=SG.xxx | |
| VAPID_PRIVATE_KEY= | |
| VAPID_PUBLIC_KEY= |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Low cost Mastodon instance on Fly.io
If you use Cloudflare for front-facing CDN, you don't need to allocate static IPv4. Point your domain to the fly.io app's ipv6 address as AAAA with Cloudflare proxy. (no need to set A record)
I decided to expose the WebSocket stream server to the Internet because the free Cloudflare plan can't have many WebSocket streams. So, you need to issue a TLS certificate in fly.io. Set acme-challenge to your DNS provider. Set CNAME for the streaming server and Uncheck the
Proxyin Cloudflare DNS settings (DNS only).just like this:

These commands are based on my memory, and maybe some lacking commands are needed 🫠.
domains are:
don.example.comfor mastodon appdon-stream.example.comfor mastodon streaming serverdon-sg.example.comfor SendGriddon-files.example.comfor media files (AWS S3 or Cloudflare R2)if you use a slower CPU machine, you may need to set longer
http_service.checks.grace_periodbecause container boot time will take much longer on slow machines.