seuros / capistrano-puma

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

Permission denied with puma_access.log #350

Closed jeff-free closed 2 years ago

jeff-free commented 2 years ago

Hi guys, thanks for the awesome gem! Recently I tried to deploy my new app but the systemd cannot execute as expected. After running the ExecStart script manually:

ExecStart=/home/ubuntu/.rbenv/bin/rbenv exec bundle exec --keep-file-descriptors puma -C /var/www/app/shared/puma.rb

The following error raised:

bundler: failed to load command: puma (/var/www/app/shared/bundle/ruby/3.1.0/bin/puma)
/var/www/app/shared/bundle/ruby/3.1.0/gems/puma-5.6.5/lib/puma/runner.rb:124:in `reopen': Permission denied @ rb_io_reopen - /var/www/app/shared/log/puma_access.log (Errno::EACCES)

Here's my log dir:

drwxrwxr-x 2 ubuntu   ubuntu    4096 Oct 21 13:23 ./
drwxrwxr-x 9 ubuntu   ubuntu    4096 Oct 21 10:14 ../
-rw-rw-r-- 1 ubuntu   ubuntu     896 Oct 21 13:03 production.log
-rw-r--r-- 1 root     root    128454 Oct 21 15:02 puma_access.log
-rw-r--r-- 1 root     root   1266054 Oct 21 15:02 puma_error.log

I could fix the issue by changing the permission of puma_access.log and puma_error.log to something like 777, but I wonder if this relates to the gem. Thanks in advance!

basicdays commented 2 years ago

Just ran into this as well. I'm guessing the systemd service unit file is redirecting stdout/stderr to puma_access.log and puma_error.log and setting the owner of those files as root. Haven't gotten further than that yet...

basicdays commented 2 years ago

In my quick debugging, couldn't find a way to have systemd create the stdout/stderr files as a particular user. I found that if I created those files beforehand as the correct user, then systemd will retain that ownership when logging to those files. The deploy task here should probably create those files itself before starting the service. I think that would resolve this issue, unless there's a more elegant way to have systemd create log files as the correct user.

seuros commented 2 years ago

@basicdays @basicdays

Can you try the latest version before the final release #349.

I really hope to fix all the issues before releasing the final version.

jeff-free commented 2 years ago

I'll give it a try, thanks @seuros!

jeff-free commented 2 years ago

Hi @seuros, I upgraded to the version of 6.0.0.beta.1, then did the following steps:

# Disable and remove the service unit generated by version 5.2.0 on remote server
systemctl disable puma_app_production.service 
rm etc/systemd/system/puma_app_production.service

# Install puma with command on my local env:
cap production puma:install

and got the following error:

○ app_puma_production.service - Puma HTTP Server for app (production)
     Loaded: loaded (/home/ubuntu/.config/systemd/user/app_puma_production.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
TriggeredBy: ○ app_puma_production.socket

Below is the directory of ~/.config/systemd/user

drwxr-xr-x 2 ubuntu ubuntu 4096 Oct 24 04:16 default.target.wants/
-rw-r----- 1 ubuntu ubuntu 1086 Oct 24 04:16 app_puma_production.service
-rw-r----- 1 ubuntu ubuntu  470 Oct 24 04:16 app_puma_production.socket
drwxr-xr-x 2 ubuntu ubuntu 4096 Oct 24 04:16 sockets.target.wants/

Is there anything I've missed? Thank you!

seuros commented 2 years ago

@jeff-free thank you for your help.

I will try the socket activation , asap. (this part is untested)

did you create config/puma or config/puma/production.rb ? can you share your configuration related to puma here ?

Do you mind using the non-socket version for now ?

jeff-free commented 2 years ago

Hi @seuros I use the default puma configuration without any change at config/puma.rb:

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

worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"

port ENV.fetch("PORT") { 3000 }

environment ENV.fetch("RAILS_ENV") { "development" }

pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }

plugin :tmp_restart

Please let me know if you need further information, thank you!

seuros commented 2 years ago

Did you compare your capistrano configuration with the sample app i provided ?

Do you have the output of the failed service ?

jeff-free commented 2 years ago

@seuros

I did compare the capistrano configuration with your sample app, which looks similar. Here's what I have: Capfile:

require "capistrano/setup"

require "capistrano/deploy"

require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

require "capistrano/rbenv"
require "capistrano/bundler"

require "capistrano/rails/migrations"
require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Systemd

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

deploy.rb:

# config valid for current version and patch releases of Capistrano
lock "~> 3.17.1"

set :application, "app"
set :repo_url, "git@github.com:app/app.git"

set :branch, ENV['BRANCH'] || 'main'

set :deploy_to, "/var/www/app"

append :linked_files, "config/database.yml", 'config/master.key'

append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "tmp/webpacker", "public/system", "vendor", "storage"

# rbenv
set :rbenv_type, :user
set :rbenv_ruby, '3.1.2'
set :rbenv_prefix, '/usr/bin/rbenv exec'
# set :rbenv_prefix, "#{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}

# Puma
set :puma_enable_socket_service, true

Here's the output from cap production puma:status:

SSHKit::Command::Failed: /bin/systemctl exit status: 3
/bin/systemctl stdout: ○ app_puma_production.service - Puma HTTP Server for app (production)
     Loaded: loaded (/home/ubuntu/.config/systemd/user/app_puma_production.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
TriggeredBy: ○ app_puma_production.socket
/bin/systemctl stderr: Nothing written
seuros commented 2 years ago

any output from the journalctl (you have to ssh into one of the server)

I suspect it failing to run the command .

you can also send me an email (to connect via slack or telegram), i can assist you in this upgrade so we can write good upgrade documentation.

jeff-free commented 2 years ago

For using 6.0.0.beta.1, the following step fixed my problem:

In ~/.config/systemd/user/app_puma.service, comment out the socket requirement:

# Requires=app_puma_production.socket