How to exit “docker run” containers once the scrip

2019-07-14 05:57发布

I have a docker-compose setup, which is deployed in three steps:

  1. Build all the containers and dc up -d (dc is an alias for docker-compose)
  2. Create database with: dc run web /usr/local/bin/python create_db.py
  3. Populate database with: dc run -d web /usr/local/bin/python -u manage.py populateDB

Steps 2 and 3 create new containers (see the first two):

~/Documents/Project » docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                              PORTS                    NAMES
2ead532ea58b        myproject_web       "/usr/local/bin/pytho"   8 minutes ago       Up 8 minutes                        8000/tcp                 myproject_web_run_2
64e1f81ecd1a        myproject_web       "/usr/local/bin/pytho"   9 minutes ago       Restarting (0) About a minute ago   8000/tcp                 myproject_web_run_1
9f5c670d4d7f        myproject_nginx     "/usr/sbin/nginx"        40 minutes ago      Up 40 minutes                       0.0.0.0:80->80/tcp       myproject_nginx_1
46d3e8c09c03        myproject_web       "/usr/local/bin/gunic"   40 minutes ago      Up 40 minutes                       8000/tcp                 myproject_web_1
ea876e68c8c6        postgres:latest     "/docker-entrypoint.s"   40 minutes ago      Up 40 minutes                       0.0.0.0:5432->5432/tcp   myproject_postgres_1

Which is all well and good, except they don't exit when their job is finished.

For example, the create db script, as you can see, is always restarting after it has created the database. Once achromap_web_run_2 has finished populating the database, it will add a second copy of each record, then a third, etc.. forever.

On github, it seems like this was asked for from docker, and the docker run --rm flag handles it. But --rm and -d are incompatible, which I don't understand.

Do you know how to kill containers which have finished executing their functions? Specifically, how to get dc run web /usr/local/bin/python create_db.py to exit once create_db.py calls exit()? Or is there a better way?

1条回答
贼婆χ
2楼-- · 2019-07-14 06:33

I think you may be conflating two things here.

The --rm flag

This exists to clean up after a container is finished, so it doesn't hang around in the dead containers pool. As you already found, it is not compatible with -d. But in this case, you don't need it anyway.

The --restart flag

(Also available in docker-compose as the restart property.)

This flag sets the restart policy. By default it is set to no, but you can set it to a few other values, including always. I would suspect you have it set to always currently, which would force the container to restart every time it stops on its own.

If you manually stop the container (docker stop ...) then the auto-restart would not engage. But if the process exits on its own, or crashes, then the container will be restarted. This is available for the obvious reason, so your service will start up again if it crashes.

How to proceed

I would say what you need is to use exec instead of run for these tasks.

First, run your container normally (i.e. docker-compose up -d).

Instead of using run to execute create_db.py, use exec.

docker-compose exec web /usr/local/bin/python create_db.py

This will use your already-running container, execute the script one time, and when the script exits, you're done. Since you did not create a new container (like run was doing), there is no cleanup to do afterward.

Note that you do not need the -it flag that is often used with docker exec. docker-compose emulates a tty on exec by default.

查看更多
登录 后发表回答