Script is being called once and being run multiple times!

Hey, I’ve been playing around with docker to get a grasp of several concepts and I’ve run into a snag. I’m trying to setup an application similar to one found on the real python blog. I will post links to both that and my source code (cant post them in OP due to limit on links).

For my proposes I would like to add initial data to the database. I looked around for a good way to do this but didn’t find much so I settled on using a simple python script to test out how to do that. This is simply a proof of concept script and I will be adding much more once I get the concept working.

#test.py

from app import db
from models import *

t = Post("Hello 3")
db.session.add(t)
db.session.commit()        

When I set up the environment via docker-compose I start everything fresh (by rm’ing all docker containters) to make sure that no data persists. My startup process can be seen here. When i view the app after this process instead of seeing the single entry of “Hello 3” I see several. I have tested this multiple times and seen differing amounts each time, and in no particular order. I’ve seen numbers of like entries ranging from 3-6. Example.

Does anybody know why this happens? If not is there a better way to add initial data to the app at startup?

thanks!

I’m following this blog post. My code can be found on github here.

My docker-compose.yml file:

 web:
      restart: always
      build: ./web
      expose:
        - "8000"
      links:
        - postgres:postgres
      volumes:
        - /usr/src/app/static
      env_file: .env
      command: /uscal/bin/gunicorn -w 2 -b :8000 app:app

nginx:
  restart: always
  build: ./nginx/
  ports:
    - "80:80"
  volumes:
    - /www/static
  volumes_from:
    - web
  links:
    - web:web

data:
  restart: always
  image: postgres:latest
  volumes:
    - /var/lib/postgresql
  command: "true"

postgres:
  restart: always
  image: postgres:latest
  volumes_from:
    - data
  ports:
    - "5432:5432"

Dockerfile for Web container:

FROM python:3.4-onbuild

Dockerfile for nginx container:

FROM tutum/nginx
RUN rm /etc/nginx/sites-enabled/default
ADD sites-enabled/ /etc/nginx/sites-enabled

docker-compose will remove the containers but preserve the volumes. Your postgres database container stores its data in a volume. This is a feature so that docker-compose can be used with a production environment.

As for a better way to add initial data at app startup, I would recommend making it idempotent. That way you don’t get duplicate initial data on subsequent runs.

Hopefully this helps

/Jeff

Thanks for the reply.

Before I start the app i rm all of my docker containers via docker stop and docker rm . Then i do docker-compose build & docker-compose up -d. I run the command to build the database. At this point if i open the site, there are no entries in the database. I then run my test script, and which then creates multiple entries of the same data after only one call. If i refresh the page, the number is increased by 1. Can you recreate this behaivor on your end by cloning the repo?

yup, I totally reproduced it

I did a handful of docker-compose run web /usr/local/bin/python test.py invocations, and this is what I found:

CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                              PORTS                    NAMES
59812c9cc68c        dockertesting_web     "/usr/local/bin/pytho"   4 minutes ago       Restarting (0) 44 seconds ago       8000/tcp                 dockertesting_web_run_4
8bae685fdfe8        dockertesting_web     "/usr/local/bin/pytho"   4 minutes ago       Restarting (0) About a minute ago   8000/tcp                 dockertesting_web_run_3
057205dad313        dockertesting_web     "/usr/local/bin/pytho"   5 minutes ago       Restarting (0) 2 minutes ago        8000/tcp                 dockertesting_web_run_2
65d0998b98c9        dockertesting_web     "/usr/local/bin/pytho"   6 minutes ago       Restarting (0) 2 minutes ago        8000/tcp                 dockertesting_web_run_1
b29ff777cb8c        dockertesting_nginx   "/usr/sbin/nginx"        22 minutes ago      Up 22 minutes                       0.0.0.0:80->80/tcp       dockertesting_nginx_1
c1f91a66f32c        dockertesting_web     "/usr/local/bin/gunic"   23 minutes ago      Up 23 minutes                       8000/tcp                 dockertesting_web_1
62dcde7a9142        postgres:latest       "/docker-entrypoint.s"   24 minutes ago      Up 24 minutes                       0.0.0.0:5432->5432/tcp   dockertesting_postgres_1
d8008012f156        postgres:latest       "/docker-entrypoint.s"   24 minutes ago      Restarting (0) 10 minutes ago       5432/tcp                 dockertesting_data_1

It looks like the restart: always is getting honored on the docker-compose run invocations. If I refresh the page, I see more and more instances over time while the containers restart.

I searched for an existing issue and found this: https://github.com/docker/compose/issues/1013

The PR fixes this problem in the case where you run the docker-compose run command with the --rm flag, but didn’t fix the base bad behavior. I’ve created another issue to address that: https://github.com/docker/compose/issues/1985

Feel free to subscribe there and add as much info there as you’d like.

/Jeff

I also found that if I just re-navigated to the page,instead of refreshing it, I didn’t see more instances being created. I don’t know if that was because I didn’t wait long enough for them to appear or if what ever is creating them, isn’t in that instance.

If you do a docker ps do you see your run instances listed in the Restarting status?

Yes I do. I also confirmed that reloading the page isn’t actually adding things to the database (unless you add one manually), but it is in fact the restating process adding them over time. I attempted to resolve the issue by adding the --rm flag to both the run commands but this caused an error (see the issue on GH). If i remove the restart-always line from the docker-compose file the issue is resolved without the need for the --rm flag, though the error didn’t happen when i tested it.

Also thanks a bunch for your help. This is the first time that I actually had to ask for help myself because I couldn’t find the answer somewhere.