From 591d6dc4ec49b4b823e39e2e2d310d313dc0516d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 7 Oct 2026 16:41:28 +0200 Subject: [PATCH] Split Mastodon runtime deps from deployment, use Redis cluster Add a kosmos-mastodon::dependencies recipe with everything needed to run Mastodon (Node, Ruby, libvips, Elasticsearch, packages) but without the app deployment. The default recipe includes it and only runs the deployment when node['kosmos-mastodon']['deploy'] is true, so a VM can be prepared ahead of a maintenance window. Stop using the local redisio instance and connect to the external Redis cluster (redis_server role, db 2, password from the credentials data bag) instead. Remove the redisio service dependencies from the systemd units and drop the redisio cookbook dependency. --- .../kosmos-mastodon/attributes/default.rb | 17 +++- site-cookbooks/kosmos-mastodon/metadata.rb | 1 - .../kosmos-mastodon/recipes/default.rb | 84 ++++--------------- .../kosmos-mastodon/recipes/dependencies.rb | 82 ++++++++++++++++++ ...odon-sidekiq-scheduler.systemd.service.erb | 2 - .../mastodon-sidekiq.systemd.service.erb | 2 - .../default/mastodon-web.systemd.service.erb | 2 - 7 files changed, 112 insertions(+), 78 deletions(-) create mode 100644 site-cookbooks/kosmos-mastodon/recipes/dependencies.rb diff --git a/site-cookbooks/kosmos-mastodon/attributes/default.rb b/site-cookbooks/kosmos-mastodon/attributes/default.rb index 73edc79..237c46e 100644 --- a/site-cookbooks/kosmos-mastodon/attributes/default.rb +++ b/site-cookbooks/kosmos-mastodon/attributes/default.rb @@ -6,8 +6,21 @@ node.default["kosmos-mastodon"]["app_port"] = 3000 node.default["kosmos-mastodon"]["streaming_port"] = 4000 node.default["kosmos-mastodon"]["domain"] = "kosmos.social" node.default["kosmos-mastodon"]["alternate_domains"] = [] -node.default["kosmos-mastodon"]["redis_url"] = "redis://localhost:6379/0" node.default["kosmos-mastodon"]["sidekiq_threads"] = 25 + +# Only run the Mastodon deployment (code, build, migrations, services) when this +# is true. Set to false to only install the runtime dependencies. +node.default["kosmos-mastodon"]["deploy"] = true + +# Runtime versions +node.default["kosmos-mastodon"]["nodejs_version"] = "24.21.0" +node.default["kosmos-mastodon"]["ruby_version"] = "4.0.7" +node.default["kosmos-mastodon"]["ruby_build_version"] = "v20260924" + +# External Redis cluster (see the kosmos_redis cookbook) +node.default["kosmos-mastodon"]["redis_server_role"] = "redis_server" +node.default["kosmos-mastodon"]["redis_port"] = 6379 +node.default["kosmos-mastodon"]["redis_db"] = 2 node.default["kosmos-mastodon"]["allowed_private_addresses"] = "127.0.0.1" node.default["kosmos-mastodon"]["onion_address"] = nil @@ -32,5 +45,3 @@ node.default["kosmos-mastodon"]["force_default_locale"] = true # additional outgoing mail/costs. Disabled by default. node.default["kosmos-mastodon"]["disable_email_subscriptions"] = true node.default["kosmos-mastodon"]["libre_translate_endpoint"] = nil - -node.override["redisio"]["version"] = "7.4.11" diff --git a/site-cookbooks/kosmos-mastodon/metadata.rb b/site-cookbooks/kosmos-mastodon/metadata.rb index 1f31d47..4e91875 100644 --- a/site-cookbooks/kosmos-mastodon/metadata.rb +++ b/site-cookbooks/kosmos-mastodon/metadata.rb @@ -10,7 +10,6 @@ depends 'backup' depends 'elasticsearch' depends 'java' depends 'firewall' -depends 'redisio' depends 'postgresql' depends 'kosmos-nodejs' depends 'kosmos_openresty' diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 29df8b3..75f04ba 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -3,46 +3,13 @@ # Recipe:: default # -node.override["kosmos_nodejs"]["version"] = "24.21.0" +include_recipe "kosmos-mastodon::dependencies" -include_recipe "kosmos-nodejs" -include_recipe "java" -include_recipe 'redisio::default' -include_recipe 'redisio::enable' -include_recipe 'firewall' +# The rest is the actual Mastodon deployment. Skip it when only the runtime +# dependencies should be installed (e.g. to pre-stage a new VM). +return unless node["kosmos-mastodon"]["deploy"] -elasticsearch_user 'elasticsearch' - -elasticsearch_install 'elasticsearch' do - type 'package' - # The current version of the elasticsearch cookbook doesn't like versions - # it doesn't know about. This would still be installing the default (7.17.9) - # on a new machine, but it doesn't upgrade the package - download_url 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.7-amd64.deb' - # SHA256 - download_checksum '5c588d779023672ba4e315e7cd4db068ac60a38873a35973574a1cae858c2030' - action :install -end - -elasticsearch_configure 'elasticsearch' do - allocated_memory node["kosmos-mastodon"]["elasticsearch"]["allocated_memory"] - - jvm_options %w( - -XX:+AlwaysPreTouch - -server - -Xss1m - -Djava.awt.headless=true - -Dfile.encoding=UTF-8 - -Djna.nosys=true - -XX:-OmitStackTraceInFastThrow - -Dio.netty.noUnsafe=true - -Dio.netty.noKeySetOptimization=true - -Dio.netty.recycler.maxCapacityPerThread=0 - -XX:+HeapDumpOnOutOfMemoryError - ) -end - -elasticsearch_service 'elasticsearch' +require 'uri' postgresql_credentials = data_bag_item('credentials', 'postgresql') @@ -55,33 +22,21 @@ bind_ip = if node.chef_environment == "production" node["kosmos-mastodon"]["bind_ip"] end -group mastodon_user do - gid 62786 -end - -user mastodon_user do - comment "mastodon user" - uid 62786 - gid 62786 - shell "/bin/bash" - home mastodon_path -end - -# Mastodon 4.6 dropped ImageMagick in favor of libvips and requires libvips >= 8.13 -package %w(build-essential ffmpeg libxml2-dev libxslt1-dev file git - curl pkg-config libprotobuf-dev protobuf-compiler libidn-dev - libjemalloc2 libpq-dev libvips-dev) - -ruby_version = "4.0.7" - +ruby_version = node["kosmos-mastodon"]["ruby_version"] ruby_path = "/opt/ruby_build/builds/#{ruby_version}" bundle_path = "#{ruby_path}/bin/bundle" -ruby_build_install 'v20260924' -ruby_build_definition ruby_version do - prefix_path ruby_path +# External Redis cluster (see the kosmos_redis cookbook) +redis_host = search(:node, "role:#{node['kosmos-mastodon']['redis_server_role']}").first&.dig("knife_zero", "host") + +if redis_host.nil? + Chef::Log.fatal("No node found with '#{node['kosmos-mastodon']['redis_server_role']}' role. Stopping here.") + return end +redis_password = URI.encode_www_form_component(data_bag_item('credentials', 'redis')['password']) +redis_url = "redis://:#{redis_password}@#{redis_host}:#{node['kosmos-mastodon']['redis_port']}/#{node['kosmos-mastodon']['redis_db']}" + execute "systemctl daemon-reload" do command "systemctl daemon-reload" action :nothing @@ -185,7 +140,7 @@ template "#{mastodon_path}/.env.#{rails_env}" do owner mastodon_user group mastodon_user sensitive true - variables redis_url: node["kosmos-mastodon"]["redis_url"], + variables redis_url: redis_url, domain: node["kosmos-mastodon"]["domain"], alternate_domains: node["kosmos-mastodon"]["alternate_domains"], active_record_encryption_deterministic_key: credentials["active_record_encryption_deterministic_key"], @@ -225,13 +180,6 @@ execute "bundle install" do command "bundle install --without development,test --deployment" end -# Node 24 ships corepack >= 0.30, for which `corepack prepare` without an -# argument is no longer valid. Enable the shims as root and let yarn pick up -# the version pinned in package.json instead. -execute "corepack enable" do - command "corepack enable" -end - execute "yarn install" do environment deploy_env user mastodon_user diff --git a/site-cookbooks/kosmos-mastodon/recipes/dependencies.rb b/site-cookbooks/kosmos-mastodon/recipes/dependencies.rb new file mode 100644 index 0000000..6cec72f --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/recipes/dependencies.rb @@ -0,0 +1,82 @@ +# +# Cookbook Name:: kosmos-mastodon +# Recipe:: dependencies +# +# Installs everything Mastodon needs to run, without deploying or starting the +# application itself. Can be run ahead of a deployment to shorten downtime. +# + +node.override["kosmos_nodejs"]["version"] = node["kosmos-mastodon"]["nodejs_version"] + +include_recipe "kosmos-nodejs" +include_recipe "java" +include_recipe "firewall" + +elasticsearch_user 'elasticsearch' + +elasticsearch_install 'elasticsearch' do + type 'package' + # The current version of the elasticsearch cookbook doesn't like versions + # it doesn't know about. This would still be installing the default (7.17.9) + # on a new machine, but it doesn't upgrade the package + download_url 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.7-amd64.deb' + # SHA256 + download_checksum '5c588d779023672ba4e315e7cd4db068ac60a38873a35973574a1cae858c2030' + action :install +end + +elasticsearch_configure 'elasticsearch' do + allocated_memory node["kosmos-mastodon"]["elasticsearch"]["allocated_memory"] + + jvm_options %w( + -XX:+AlwaysPreTouch + -server + -Xss1m + -Djava.awt.headless=true + -Dfile.encoding=UTF-8 + -Djna.nosys=true + -XX:-OmitStackTraceInFastThrow + -Dio.netty.noUnsafe=true + -Dio.netty.noKeySetOptimization=true + -Dio.netty.recycler.maxCapacityPerThread=0 + -XX:+HeapDumpOnOutOfMemoryError + ) +end + +elasticsearch_service 'elasticsearch' + +mastodon_path = node["kosmos-mastodon"]["directory"] +mastodon_user = "mastodon" + +group mastodon_user do + gid 62786 +end + +user mastodon_user do + comment "mastodon user" + uid 62786 + gid 62786 + shell "/bin/bash" + home mastodon_path +end + +# Mastodon 4.6 dropped ImageMagick in favor of libvips and requires libvips >= 8.13 +package %w(build-essential ffmpeg libxml2-dev libxslt1-dev file git + curl pkg-config libprotobuf-dev protobuf-compiler libidn-dev + libjemalloc2 libpq-dev libvips-dev) + +ruby_version = node["kosmos-mastodon"]["ruby_version"] + +ruby_path = "/opt/ruby_build/builds/#{ruby_version}" + +ruby_build_install node["kosmos-mastodon"]["ruby_build_version"] +ruby_build_definition ruby_version do + prefix_path ruby_path +end + +# Node 24 ships corepack >= 0.30, for which `corepack prepare` without an +# argument is no longer valid. Enable the shims as root and let yarn pick up +# the version pinned in package.json instead. +execute "corepack enable" do + command "corepack enable" +end diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq-scheduler.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq-scheduler.systemd.service.erb index 82d36f4..4c9e995 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq-scheduler.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq-scheduler.systemd.service.erb @@ -1,7 +1,5 @@ [Unit] Description=mastodon-sidekiq-scheduler -Requires=redis@6379.service -After=redis@6379.service [Service] Type=simple diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb index 19452da..c6646d4 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb @@ -1,7 +1,5 @@ [Unit] Description=mastodon-sidekiq -Requires=redis@6379.service -After=redis@6379.service [Service] Type=simple diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb index 93a694e..86ce186 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb @@ -1,7 +1,5 @@ [Unit] Description=mastodon-web -Requires=redis@6379.service -After=redis@6379.service [Service] Type=simple