seuros / capistrano-puma

Puma integration for Capistrano
https://github.com/seuros/capistrano-puma
MIT License
615 stars 299 forks source link

Update to Puma 6 with capistrano3-puma 6.0.0.beta.1 #376

Open Soeren-Klatt opened 2 months ago

Soeren-Klatt commented 2 months ago

Sadly the gem is not really maintained right now, but there is the gem gem 'capistrano3-puma', '6.0.0.beta.1'. I was able to update to Puma 6 with but run in to more problems with the "new" systemd services. With the new beta version of this gem, you need to create user specific services what i really liked. Before i had to set which user can use which service in the visudo. From now on every user gets his own services under ~/.config/systemd/user/<application_name>_puma_<stage_name>.service. For me it was a pain to create these services for every application on my own, that why i just build a small task that is executed after the deploy finished.

# only needed for puma 6 or higher
  desc 'Create systemd user service for Puma'
  task :create_puma_service do
    on roles(:app) do

      service_name = "#{fetch(:application)}_puma_#{fetch(:stage)}.service"
      service_path = "/home/#{fetch(:user)}/.config/systemd/user/#{service_name}"
      rbenv_path = "/home/#{fetch(:user)}/.rbenv/bin/rbenv"

      # Check if the service already exists
      if test("[ -f #{service_path} ]")
        puts "Service already exists. Skipping creation."
        next
      end
      # Create the directory for the user service file if it doesn't exist
      execute "mkdir -p /home/#{fetch(:user)}/.config/systemd/user"

      # Define the service file content
      service_content = <<-EOF
        [Unit]
        Description=Puma HTTP Server for #{fetch(:application)} (#{fetch(:stage)})
        After=network.target

        [Service]
        Type=simple
        WorkingDirectory=#{fetch(:deploy_to)}/current
        ExecStart=#{rbenv_path} exec bundle exec puma -C #{fetch(:deploy_to)}/shared/puma.rb
        Restart=always
        RestartSec=1
        SyslogIdentifier=puma

        # Use journald for logging; comment these out if you prefer file logging
        StandardOutput=journal
        StandardError=journal

        # Uncomment these lines if you prefer file logging
        # StandardOutput=append:#{fetch(:deploy_to)}/current/log/puma.stdout.log
        # StandardError=append:#{fetch(:deploy_to)}/current/log/puma.stderr.log

        [Install]
        WantedBy=default.target
      EOF

      # Upload the service file with proper line breaks
      upload! StringIO.new(service_content), service_path

      execute "systemctl --user daemon-reload"
      execute "systemctl --user restart #{service_name}"
    end
  end

Just put this for example in your staging.rb under the namespace deploy and add after :finishing, :create_puma_service. Maybe you have to adjust some paths.

Im not sure, why this isnt included in the gem directly but maybe it will in the future.^^

microspino commented 1 month ago

@Soeren-Klatt super grateful for this task Thanks a lot.