1

I have a problem. I have build an application in rails using docker. This application consists of 4 containers:

  • Rails app
  • Postgres DB
  • Redis
  • Sidekiq (Clone of rails app)

Now I want to reset my db in my rails app, but when I run:

docker-compose exec app rails db:migrate:reset

I get:

ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR:  database "my_app_development" is being accessed by other users
DETAIL:  There are 4 other sessions using the database.

I saw this fix from someone, but this code results in:

kill: you need to specify whom to kill

I think because this is task will be executed in one container and it only looks for process within that container and not the other docker containers. My question is how I can reset my db without the other docker images to crash or anything, but temporary stop the database connections for them. I really need to be able to reset my database when I have to!

Please let me know!

A. Vreeswijk
  • 822
  • 1
  • 19
  • 57

1 Answers1

0

If you just want to stop and reset everything, the easiest way is to ask Compose to stop all of the containers and delete all of the state

docker-compose down -v

then recreate the database

docker-compose run app rake db:create

and finally restart the application

docker-compose up -d

You might also be able to do this by stopping the application containers, running the reset command, and then restarting things

docker-compose stop app sidekiq
docker-compose run app rails db:migrate:reset
docker-compose up -d

One notable thing here is that I'm using docker-compose run and not exec. This launches a new temporary container based on the app service, but overrides its command: with whatever you provide on the command line and doesn't publish ports:. In particular your error suggests that you can't run this command while the main rails server is running; but if you stop it then there's not a running container you can docker exec into. Starting a new container with docker-compose run gets around this problem; since it has the same network setup, image, and entrypoint wrapper as the main service, it should be able to run the same rails and rake commands.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • I added `depends_on` to the rails app and added the other 3 containers. Does that conflict with this answer? – A. Vreeswijk Dec 25 '22 at 19:06
  • In my docker-compose.yml – A. Vreeswijk Dec 25 '22 at 20:08
  • The error message you quote implies to me that you can't run this particular command while any of the Ruby containers are still running. A `depends_on:` declaration will help bring up smaller parts of the stack but doesn't affect the details of this answer at all. – David Maze Dec 26 '22 at 12:25
  • Well, stopping sidekiq when it uses a `depends_on` closes the depending containers as well if I am correct? – A. Vreeswijk Dec 26 '22 at 19:34
  • I don't think that happens. If both `app` and `sidekiq` declare `depends_on: [redis]` then in principle you couldn't stop `redis` until both depending containers are stopped, and I don't think Compose usually checks that. – David Maze Dec 27 '22 at 11:25
  • To get what I want I use the `wait-for-it.sh` script for both containers and then wait for `db` and `redis`. I am still not sure about the depends_on... I feel it brings more disadvantages, when running a bigger network – A. Vreeswijk Dec 28 '22 at 01:21
  • `depends_on:` essentially does two things: if you `docker-compose up app` it ensures the database is started as well, and it mostly ensures the dependencies' DNS names will resolve (but not that the dependencies are actually running). It's a little secondary to the question you're asking here. – David Maze Dec 28 '22 at 12:04