I have a rails5 app and using puma as it's web service. It's all right when to deploy it in a normal environment but failed when to deploy it in docker with daemon mode. I'll list what I can do and what I cannot do as below:
Can:
rails s
without docker
puma
without docker
puma --daemon
without docker
puma -C config/puma.rb
without docker # in which set daemon: true
puma
in docker
Can't:
`puma --daemon' in docker
puma -C config/puma.rb
in docker in which set daemon: true
The conclusion is that I can't run puma in docker with daemon mode, and when I use docker-compose up
command it returns:
Puma starting in single mode...
- Version 3.8.2 (ruby 2.4.0-p0), codename: Sassy Salamander
- Min threads: 5, max threads: 5
- Environment: production
- Daemonizing...
- website_1 exited with code 0
No any other informations.
So, what does it really happen?
Docker containers run a single process. When that process completes, the container exits. Knowing this, let's take a look at what puma --daemon
option does.
The help output for Puma says:
-d, --daemon Daemonize the server into the background
When you do this, Puma is forking itself into the background. The parent process at this point is done and exits. This is the actual process that Docker knows about. Since this process is done and exits, the container exits.
To run Puma in a container you need to run in the foreground without the daemon option.
Edit: I found a good explanation of how the Process.daemon
method works in Ruby (which Puma is using at https://github.com/puma/puma/blob/f5f23aaac7aaccff1b6b138d93dd4b1755ebf1c2/lib/puma/daemon_ext.rb) in https://www.jstorimer.com/blogs/workingwithcode/7766093-daemon-processes-in-ruby.