Compose: When closing a container with a rails app, rails doesn't delete /tmp/pids/server.pid

Created on 6 May 2015  路  12Comments  路  Source: docker/compose

This prevents the server from starting up the next time I call sudo docker-compose up

kinquestion

Most helpful comment

Workaround (replace bundle exec rails ... with however you start your server):

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

All 12 comments

Workaround (replace bundle exec rails ... with however you start your server):

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

This doesn't sound as a bug in Docker Compose, and something that should be handled by the image/container that is used.

See for example, the script that is used in the official Apache image; https://github.com/docker-library/httpd/blob/7ef8528047b6d344b32009572b9b61285c30e73a/2.4/httpd-foreground#L5

You could add a similar script to your image and set that as the CMD, that way, you don't have to include the removal as part of your command: ..., which is less "hacky"

This actually relates to a couple different issues I've been trying to tackle recently:

  1. Removing server.pid is technically a cleanup script, and should ideally be run when the container is shutting down. So the run script could still just be bundle exec rails s ..., unless there are other steps you need to start your server.
  2. We wouldn't need to do any cleanup if Rails didn't keep a tmp folder inside of its own codebase. It's standard to simply add this folder to .gitignore, but with docker-compose, if you mount your codebase as a Volume, there is no (easy) way to exclude folders within the volume. Ideally, tmp would be created and persist only as long as the docker container is running. And there is no easy way to tell Rails to use a different location within the container, outside of the volume.

Neither of these issues sound strictly like something docker-compose _needs_ to address, but they could be considered nice-to-haves. Or maybe there's already a really simple way to tackle either or both, and I just haven't come across it.

Kind of. Would something like that allow me to mount a ./tmp folder _within_ an existing volume, without having that folder show up in the matching folder on the host?

The problem with Rails is that it's not readily possible to change the location of ./tmp. You can't point it to the system /tmp, so mounting /tmp as tmpfs would do no good.

One really complex workaround I put together involves symlinking every file and folder _except_ ./tmp from a different path on the container, and then booting the Rails app from there. So it writes to its relative ./tmp and those changes don't persist in the volume, as desired. But the downside is that adding files to the root of the volume requires rebooting the container (not a huge downside, but it is non-obvious to anyone who doesn't realize what's happening inside the container -- Rails just doesn't pick up the new files).

I wonder if mounting another volume inside a volume works correctly here, yes.

Still, using an entrypoint script to cleanup looks like a sane solution here.

Agreed, the entrypoint script is much saner, especially if the cleanup is trivial.

As a followup to this. I was using Puma to serve up my rails application and used a config file to specify where the pid file and state file would live within my container. This meant that I could simple start puma within given config file and not require the cleanup.

It sounds like this issue is not directly related to compose, and workarounds have been suggested. I'm going to close this issue, but please do let me know if you feel there is something that still needs to be addressed, and we can re-open it.

Still needs to be addressed.

I came across this problem myself. Another approach, if you don't re-use your containers (e.g. if you use the '--rm' flag) is to specify -P /tmp/rails.pid in the startup command. This means you can run the same Rails app in multiple containers, and the pidfile gets automatically deleted with the container.

https://github.com/rails/rails/pull/36486

How about setting the PIDFILE to /dev/null? I just tried that and it seems to work fine:
rails server -b 0.0.0.0 -P /dev/null

Was this page helpful?
0 / 5 - 0 ratings