Browse Source

Better Puma configuration + documentation for systemd unit

rails6
Jérémy Lecour 11 months ago
parent
commit
404f9df820
4 changed files with 85 additions and 27 deletions
  1. +24
    -4
      INSTALL.md
  2. +4
    -0
      config/deploy.rb
  3. +21
    -0
      config/deploy/puma-chexpire@.service
  4. +36
    -23
      config/puma.rb

+ 24
- 4
INSTALL.md View File

@@ -11,7 +11,7 @@ We are usually running Chexpire on typical POSIX servers like :
- Linux Debian 9, Ruby 2.5.4, NodeJS 8.11 and MariaDB 10.1
- macOS High Sierra, Ruby 2.5.4, NodeJS 10.2.1 and MariaDB 10.2

It probably works on any system that supports Ruby >2.3, NodeJS >6 and MySQL >5.5. Feel free to report any unexpected incompatibilities.
It probably works on any system that supports Ruby >= 2.5.4, NodeJS >= 6 and MySQL >= 5.5. Feel free to report any unexpected incompatibilities.

If you use rbenv, chruby or RVM, you can set your prefered Ruby version in the `.ruby-version` file at the root of the project.

@@ -34,7 +34,7 @@ If you want to do manual installations, you can use our Wiki documentations for

Execute `# bundle install` to install Ruby gems (including Rails itself).

Execute `# yarn install` to install Javascript/NodeJS packages.
Execute `# yarn install --check-files` to install Javascript/NodeJS packages.

Depending on what is already installed on your OS or not, you might need to install a few system packages to be able to have everything working.

@@ -45,15 +45,21 @@ To use elliptic curve SSH keys, we need to have `libsodium` and its headers.
* on macOS with Homebrew : `# brew install libsodium`.


## Rails configuration
## Application configuration

After cloning this repository, you have to create and edit a few files for your local development/test configuration. Theses files will be ignored by git.

### Environment variables

A handful of settings can be set by environment variables. If you use Heroku-like platforms they offer a simple way to set them.

If you use Rbenv, there is the `rbenv-vars` plugin. That is what we recommend on POSIX servers. You have to put an `.rbenv-vars` file at the root of the project. If you use Capistrano, put it in the shared directory and have it linked in the `current` directory at deploy time.

### Database configuration

Create the file if missing : `cp config/database.example.yml config/database.yml`. If you change the settings in the `defaults` section it applies to the `development` and `test` sections. More information is available at "guides.rubyonrails.org":https://guides.rubyonrails.org/configuring.html#configuring-a-database

Note that on Debian 9 with MariaDB, the database socket is at `/var/run/mysqld/mysqld.sock`, which is not the default in the configuration file.
Note that on Debian 9+ with MariaDB, the database socket is at `/var/run/mysqld/mysqld.sock`, which is not the default in the configuration file.

### Rails secrets

@@ -113,3 +119,17 @@ You can use the `script/to_staging` and/or `script/to_production` scripts.
* with `to_production` you deploy the `master` branch to production.

On the remote servers – where the application will be deployed – you have to copy the configuration files just as you've just did for your development setup. The files has to go in the `shared/config/` directory, relative to your `deploy_to` path. They will be symlinked to the proper destination by Capistrano.
If an `.rbenv-vars` file is found in the shared directory, it will be linked to help loading environment files (by Ruby via Rbenv, systemd…).

### systemd

If you want to use systemd to manage your Puma process, there are [a few different ways](https://github.com/puma/puma/blob/master/docs/systemd.md). We've prepared a systemd unit file (`config/deploy/puma-chexpire@.service`) but you can adjust to better suit your needs.

If you deploy your application to `/home/chexpire_<environment>`, the systemd unit can be used as a template, for example : `puma-chexpire@production.service`. This template is compatible with systemd actions like `systemctl stop puma-chexpire@production.service` and also with Capistrano tasks like `cap production puma:stop`.

To install the systemd unit :

```
$ cp config/deploy/puma-chexpire@.service /etc/systemd/system/puma-chexpire@.service
$ systemctl enable puma-chexpire@<environment>.service
```

+ 4
- 0
config/deploy.rb View File

@@ -24,12 +24,16 @@ set :repo_url, "https://github.com/Evolix/chexpire.git"

# Default value for :linked_files is []
append :linked_files,
".rbenv-vars",
"config/chexpire.yml",
"config/database.yml",
"config/secrets.yml"

# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
append :linked_dirs,
"tmp/pids",
"tmp/sockets"

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }


+ 21
- 0
config/deploy/puma-chexpire@.service View File

@@ -0,0 +1,21 @@
[Unit]
Description=Puma Server for Chexpire (%i)
After=network.target

[Service]
Type=forking
User=chexpire_%i
EnvironmentFile=/home/chexpire_%i/www/current/.rbenv-vars
Environment=RAILS_ENV=%i
WorkingDirectory=/home/chexpire_%i/www/current/
PIDFile=/home/chexpire_%i/www/shared/tmp/pids/puma.pid

ExecStart=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec puma -C /home/chexpire_%i/www/current/config/puma.rb --daemon
ExecStop=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec pumactl -F /home/chexpire_%i/www/current/config/puma.rb stop
ExecReload=/home/chexpire_%i/.rbenv/bin/rbenv exec bundle exec pumactl -F /home/chexpire_%i/www/current/config/puma.rb phased-restart

Restart=no
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

+ 36
- 23
config/puma.rb View File

@@ -8,31 +8,44 @@ max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
rails_env = ENV.fetch("RAILS_ENV") { "development" }
environment rails_env

# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
app_dir = File.expand_path("../..", __FILE__)
directory app_dir
shared_dir = "#{app_dir}/tmp"

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
if %w[production staging].member?(rails_env)
# Logging
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"

# Change to match your CPU core count
workers ENV.fetch("WEB_CONCURRENCY") { 2 }

preload_app!

# Set up socket location and port
bind "unix://#{shared_dir}/sockets/puma.sock"
port ENV.fetch("PORT") { 3000 }

before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
on_worker_boot do
ActiveSupport.on_load(:active_record) do
db_url = ENV.fetch('DATABASE_URL')
# puts "puma: connecting to DB at #{db_url}"
ActiveRecord::Base.establish_connection(db_url)
end
end
elsif rails_env == "development"
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT") { 3000 }
plugin :tmp_restart
end

Loading…
Cancel
Save