jshimko / meteor-launchpad

A base Docker image for Meteor applications.
https://hub.docker.com/r/jshimko/meteor-launchpad/
MIT License
276 stars 152 forks source link

How to bind a volume to internally installed mongodb's data path #36

Closed rsercano closed 7 years ago

rsercano commented 7 years ago

Hello,

I'm trying to bind an external volume to keep my settings persistent (as expected) so I'm trying to run docker with argument: -v /home/sercan/mongoclient_data2/:/data/db

But it fails to run, that's probably you've changed how to install mongodb and now it's being started as mongodb user. Is there a workaround to run docker with this argument ?

Thanks in advance.

jshimko commented 7 years ago

It'd be helpful if you can share the exact commands and output.

Also, are you saying it used to work and now it doesn't after the update?

rsercano commented 7 years ago

Yes exactly, @jshimko after this root fixes it stopped working. (I'm using partially forked of your implementation and doing a local build because of #19 )

This's the full command: docker run -d -p 3000:3000 -v /home/sercan/mongoclient_data/:/data/db mongoclient/mongoclient

Since you're assigning /data/db directory to mongodb user at inside of container, I guess it causes this issue. And I've found this that I thought it can be related, but couldn't actually be sure since I'm not an expert on docker.

jshimko commented 7 years ago

Hmm. According to that second link, you should be able to chown the volume at runtime from inside the container. So presumably you could add it in the entrypoint script that starts Mongo.

So, right above this line...

https://github.com/jshimko/meteor-launchpad/blob/master/scripts/entrypoint.sh#L9

Add this...

chown -R mongodb:mongodb /data/{db,configdb}

(then obviously rebuild the image with ./build.sh)

Let me know if that fixes it and I'll get it added in.

rsercano commented 7 years ago

Sorry but no chance:


[-] External MONGO_URL not found. Starting local MongoDB...

[-] External MONGO_URL not found. Starting local MongoDB...

chown: changing ownership of '/data/db': Operation not permitted
chown: changing ownership of '/data/configdb': Operation not permitted

By the way here's the branch that I'm trying to fix this issue, and here's the docker file it would be appreciated if you have a chance to look at these to ensure problem is not about my structure,

p.s. this changed my directory's users:

drwxrwxr-x 2 syslog crontab 4,0K Mar 17 15:14 mongoclient_data2

jshimko commented 7 years ago

Well, that seems strange. The official mongo image does exactly that in the same spot.

https://github.com/docker-library/mongo/blob/4a81205a13fefc418355248f750551e4f7c62361/3.4/docker-entrypoint.sh#L12

And I know you can expose the volume with the official image, so I'm not sure what's different. Do you already have existing data there? (outside of the container). That may be why. If so, try using an empty host directory and see if that lets you do it.

rsercano commented 7 years ago

Yeah, I thought the same way end cleared directory but didn't work either, sorry for causing more trouble.

Actually I've re-created directory:


sercan@aytws08:~$ pwd
/home/sercan
sercan@aytws08:~$ rm -rf mongoclient_data2/
sercan@aytws08:~$ mkdir mongoclient_data2/
sercan@aytws08:~$ docker run -d -p 5000:3000 -v /home/sercan/mongoclient_data2/:/data/db mongoclient-local
1efdac2f6d9693259932332cfe0eec70659c44c195c4df6661b1f2db198fee3f
sercan@aytws08:~$ docker logs 1efdac2f6d9693259932332cfe0eec70659c44c195c4df6661b1f2db198fee3f

[-] External MONGO_URL not found. Starting local MongoDB...

[-] External MONGO_URL not found. Starting local MongoDB...

chown: changing ownership of '/data/db': Operation not permitted
chown: changing ownership of '/data/configdb': Operation not permitted
jshimko commented 7 years ago

For what it's worth, you could just use the official Mongo image with Docker Compose. That obviously doesn't fix this image, but it's generally a better practice to use separate containers anyway. That way you can update them individually.

# docker-compose.yml

app:
  image: yourname/app
  ports:
    - "80:3000"
  links:
    - mongo
  environment:
    - ROOT_URL=http://example.com
    - MONGO_URL=mongodb://mongo:27017/meteor

mongo:
  image: mongo:latest --storageEngine=wiredTiger
  volumes:
    - /path/on/host:/data/db

Then...

docker-compose up -d
jshimko commented 7 years ago

That also allows you to keep all of your config in a file and run a really simple command to start everything (instead of a long docker run command).

rsercano commented 7 years ago

I'll try this asap, thanks, I assume I need to disable installing mongodb inside of container ?

rsercano commented 7 years ago

By the way, I'm using an automated build on docker hub, will this be sufficient for all docker people ?

jshimko commented 7 years ago

I don't see why not. Assuming it finishes successfully, a build there should be the same as a build from anywhere else.

rsercano commented 7 years ago

I guess I solved it (without compose), changing owner of data path to node recursively and during installation of mongodb, doing same thing resolved it, now I'm able to use another volume.

#install-mongo.sh
  chown -R node:node /data/{db,configdb}
#entrypoint.sh
  chown -R node:node /data/{db,configdb}

 if hash mongod 2>/dev/null; then
    printf "\n[-] External MONGO_URL not found. Starting local MongoDB...\n\n"
    chown -R node:node /data
    exec gosu node mongod --storageEngine=wiredTiger > /dev/null 2>&1 &
  else
rsercano commented 7 years ago

But I'm still unable to run my image with user --user node and still it's running as root :(

jshimko commented 7 years ago

Ah. You didn't mention that you were trying to run with the --user flag. That shouldn't be necessary. The app is already run by the node user. And using that flag is going to be a problem when you're running two processes in the same container with two different users (which is one of the many reasons you're supposed to do one process per container with Docker).

I don't think I can remove the Mongo option at this point, but I do think you should always use an external Mongo container in production. It's a best practice for good reasons. I originally only included Mongo as an optional install in this image because some people like having a quick/easy way to run mongo in development without having to deal with multiple containers. It's really not a great idea to run everything in one place in production though.

jshimko commented 7 years ago

Just so you know, that's the entire point of gosu. You can run the container as root and gosu steps down the app processes to whatever non-root user you want. So you have all of the flexibility of running as root, but the security of running the app processes as non-root.

rsercano commented 7 years ago

Thank you so much for your great support, actually I totally agree with you to keep everything separated for production use, but since mongoclient is a product, and more probably people don't want to be bothered for such an extra step while installing it.

I now changed it a bit and did mongodb installation via using curl for the tarball. You can check here. With this altitude I'm now able to use USER node in main Dockerfile

I was actually trying to do an openshift deployment but I failed anyway, and gave up. But at least now have a proper docker setup :)

Thanks again.