fly-apps/dockerfile-rails

`docker-compose.yml` for `postgresql` specifies a local volume that ends up being owned by `root` on the host

G-Rath opened this issue · 11 comments

G-Rath commented

Disclaimer: I'm not a docker superuser, especially when it comes to managing permissions and users between the host and containers, so it's very possible I'm doing something wrong.

Doing a standard generation with --compose --postgresql seems to generate a docker-compose.yml that specifies a volume mapping of ./tmp/db:/var/lib/postgresql/data; the resulting tmp/db directory is owned by root on the host system which is problematic - this caught me out specifically because when I attempted to do docker build . it would fail since it wasn't allowed to read that file.

I suspect this is probably not a direct bug in the gem itself, but it's the sort of thing I feel this gem should be trying to help with.

(I assume this probably happened with all variations that configure volumes, but have only used postgresql myself)

rubys commented

When I run demo 3 from https://github.com/rubys/dockerfile-rails/blob/main/DEMO.md on a Mac, I'm not seeing that. I'm only seeing files owned by me. Can you try that demo?

% ls -ld tmp/db
drwx------@ 26 rubys  staff  832 Apr  8 07:09 tmp/db
G-Rath commented

Running that demo on Ubuntu 20.04 via WSLv2 + Docker for Windows gives me a folder owned by root:

demo on  main [?] via 💎 v3.1.2
❯ ll tmp
total 28
drwxr-xr-x  6 gareth gareth 4096 Apr  9 05:33 ./
drwxr-xr-x 14 gareth gareth 4096 Apr  9 05:32 ../
-rw-r--r--  1 gareth gareth    0 Apr  9 05:31 .keep
drwxr-xr-x  4 gareth gareth 4096 Apr  9 05:32 cache/
drwx------ 19    999 root   4096 Apr  9 05:34 db/
-rw-r--r--  1 gareth gareth  128 Apr  9 05:32 development_secret.txt
drwxr-xr-x  2 gareth gareth 4096 Apr  9 05:31 pids/
drwxr-xr-x  2 gareth gareth 4096 Apr  9 05:31 storage/

Versions:

image

rubys commented

I've reproduced the problem. this post suggests a workaround. I'm traveling this week so it may be a few days before I am able to fully test a few.

rubys commented

dockremap also looks promising

G-Rath commented

hmm both of those sound like they could be pretty finicky, though probably worth at least documenting for advanced users.

I'm not sure if we need a local named volume (that's probably the wrong name) for db containers at least though?

On other projects I think I've not had this problem because we're doing something like:

services:
    mysql:
        image: 'mariadb:10.4'
        ports:
            - '3306:3306'
        environment:
            MYSQL_ROOT_PASSWORD: drupal
            MYSQL_DATABASE: drupal
        volumes:
            - 'mysql_data:/var/lib/mysql'
            - "./data/:/docker-entrypoint-initdb.d/"
volumes:
    mysql_data:

I wouldn't be surprised if the actual directories on disk is still owned by root, but it's out of sight in a way that doesn't (seem) to impact our builds.

I also find it interesting that building with docker compose doesn't have this issue.

rubys commented

If volumes are better, then I'm fine with switching to volumes. If the answer is "it depends", I'm fine with it being an option.

It seems to me that with volumes, either a name prefix or a mapping would make sense to avoid to separate applications from attempting to use the same volume?

G-Rath commented

I think named volumes are what I've experienced more often, and I guess unless/until someone else gives some counter points it's probably best to just go with them for now 🤔

to avoid to separate applications from attempting to use the same volume

I don't think that's the problem here - that is something that stuck out to me in the links you gave: they seem to be about applications sharing volumes which I don't think is the case here, but I think the underlying problem is about the same - because the volume data is being owned by root on the host, anything trying to access that data who isn't root gets an error so it impacts both when you try to build an image and when you try to share a volume with two applications.

rubys commented

I don't think that's the problem here

My apologies. I was unclear. What happens if you generate a docker compose file for one app, and later generate a docker compose file for a separate app. Will they interfere with each other if they both use the same type of database?

G-Rath commented

Assuming you don't mean in the same app directory / docker-compose.yml file, no there isn't any issue - my understanding is that is what docker compose is managing for you (i.e. most stuff ends up being namespaced with the service name) so you should be safe to assume there won't be any issues unless you start referencing paths outside of the root directory the docker-compose file is in (and in the case of named volumes where you don't set a path, it's handled by docker compose)

rubys commented

Would you consider making a pull request?

The tmplate can be found here: https://github.com/rubys/dockerfile-rails/blob/main/lib/generators/templates/docker-compose.yml.erb

Running rake test:capture will update the expected test results to match your changes. Run git diff to visual inspect the changes.

Commit and push the changed templates and test results together.

G-Rath commented

Yup, I'll do that when I next have some free time :)

(I've got a few other things I'll probably open issues and PRs for, but am waiting until I've properly finished things off so I can be sure what I'm saying is right etc)