capistrano3-puma 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -2
- data/LICENSE.txt +1 -1
- data/README.md +111 -5
- data/lib/capistrano/puma/systemd.rb +1 -4
- data/lib/capistrano/puma.rb +13 -12
- data/lib/capistrano/templates/puma.service.erb +7 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0e3b56cceac3a829240f070437a0e232c5c79f38370989572024ab08af9038a
|
4
|
+
data.tar.gz: 67e21b9c665facae205f009b694d6a2652c0a9546c95a3db3739fac5c5a0159f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c216aed4f83378c3ecf0a2bb0cab5c7046eb1a2ad9bf280691ea4325e6d583dbf98640c14e7c8e793eb8ee9c3645d2c0da17b9205e20db3c48b330fa4ed80ed
|
7
|
+
data.tar.gz: 4b19a5a3c2513402c5987ec0e501e5dcb19d7fb47e80b3ad4eec037d1a4171c1ba9645c0bad51f8cc28f5c8f16f215084015f1e32861784fd13ccbe364a995a1
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
[
|
4
|
-
|
3
|
+
## [6.2.0](https://github.com/seuros/capistrano-puma/tree/6.2.0) (2025-06-22)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/seuros/capistrano-puma/compare/v6.1.0...6.2.0)
|
6
|
+
- Harmonized interface with capistrano-sidekiq for better ecosystem consistency
|
7
|
+
- Aligned configuration variable naming patterns
|
8
|
+
- Unified systemd command execution methods
|
9
|
+
- Standardized template search order across both gems
|
10
|
+
- Added documentation reference to example application
|
11
|
+
|
12
|
+
## [6.1.0](https://github.com/seuros/capistrano-puma/tree/6.1.0) (2025-01-21)
|
13
|
+
|
14
|
+
[Full Changelog](https://github.com/seuros/capistrano-puma/compare/v6.0.0...6.1.0)
|
15
|
+
- Restored default value for `puma_bind` to fix socket activation (Issue #387)
|
16
|
+
- Added documentation for puma.rb symlink requirement in v6.0.0 (Issue #384)
|
17
|
+
- Made WatchdogSec configurable via `puma_systemd_watchdog_sec` (Issue #373)
|
18
|
+
- Improved documentation for first-time setup and troubleshooting (Issues #377, #376, #372)
|
19
|
+
- Added migration guide for upgrading from v5 to v6
|
20
|
+
- Added troubleshooting section for common issues
|
21
|
+
- Removed support for monit and upstart (will add them back if someone is willing to maintain them)
|
5
22
|
- Sync configuration with capistrano-sidekiq
|
6
23
|
- Support for notify systemd service. Add sd_notify gem to your Gemfile.
|
7
24
|
- Add example application for easier testing.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
[](http://badge.fury.io/rb/capistrano3-puma)
|
2
2
|
# Capistrano::Puma
|
3
3
|
|
4
|
+
Puma integration for Capistrano - providing systemd service management and zero-downtime deployments for Puma 5.1+.
|
5
|
+
|
6
|
+
## Example Application
|
7
|
+
|
8
|
+
For a complete working example of this gem in action, see the [capistrano-example-app](https://github.com/seuros/capistrano-example-app) which demonstrates:
|
9
|
+
- Rails 8.0 deployment with Capistrano
|
10
|
+
- Puma 6.0 with systemd socket activation
|
11
|
+
- Zero-downtime deployments
|
12
|
+
- rbenv integration
|
13
|
+
- Nginx configuration examples
|
14
|
+
|
4
15
|
## Installation
|
5
16
|
|
6
17
|
Add this line to your application's Gemfile:
|
@@ -15,6 +26,34 @@ And then execute:
|
|
15
26
|
|
16
27
|
$ bundle
|
17
28
|
|
29
|
+
## Upgrading from Version 5.x to 6.x
|
30
|
+
|
31
|
+
Version 6.0 includes several breaking changes:
|
32
|
+
|
33
|
+
### Breaking Changes:
|
34
|
+
1. **Manual Puma Configuration**: The gem no longer generates `puma.rb` automatically
|
35
|
+
- You must create your own `config/puma.rb` in your repository
|
36
|
+
- Add it to `linked_files` in your `deploy.rb`
|
37
|
+
|
38
|
+
2. **Default puma_bind Removed**: You must explicitly set the bind address
|
39
|
+
```ruby
|
40
|
+
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
|
41
|
+
```
|
42
|
+
|
43
|
+
3. **Systemd Service Changes**: Services are now user-specific by default
|
44
|
+
- Services are created in `~/.config/systemd/user/`
|
45
|
+
- Run `cap production puma:install` again after upgrading
|
46
|
+
|
47
|
+
### Migration Steps:
|
48
|
+
1. Create your `config/puma.rb` if you don't have one
|
49
|
+
2. Add to your `deploy.rb`:
|
50
|
+
```ruby
|
51
|
+
append :linked_files, 'config/puma.rb'
|
52
|
+
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
|
53
|
+
```
|
54
|
+
3. Run `cap production puma:install` to update the systemd service
|
55
|
+
4. Deploy as normal
|
56
|
+
|
18
57
|
## Usage
|
19
58
|
```ruby
|
20
59
|
# Capfile
|
@@ -43,17 +82,53 @@ To make it work with rvm, rbenv and chruby, install the plugin after correspondi
|
|
43
82
|
### Config
|
44
83
|
|
45
84
|
Puma configuration is expected to be in `config/puma.rb` or `config/puma/#{fetch(:puma_env)}.rb` and checked in your repository.
|
46
|
-
Uploading the configuration via capistrano was removed as it was causing problems with custom configurations.
|
47
85
|
|
48
|
-
|
86
|
+
Starting with version 6.0.0, you need to manage the puma configuration file yourself. Here are the steps:
|
49
87
|
|
50
|
-
|
51
|
-
|
88
|
+
1. Create your puma configuration in `shared/config/puma.rb` on the server
|
89
|
+
2. Add it to linked_files in your `deploy.rb`:
|
90
|
+
```ruby
|
91
|
+
append :linked_files, 'config/puma.rb'
|
92
|
+
```
|
93
|
+
|
94
|
+
This ensures the puma configuration persists across deployments. The systemd service will start puma with `puma -e <environment>` from your app's current directory.
|
95
|
+
|
96
|
+
### First-Time Setup (IMPORTANT! 🎉)
|
97
|
+
|
98
|
+
**🙋 Hey there, human! Read this magical section and save yourself from confusion! 😊**
|
99
|
+
|
100
|
+
Before your first deployment, you MUST install the Puma systemd service on your server:
|
101
|
+
|
102
|
+
```bash
|
103
|
+
# ✨ This only needs to be done once per server/stage - it's like a first date! 💝
|
52
104
|
$ bundle exec cap production puma:install
|
53
105
|
```
|
54
106
|
|
55
|
-
|
107
|
+
This command will:
|
108
|
+
- 🏗️ Create the systemd service files for Puma
|
109
|
+
- 🚀 Enable the service to start on boot
|
110
|
+
- 🔐 Set up the proper user permissions
|
111
|
+
|
112
|
+
**🎭 Plot twist:** Without running this command first, your deployment will succeed but Puma won't start! (We know, it's sneaky like that 😅)
|
113
|
+
|
114
|
+
### Deployment
|
115
|
+
|
116
|
+
After the initial setup, normal deployments will work as expected:
|
117
|
+
```bash
|
118
|
+
$ bundle exec cap production deploy
|
119
|
+
```
|
120
|
+
|
121
|
+
The deployment process will automatically restart Puma using the installed systemd service.
|
122
|
+
|
123
|
+
To manually control the Puma service:
|
124
|
+
```bash
|
125
|
+
$ bundle exec cap production puma:start
|
126
|
+
$ bundle exec cap production puma:stop
|
127
|
+
$ bundle exec cap production puma:restart
|
56
128
|
```
|
129
|
+
|
130
|
+
To uninstall the systemd service:
|
131
|
+
```bash
|
57
132
|
$ bundle exec cap production puma:uninstall
|
58
133
|
```
|
59
134
|
|
@@ -100,6 +175,8 @@ Configurable options, shown here with defaults: Please note the configuration op
|
|
100
175
|
```ruby
|
101
176
|
set :puma_user, fetch(:user)
|
102
177
|
set :puma_role, :web
|
178
|
+
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
|
179
|
+
set :puma_systemd_watchdog_sec, 10 # Set to 0 or false to disable watchdog
|
103
180
|
set :puma_service_unit_env_files, []
|
104
181
|
set :puma_service_unit_env_vars, []
|
105
182
|
```
|
@@ -109,6 +186,35 @@ __Notes:__ If you are setting values for variables that might be used by other p
|
|
109
186
|
append :rbenv_map_bins, 'puma', 'pumactl'
|
110
187
|
```
|
111
188
|
|
189
|
+
## Troubleshooting
|
190
|
+
|
191
|
+
### Puma is not starting after deployment
|
192
|
+
- Ensure you ran `cap production puma:install` before your first deployment
|
193
|
+
- Check the service status: `cap production puma:status`
|
194
|
+
- Check logs: `sudo journalctl -u your_app_puma_production -n 100`
|
195
|
+
|
196
|
+
### Nginx 502 Bad Gateway errors
|
197
|
+
This usually means nginx and puma have mismatched configurations:
|
198
|
+
- If nginx expects a unix socket but puma binds to a port (or vice versa)
|
199
|
+
- Ensure your `puma_bind` in deploy.rb matches your nginx upstream configuration
|
200
|
+
- Common configurations:
|
201
|
+
```ruby
|
202
|
+
# Unix socket (default)
|
203
|
+
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
|
204
|
+
|
205
|
+
# TCP port
|
206
|
+
set :puma_bind, "tcp://0.0.0.0:3000"
|
207
|
+
```
|
208
|
+
|
209
|
+
### Puma keeps restarting (systemd watchdog kills it)
|
210
|
+
- Your app may take longer than 10 seconds to boot
|
211
|
+
- Disable or increase WatchdogSec (requires version 6.0.0+):
|
212
|
+
```ruby
|
213
|
+
set :puma_systemd_watchdog_sec, 30 # 30 seconds
|
214
|
+
# or
|
215
|
+
set :puma_systemd_watchdog_sec, 0 # Disable watchdog
|
216
|
+
```
|
217
|
+
|
112
218
|
# Nginx documentation
|
113
219
|
Nginx documentation was moved to [nginx.md](docs/nginx.md)
|
114
220
|
|
@@ -14,6 +14,7 @@ module Capistrano
|
|
14
14
|
set_if_empty :puma_systemctl_bin, -> { fetch(:systemctl_bin, '/bin/systemctl') }
|
15
15
|
set_if_empty :puma_service_unit_name, -> { "#{fetch(:application)}_puma_#{fetch(:stage)}" }
|
16
16
|
set_if_empty :puma_enable_socket_service, false
|
17
|
+
set_if_empty :puma_systemd_watchdog_sec, 10
|
17
18
|
|
18
19
|
set_if_empty :puma_service_unit_env_files, -> { fetch(:service_unit_env_files, []) }
|
19
20
|
set_if_empty :puma_service_unit_env_vars, -> { fetch(:service_unit_env_vars, []) }
|
@@ -25,10 +26,6 @@ module Capistrano
|
|
25
26
|
set_if_empty :puma_service_templates_path, fetch(:service_templates_path, 'config/deploy/templates')
|
26
27
|
end
|
27
28
|
|
28
|
-
def expanded_bundle_command
|
29
|
-
backend.capture(:echo, SSHKit.config.command_map[:bundle]).strip
|
30
|
-
end
|
31
|
-
|
32
29
|
def fetch_systemd_unit_path
|
33
30
|
if fetch(:puma_systemctl_user) == :system
|
34
31
|
"/etc/systemd/system/"
|
data/lib/capistrano/puma.rb
CHANGED
@@ -6,18 +6,18 @@ module Capistrano
|
|
6
6
|
def puma_switch_user(role, &block)
|
7
7
|
user = puma_user(role)
|
8
8
|
if user == role.user
|
9
|
-
|
9
|
+
yield
|
10
10
|
else
|
11
|
-
backend.as
|
12
|
-
block.call
|
13
|
-
end
|
11
|
+
backend.as(user, &block)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
17
15
|
def puma_user(role)
|
18
16
|
properties = role.properties
|
17
|
+
return role.user unless properties
|
18
|
+
|
19
19
|
properties.fetch(:puma_user) || # local property for puma only
|
20
|
-
fetch(:puma_user) ||
|
20
|
+
fetch(:puma_user, nil) ||
|
21
21
|
properties.fetch(:run_as) || # global property across multiple capistrano gems
|
22
22
|
role.user
|
23
23
|
end
|
@@ -53,11 +53,7 @@ module Capistrano
|
|
53
53
|
File.expand_path("../templates/#{from}.rb.erb", __FILE__)
|
54
54
|
].detect { |path| File.file?(path) }
|
55
55
|
erb = File.read(file)
|
56
|
-
|
57
|
-
StringIO.new(ERB.new(erb, nil, '-').result(binding))
|
58
|
-
else
|
59
|
-
StringIO.new(ERB.new(erb, trim_mode: '-').result(binding))
|
60
|
-
end
|
56
|
+
StringIO.new(ERB.new(erb, trim_mode: '-').result(binding))
|
61
57
|
end
|
62
58
|
|
63
59
|
def template_puma(from, to, role)
|
@@ -102,6 +98,10 @@ module Capistrano
|
|
102
98
|
PumaBind.new(m, etype.to_sym, address)
|
103
99
|
end
|
104
100
|
end
|
101
|
+
|
102
|
+
def expanded_bundle_command
|
103
|
+
backend.capture(:echo, SSHKit.config.command_map[:bundle]).strip
|
104
|
+
end
|
105
105
|
end
|
106
106
|
|
107
107
|
class Puma < Capistrano::Plugin
|
@@ -109,9 +109,10 @@ module Capistrano
|
|
109
109
|
|
110
110
|
def set_defaults
|
111
111
|
set_if_empty :puma_role, :web
|
112
|
-
set_if_empty :puma_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
112
|
+
set_if_empty :puma_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:rake_env, fetch(:stage)))) }
|
113
|
+
set_if_empty :puma_bind, -> { "unix://#{File.join(shared_path, 'tmp', 'sockets', 'puma.sock')}" }
|
113
114
|
set_if_empty :puma_access_log, -> { File.join(shared_path, 'log', "puma.log") }
|
114
|
-
set_if_empty :puma_error_log, -> { File.join(shared_path, 'log', "
|
115
|
+
set_if_empty :puma_error_log, -> { File.join(shared_path, 'log', "puma_error.log") }
|
115
116
|
|
116
117
|
# Chruby, Rbenv and RVM integration
|
117
118
|
append :chruby_map_bins, 'puma', 'pumactl' if fetch(:chruby_map_bins)
|
@@ -16,10 +16,16 @@ After=syslog.target network.target
|
|
16
16
|
|
17
17
|
[Service]
|
18
18
|
Type=<%= service_unit_type %>
|
19
|
-
|
19
|
+
<% if fetch(:puma_systemd_watchdog_sec) && fetch(:puma_systemd_watchdog_sec) > 0 %>
|
20
|
+
WatchdogSec=<%= fetch(:puma_systemd_watchdog_sec) %>
|
21
|
+
<% end %>
|
20
22
|
<%="User=#{puma_user(@role)}" if fetch(:puma_systemctl_user) == :system %>
|
21
23
|
WorkingDirectory=<%= current_path %>
|
24
|
+
<% if fetch(:puma_use_login_shell) %>
|
25
|
+
ExecStart=/bin/bash -lc '<%= expanded_bundle_command %> exec puma -e <%= fetch(:puma_env) %>'
|
26
|
+
<% else %>
|
22
27
|
ExecStart=<%= expanded_bundle_command %> exec puma -e <%= fetch(:puma_env) %>
|
28
|
+
<% end %>
|
23
29
|
ExecReload=/bin/kill -USR1 $MAINPID
|
24
30
|
<%- Array(fetch(:puma_service_unit_env_files)).each do |file| %>
|
25
31
|
<%="EnvironmentFile=#{file}" -%>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano3-puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abdelkader Boudih
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: capistrano
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '0'
|
100
100
|
requirements: []
|
101
|
-
rubygems_version: 3.6.
|
101
|
+
rubygems_version: 3.6.7
|
102
102
|
specification_version: 4
|
103
103
|
summary: Puma integration for Capistrano
|
104
104
|
test_files: []
|