Search code examples
ruby-on-railsdockerdocker-composedaemonpuma

Can't run puma in daemon mode in docker


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?


Solution

  • 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.