1

I know I am missing something very basic here. I have see some of the older questions on persisting data using docker, but I think I am following the most recent documentation found here. I have a rails app that I am trying to run in docker. It runs fine but every time I start it up i get ActiveRecord::NoDatabaseError. After I create the database and migrate it, the app runs fine, until I shut it down and restart it.

here is my docker file:

FROM ruby:2.3.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
ENV RAILS_ROOT /ourlatitude
RUN mkdir -p $RAILS_ROOT/tmp/pids
WORKDIR $RAILS_ROOT
COPY Gemfile Gemfile     
COPY Gemfile.lock Gemfile.lock
RUN gem install bundler     
RUN bundle install
COPY . .

and here is my docker-compose.yml file

version: '2'
services:
  db:
    image: postgres:9.4.5
  app:
    build: .
    environment:
      RAILS_ENV: $RAILS_ENV
  ports:
    - "3000:3000"
  command: bundle exec rails s -b 0.0.0.0
  volumes:
    - .:/ourlatitude/database
  depends_on:
    - db

the basic flow I am following is this:

export RAILS_ENV=development
docker-compose build
docker-compose up
docker-compose run app rake db:create
docker-compose run app rake db:migrate

at this point the app will be running fine

but then I do this

docker-compose down
docker-compose up

and then I am back to the ActiveRecord::NoDatabaseError

So as I said, I think I am missing something very basic.

nPn
  • 16,254
  • 9
  • 35
  • 58

2 Answers2

3

It doesn't look like you put your postgres on a volume, you may be missing other persistent data sources in your app container, and it appears you missed some indentation on your app container definition.

version: '2'
services:
  db:
    image: postgres:9.4.5
    volumes:
      - postgres-data:/var/lib/postgresql/data
  app:
    build: .
    environment:
      RAILS_ENV: $RAILS_ENV
    ports:
      - "3000:3000"
    command: bundle exec rails s -b 0.0.0.0
    volumes:
      - .:/ourlatitude/database
    depends_on:
      - db
volumes:
  postgres-data:
    driver: local

In the example above, the postgres data is stored in a named volume. See the advice on docker hub for more details on persisting data for that application. If you are still losing data, check the output of docker diff $container_id on a container to see what files are changing outside of your volumes that would be lost on a down/up.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • almost worked, but it also needs a volumes stanza with the name of the named volume. – nPn Jul 01 '16 at 21:13
  • maybe this wold have worked if I had created the volume manually? – nPn Jul 01 '16 at 21:17
  • Updated to include the volumes section, wasn't sure if you wanted that as a named volume or preferred to map it to your own host folder. – BMitch Jul 01 '16 at 21:21
  • interesting, I guess if I had created a folder under my current directory called postgres-data that would have worked? I am guessing the preferred way would be to use a named volume, right? – nPn Jul 01 '16 at 21:46
  • Named volumes have the advantage of hiding any uid mapping issues and you can use other drivers to locate your data elsewhere. Host volumes leave the data where it's easily accessed by developers without spinning up a management container. I selected a named volume because you were using `.` for the app and didn't want the DB to end up inside your app. It would be easier if you moved the app files into a separate sub folder. – BMitch Jul 02 '16 at 02:18
0

I managed to get this to work properly using the following docker-compose.yml file.

version: '2'
volumes:
  postgres-data:
services:
  db:
    image: postgres:9.4.5
    volumes:
      - postgres-data:/var/lib/postgresql/data
  app:
    build: .
    environment:
      RAILS_ENV: $RAILS_ENV
    ports:
      - "3000:3000"
    command: bundle exec rails s -b 0.0.0.0
    depends_on:
      - db

The key was to add the

volumes:
  postgres-data:

which creates the named volume and then the

volumes:
  - postgres-data:/var/lib/postgresql/data

under the db section which maps the named volume to the expected location in the container of /var/lib/postgresql/data

nPn
  • 16,254
  • 9
  • 35
  • 58