Python web application project structure and docke

2019-05-27 12:15发布

问题:

Description

For instance, I have a following flask project structure:

├ project_root/
├── .gitignore
├── README.md
├── docs
├── requirements.txt
├── yourapp
│   ├── templates/
│   ├── static/
│   ├── migrations/
│   ├── config.py
│   ├── app1/
│   │   ├── __init__.py
│   │   ├── controllers.py
│   │   ├── forms.py
│   │   └── models.py
│   ├── app2/
│   │   └── ...
│   └── app.py
└── tests/

And I have following requirements:

  1. I would like to deploy it with gunicorn behind nginx, with a rabbitmq and celery and postgresql as database. Nginx serves static files from yourapp/static
  2. I would like to have all configuration be the part of my codebase, for instance all nginx, gunicorn and other configs should be placed somewhere in the same git repository.
  3. I would like to use a docker and have following docker images: web-app, postgresql, nginx, rabbitmq and celery-worker.
  4. I would like to be able to build all docker images from this git repository
  5. I would like to use Dockerfiles

Question

Where should I put configuration files and Dockerfiles if I want to meet all these requirements?

Additional information

I have some thoughts, but it's not clear. For instance I know, that I actually don't need a Dockerfile for postgresql image, I can use volume-only container and postgres image from Docker hub.

The main problem, that I can't solve is a interference of the nginx and application scopes: static files should be visible for nginx's Dockerfile and whole flask application also should be visible for gunicorn's Dockerfile, but I can't put 2 Dockerfiles in the same folder.

The other problem, that I would like to have folder with flask code(yourapp) be separated from the configurations folder, and all configuration files(nginx, gunicorn, celery) should be stored in the same folder.

回答1:

I would use docker-compose and do something like this example docker-compose.yml

web-app:
    build: .
    links:
         - postgresql
         - rabbitmq
    volumes_from:
         - config

config:
    build: .
    dockerfile: dockerfiles/Dockerfile.config

postgresql:
    image: postgres:9.4
    volumes_from:
        - postgresql-data

postgresql-data:
    build: dockerfiles/postgresql-data/

nginx:
    build: .
    dockerfile: dockerfiles/Dockerfile.nginx
    links:
        - web-app

rabbitmq:
    image: rabbitmq:3.5

celery-worker:
    build: .
    dockerfile: dockerfiles/Dockerfile.celery-worker
    links:
        - rabbitmq

web-app will use the default Dockerfile in the project_root/, all the other services will use a named dockerfile in a subdirectory (they can really be placed anywhere you want, they could be in the root as well). As long as the build points at the root directory they will have access to all the files.

I would put your application configuration into a separate container and use volumes_from to make it available to the application, so that you can use the same stateless app container with different configurations.

I think this satisfies all your requirements.