From dbb811308011be6f15091f0984c3350df668b81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20=C3=81lvarez?= Date: Wed, 17 Dec 2025 18:25:07 +0100 Subject: [PATCH 1/3] Extend the number of Beta environments --- saas/.kamal/secrets.beta1 | 1 + saas/.kamal/secrets.beta2 | 1 + saas/.kamal/secrets.beta3 | 1 + saas/.kamal/secrets.beta4 | 1 + saas/README.md | 9 ++- saas/config/deploy.beta.yml | 69 +++++++++++++++++-- saas/config/deploy.beta1.yml | 2 + saas/config/deploy.beta2.yml | 2 + saas/config/deploy.beta3.yml | 2 + saas/config/deploy.beta4.yml | 2 + .../migrate-content-to-slugged-urls.rb | 6 +- 11 files changed, 84 insertions(+), 12 deletions(-) create mode 120000 saas/.kamal/secrets.beta1 create mode 120000 saas/.kamal/secrets.beta2 create mode 120000 saas/.kamal/secrets.beta3 create mode 120000 saas/.kamal/secrets.beta4 create mode 100644 saas/config/deploy.beta1.yml create mode 100644 saas/config/deploy.beta2.yml create mode 100644 saas/config/deploy.beta3.yml create mode 100644 saas/config/deploy.beta4.yml diff --git a/saas/.kamal/secrets.beta1 b/saas/.kamal/secrets.beta1 new file mode 120000 index 0000000000..80e6c155e1 --- /dev/null +++ b/saas/.kamal/secrets.beta1 @@ -0,0 +1 @@ +secrets.beta \ No newline at end of file diff --git a/saas/.kamal/secrets.beta2 b/saas/.kamal/secrets.beta2 new file mode 120000 index 0000000000..80e6c155e1 --- /dev/null +++ b/saas/.kamal/secrets.beta2 @@ -0,0 +1 @@ +secrets.beta \ No newline at end of file diff --git a/saas/.kamal/secrets.beta3 b/saas/.kamal/secrets.beta3 new file mode 120000 index 0000000000..80e6c155e1 --- /dev/null +++ b/saas/.kamal/secrets.beta3 @@ -0,0 +1 @@ +secrets.beta \ No newline at end of file diff --git a/saas/.kamal/secrets.beta4 b/saas/.kamal/secrets.beta4 new file mode 120000 index 0000000000..80e6c155e1 --- /dev/null +++ b/saas/.kamal/secrets.beta4 @@ -0,0 +1 @@ +secrets.beta \ No newline at end of file diff --git a/saas/README.md b/saas/README.md index 80ff67a36a..69697ded44 100644 --- a/saas/README.md +++ b/saas/README.md @@ -64,9 +64,14 @@ This environment uses a FlashBlade bucket for blob storage. Beta is primarily intended for testing product features. It uses the same production database and Active Storage configuration. -Beta tenant is: +There are 4 beta environments: -- https://fizzy-beta.37signals.com +- https://beta1.fizzy-beta.com +- https://beta2.fizzy-beta.com +- https://beta3.fizzy-beta.com +- https://beta4.fizzy-beta.com + +Deploy with: `bin/kamal deploy -d beta1` (or `-d beta2`, `-d beta3`, `-d beta4`) ### Staging diff --git a/saas/config/deploy.beta.yml b/saas/config/deploy.beta.yml index 9bf6457f6a..8a9c7d860c 100644 --- a/saas/config/deploy.beta.yml +++ b/saas/config/deploy.beta.yml @@ -1,14 +1,70 @@ +<% + raise "The BETA_NUMBER environment variable must be given" unless ENV["BETA_NUMBER"] + @data = { + "1" => { + "hosts" => { + "web" => ["fizzy-beta-app-101.df-iad-int.37signals.com"], + "jobs" => ["fizzy-beta-jobs-101.df-iad-int.37signals.com"], + "lb" => "fizzy-beta-lb-101.df-iad-int.37signals.com" + }, + "dbs" => { + "solidqueue" => "fizzy-beta-solidqueue-db-101.df-iad-int.37signals.com" + } + }, + "2" => { + "hosts" => { + "web" => ["fizzy-beta-app-102.df-iad-int.37signals.com"], + "jobs" => ["fizzy-beta-jobs-102.df-iad-int.37signals.com"], + "lb" => "fizzy-beta-lb-102.df-iad-int.37signals.com" + }, + "dbs" => { + "solidqueue" => "fizzy-beta-solidqueue-db-102.df-iad-int.37signals.com" + } + }, + "3" => { + "hosts" => { + "web" => ["fizzy-beta-app-103.df-iad-int.37signals.com"], + "jobs" => ["fizzy-beta-jobs-103.df-iad-int.37signals.com"], + "lb" => "fizzy-beta-lb-103.df-iad-int.37signals.com" + }, + "dbs" => { + "solidqueue" => "fizzy-beta-solidqueue-db-103.df-iad-int.37signals.com" + } + }, + "4" => { + "hosts" => { + "web" => ["fizzy-beta-app-104.df-iad-int.37signals.com"], + "jobs" => ["fizzy-beta-jobs-104.df-iad-int.37signals.com"], + "lb" => "fizzy-beta-lb-104.df-iad-int.37signals.com" + }, + "dbs" => { + "solidqueue" => "fizzy-beta-solidqueue-db-104.df-iad-int.37signals.com" + } + } + } + @beta_number = ENV["BETA_NUMBER"] + raise "Beta #{@beta_number} doesn't appear to be defined" unless @data[@beta_number] + + @web_hosts = @data[@beta_number]["hosts"]["web"] + @job_hosts = @data[@beta_number]["hosts"]["jobs"] + @lb_host = @data[@beta_number]["hosts"]["lb"] + @solidqueue_db = @data[@beta_number]["dbs"]["solidqueue"] +%> + retain_containers: 1 servers: web: hosts: - - fizzy-beta-app-01.sc-chi-int.37signals.com: sc_chi + - <%= @web_hosts[0] %>: df_iad labels: otel_scrape_enabled: true -# we don't run the jobs role in beta -allow_empty_roles: true + jobs: + hosts: + - <%= @job_hosts[0] %>: df_iad + labels: + otel_scrape_enabled: true proxy: ssl: false @@ -22,8 +78,8 @@ env: MYSQL_DATABASE_HOST: fizzy-mysql-primary MYSQL_DATABASE_REPLICA_HOST: fizzy-mysql-replica MYSQL_SOLID_CABLE_HOST: fizzy-mysql-primary - MYSQL_SOLID_QUEUE_HOST: fizzy-mysql-primary - MYSQL_SOLID_CACHE_HOST: fizzy-beta-solidcache-db-101 + MYSQL_SOLID_QUEUE_HOST: <%= @solidqueue_db %> + MYSQL_SOLID_CACHE_HOST: fizzy-beta-solidcache-db-101.df-iad-int.37signals.com secret: - RAILS_MASTER_KEY - MYSQL_ALTER_PASSWORD @@ -48,14 +104,13 @@ env: - STRIPE_SECRET_KEY - STRIPE_WEBHOOK_SECRET tags: - sc_chi: {} df_iad: PRIMARY_DATACENTER: true accessories: load-balancer: image: basecamp/kamal-proxy:lb - host: fizzy-beta-lb-01.sc-chi-int.37signals.com + host: <%= @lb_host %> labels: otel_role: load-balancer otel_service: fizzy-load-balancer diff --git a/saas/config/deploy.beta1.yml b/saas/config/deploy.beta1.yml new file mode 100644 index 0000000000..8cf8899b90 --- /dev/null +++ b/saas/config/deploy.beta1.yml @@ -0,0 +1,2 @@ +<% ENV["BETA_NUMBER"] = "1" %> +<%= ERB.new(File.read(File.join(Gem::Specification.find_by_name("fizzy-saas").gem_dir, "config", "deploy.beta.yml")), trim_mode: 2).result %> diff --git a/saas/config/deploy.beta2.yml b/saas/config/deploy.beta2.yml new file mode 100644 index 0000000000..97d348be63 --- /dev/null +++ b/saas/config/deploy.beta2.yml @@ -0,0 +1,2 @@ +<% ENV["BETA_NUMBER"] = "2" %> +<%= ERB.new(File.read(File.join(Gem::Specification.find_by_name("fizzy-saas").gem_dir, "config", "deploy.beta.yml")), trim_mode: 2).result %> diff --git a/saas/config/deploy.beta3.yml b/saas/config/deploy.beta3.yml new file mode 100644 index 0000000000..fc20f4c027 --- /dev/null +++ b/saas/config/deploy.beta3.yml @@ -0,0 +1,2 @@ +<% ENV["BETA_NUMBER"] = "3" %> +<%= ERB.new(File.read(File.join(Gem::Specification.find_by_name("fizzy-saas").gem_dir, "config", "deploy.beta.yml")), trim_mode: 2).result %> diff --git a/saas/config/deploy.beta4.yml b/saas/config/deploy.beta4.yml new file mode 100644 index 0000000000..966c17fd4e --- /dev/null +++ b/saas/config/deploy.beta4.yml @@ -0,0 +1,2 @@ +<% ENV["BETA_NUMBER"] = "4" %> +<%= ERB.new(File.read(File.join(Gem::Specification.find_by_name("fizzy-saas").gem_dir, "config", "deploy.beta.yml")), trim_mode: 2).result %> diff --git a/script/migrations/migrate-content-to-slugged-urls.rb b/script/migrations/migrate-content-to-slugged-urls.rb index 9253d53638..f5f13f90bc 100755 --- a/script/migrations/migrate-content-to-slugged-urls.rb +++ b/script/migrations/migrate-content-to-slugged-urls.rb @@ -3,9 +3,9 @@ require_relative "../config/environment" domains = { - "production" => "box-car.com", - "beta" => "fizzy-beta.37signals.com", - "staging" => "fizzy.37signals-staging.com" + "production" => "app.fizzy.do", + "beta" => ENV.fetch("APP_FQDN", "beta1.fizzy-beta.com"), + "staging" => "app.fizzy-staging.com" } def fix_attachments(rich_text) From 78d3a72cc4634e6ebe9293936707a9671a9f0ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20=C3=81lvarez?= Date: Fri, 19 Dec 2025 18:01:05 +0100 Subject: [PATCH 2/3] Update script to configure betas load balancers --- saas/script/configure-lb-beta.sh | 38 ++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/saas/script/configure-lb-beta.sh b/saas/script/configure-lb-beta.sh index 73844ee2b7..89895c67d5 100755 --- a/saas/script/configure-lb-beta.sh +++ b/saas/script/configure-lb-beta.sh @@ -2,14 +2,38 @@ set -e -# fizzy-beta-lb-01.sc-chi-int.37signals.com -# -ssh app@fizzy-beta-lb-01.sc-chi-int.37signals.com \ +# Beta 1: fizzy-beta-lb-101 -> fizzy-beta-app-101 +ssh app@fizzy-beta-lb-101.df-iad-int.37signals.com \ docker exec fizzy-load-balancer \ kamal-proxy deploy fizzy \ --force \ --tls \ - --host=fizzy-beta.37signals.com \ - --writer-affinity-timeout=0 \ - --target=fizzy-beta-app-101.df-iad-int.37signals.com \ - --read-target=fizzy-beta-app-01.sc-chi-int.37signals.com + --host=beta1.fizzy-beta.com \ + --target=fizzy-beta-app-101.df-iad-int.37signals.com + +# Beta 2: fizzy-beta-lb-102 -> fizzy-beta-app-102 +ssh app@fizzy-beta-lb-102.df-iad-int.37signals.com \ + docker exec fizzy-load-balancer \ + kamal-proxy deploy fizzy \ + --force \ + --tls \ + --host=beta2.fizzy-beta.com \ + --target=fizzy-beta-app-102.df-iad-int.37signals.com + +# Beta 3: fizzy-beta-lb-103 -> fizzy-beta-app-103 +ssh app@fizzy-beta-lb-103.df-iad-int.37signals.com \ + docker exec fizzy-load-balancer \ + kamal-proxy deploy fizzy \ + --force \ + --tls \ + --host=beta3.fizzy-beta.com \ + --target=fizzy-beta-app-103.df-iad-int.37signals.com + +# Beta 4: fizzy-beta-lb-104 -> fizzy-beta-app-104 +ssh app@fizzy-beta-lb-104.df-iad-int.37signals.com \ + docker exec fizzy-load-balancer \ + kamal-proxy deploy fizzy \ + --force \ + --tls \ + --host=beta4.fizzy-beta.com \ + --target=fizzy-beta-app-104.df-iad-int.37signals.com From 037559fb25b3c9c742abc917efa171b6eb014dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20=C3=81lvarez?= Date: Tue, 23 Dec 2025 11:44:03 +0100 Subject: [PATCH 3/3] Set beta site automatically in deployment --- saas/config/deploy.beta.yml | 1 + saas/config/environments/beta.rb | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/saas/config/deploy.beta.yml b/saas/config/deploy.beta.yml index 8a9c7d860c..18f4b8cbc2 100644 --- a/saas/config/deploy.beta.yml +++ b/saas/config/deploy.beta.yml @@ -74,6 +74,7 @@ ssh: env: clear: + APP_FQDN: beta<%= @beta_number %>.fizzy-beta.com RAILS_ENV: beta MYSQL_DATABASE_HOST: fizzy-mysql-primary MYSQL_DATABASE_REPLICA_HOST: fizzy-mysql-replica diff --git a/saas/config/environments/beta.rb b/saas/config/environments/beta.rb index 11025f141d..c7c6b79bdb 100644 --- a/saas/config/environments/beta.rb +++ b/saas/config/environments/beta.rb @@ -1,8 +1,8 @@ require_relative "production" Rails.application.configure do - config.action_mailer.smtp_settings[:domain] = "fizzy-beta.37signals.com" + config.action_mailer.smtp_settings[:domain] = ENV.fetch("APP_FQDN", "fizzy-beta.com") config.action_mailer.smtp_settings[:address] = "smtp-outbound-staging" - config.action_mailer.default_url_options = { host: "fizzy-beta.37signals.com", protocol: "https" } - config.action_controller.default_url_options = { host: "fizzy-beta.37signals.com", protocol: "https" } + config.action_mailer.default_url_options = { host: ENV.fetch("APP_FQDN", "fizzy-beta.com"), protocol: "https" } + config.action_controller.default_url_options = { host: ENV.fetch("APP_FQDN", "fizzy-beta.com"), protocol: "https" } end