README.adoc in puma-daemon-0.1.0 vs README.adoc in puma-daemon-0.1.1
- old
+ new
@@ -1,30 +1,137 @@
= Puma::Daemon
+:toc:
+:toclevels: 4
+:sectnums:
+:icons: font
-Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/puma/daemon`. To experiment with that code, run `bin/console` for an interactive prompt.
+image:https://github.com/kigster/puma-daemon/workflows/Ruby/badge.svg[link=https://github.com/kigster/puma-daemon/actions?query=workflow%3ARuby] image:https://codecov.io/gh/kigster/puma-daemon/branch/master/graph/badge.svg?token=asxarMSGbz[link=https://codecov.io/gh/kigster/puma-daemon]
-TODO: Delete this and the text above, and describe your gem
+In version 5.0 of the popular Ruby HTTP server https://github.com/puma/puma[Puma] the developers chose to https://github.com/puma/puma/pull/2170/files[drop the daemonization] support from Puma. They did that because the code wasn't actively maintained. Other and perhaps better options now exist (such as `systemd`, etc), not to mention that many people have switched to Kubernetes and Docker, where you generally want to start all servers in the foreground.
+And yet, on occasion, it was rather useful and straightforward to use the built-in daemonization feature that was cross-platform and is now gone. Some folks are still using this feature and are therefore stuck with Puma version 4, or must wrap Puma either in the `systemd` manifest or `launchctl plist` on Mac OS-X, or a Docker container. Well, **not anymore!**
+
+NOTE: Add this gem to your dependencies, and make a one line change either in your `config/puma.rb` file, or use `pumad` binary to start Puma as per usual, and you can even leave `-d` flags there (they are ignored when started via `pumad`, and Puma always goes to the background when started that way).
+
+One of the nice features of the old daemonization functionality was that it worked across all platforms.
+
+So, if you want to use the latest and greatest Puma 5+, but have it self-daemonize, this gem is for you.
+
+== Compatility
+
+We did not restore the daemonization code for JRuby; so at the moment this will work with the MRI distribution, and possibly others that support `Process.daemon(true)`.
+
+We currently run CI suite on Github Actions against
+
+ * MRI Ruby 3.0.0
+ * MRI Ruby 2.7.2
+ * MRI Ruby 2.6.6
+ * MRI Ruby 2.5.7
+
+
+== Design Decisions
+
+This gem's goal was to surgically augment Puma's source code to restore daemonization by merely requiring `puma/daemon`. We almost got there, but not quite.
+
+While this was an admirable goal, it has not been accomplished in the current version. The internals of Puma isn't very easy to monkey-patch or augment. For example, we couldn't think of a way to add back the `-d` flags to the Option Parsing method without having to override the entire method: — which is _not a good solution_, because — what if Puma developers add a new flag in the future? We would have to keep this overridden method frequently updated and potentially choose a different version depending on what version of Puma you are using. That sounds like a nightmare.
+
+It is why instead, we took an approach that requires you — the user — to make a couple of small changes in your Puma configuration to bring daemonization back, or in your scripts, change `puma` to `pumad`, and everything should work. If you run into problems, please https://github.com/kigster/puma-daemon/issues/new[submit an issue].
+
== Installation
Add this line to your application's Gemfile:
[source,ruby]
----
-gem 'puma-daemon'
+gem 'puma-daemon', require: false
+gem 'puma', '~> 5'
----
And then execute:
$ bundle install
-Or install it yourself as:
+== Usage
- $ gem install puma-daemon
+There were two ways you could daemonize Puma in the past:
-== Usage
+ 1. By specifying `daemonize` or `daemonize(true)` in your config file.
+ 2. Or, by passing a `-d` or `--daemonize` command line flag.
-Work in progress.
+This gem allows you to daemonize using both ways, but with a small caveat in each case.
+
+Please note that both ways require you to include this gem in your Gemfile, but you may specify it as `require: false` — it will only activate if you explicitly require it, or use `pumad` executable.
+
+=== Daemonizing via the Config File
+
+If you want to specify `daemonize` in your config file, simply include `require 'puma/daemon'` at the top of your config file:
+
+[source,ruby]
+----
+# file: config/puma.rb
+require 'puma/daemon'
+
+port 3001
+workers 3
+threads 2,3
+# accepts true or false, and if false is passed will NOT daemonize
+daemonize
+----
+
+With this method you can continue using the standard `puma` executable to get it started, but (and this is important) — **you must remove any `-d` or `--daemonize` from the command line**, or Puma v5 and above will fail with an error.
+
+Here is an example of daemonizing via the config file shown above, and using the regular `puma` binary:
+
+[source,bash]
+----
+❯ gem install puma-daemon puma -N
+❯ puma -C config/puma.rb config.ru
+
+[98795] Puma starting in cluster mode...
+[98795] * Puma version: 5.1.1 (ruby 2.7.2-p137) ("At Your Service")
+[98795] * Min threads: 2
+[98795] * Max threads: 3
+[98795] * Environment: production
+[98795] * Master PID: 98795
+[98795] * Workers: 3
+[98795] * Restarts: (✔) hot (✔) phased
+[98795] * Listening on http://0.0.0.0:3001
+[98795] * Puma Daemon: Daemonizing (puma-daemon v0.1.1)...
+----
+
+Note that using this method you can decide whether to daemonize or not by passing true or false to the `daemonize` method.
+
+=== Daemonizing on the Command Line
+
+If you prefer to make a decision whether to daemonize or not on the command line, you only have to make one chance: replace `puma` with `pumad`.
+
+NOTE: We did not want to conflict with the `puma` gem by introducing another executable under the same name. The executable this gem provides is called `pumad` (where 'd' stands for daemon, and follows standard UNIX convention, as in eg `sshd`, `ftpd`, etc).
+
+If you replace `puma` with `pumad` — you no longer need to pass any aditional command line flag t ocontinue passing it `-d` or you can remove it (both `-d` and `--daemonize` are stripped out before ARGV is passed onto Puma's CLI parser.)
+
+[source,bash]
+----
+❯ gem install puma --version 5.1.1 -N
+❯ gem install puma-daemon -N
+
+❯ pumad -C config/puma.rb spec/rackup/bind.ru
+
+[98795] Puma starting in cluster mode...
+[98795] * Puma version: 5.1.1 (ruby 2.7.2-p137) ("At Your Service")
+[98795] * Min threads: 2
+[98795] * Max threads: 8
+[98795] * Environment: production
+[98795] * Master PID: 98795
+[98795] * Workers: 3
+[98795] * Restarts: (✔) hot (✔) phased
+[98795] * Listening on http://0.0.0.0:3000
+[98795] * Puma Daemon: Daemonizing (puma-daemon v0.1.1)...
+----
+
+As you can see, at the end it says "Daemonizing".
+
+If you start puma this way, you can still specify `daemonize(false)` in the configuration file to turn it off, but the default is to daemonize. Also, if you start with `pumad` you do not need to include `require 'puma/daemon'` in your configuration file, as the `pumad` binary loads all dependencies prior to parsing the config.
+
== Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.