docker-compose:使用docker-compose部署nginx+supervisor+uwsgi+flask程序(mongodb)

0 写在前面

百度搜索的文档渣的要命,一定要Google,一定要GitHub。

1 目录层次

我们必须清楚我们docker-compose.yaml文件和Dockerfile的位置以及其他配置脚本的位置
假设我们有一个路径:/data/www/backend
那么该目录下应该是:
web/
docker-compose.yaml
 
而配置文件的docker-compose.yaml如下: 
version: '2'
services:
  web:
    build: ./web
    container_name: "web"
    volumes:
     - /data/www:/data/www
    ports:
     - 80:80
    depends_on:
     - mongodb

  mongodb:
    image: mongo:latest
    container_name: "mongodb"
    environment:
     - MONGO_DATA_DIR=/data/db
     - MONGO_LOG_DIR=/dev/null
    volumes:
     - ./data/db:/data/db
   

加入了kong API getway 网关的docker-compose.yaml
version: '2'
services:
  web:
    build: ./web
    container_name: "web"
    volumes:
     - /data/www:/data/www
    ports:
     - 80:80
    depends_on:
     - mongodb

  mongodb:
    image: mongo:latest
    container_name: "mongodb"
    environment:
     - MONGO_DATA_DIR=/data/db
     - MONGO_LOG_DIR=/dev/null
    volumes:
     - ./data/db:/data/db
     - ./data/www:/data/www

  kong-database:
    image: postgres:9.4
    container_name: "kong-database"
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=kong
      - POSTGRES_DB=kong
    volumes:
      - ./var/lib/postgresql/data:/var/lib/postgresql/data
  kong:
    image: kong:0.9.1
    container_name: kong
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
    restart: always
    ports:
      - 8000:8000
      - 8443:8443
      - 8001:8001
      - 7946:7946
      - 7946:7946/udp
    links:
      - kong-database

 

 
 
web 下面的目录是:
app/
Dockerfile
entrypoint.sh
start.sh
 
app里面的目录是,是自己的整个程序:
 
aliyunapi/
wechatapi/
myutils/
static/
templates/
website/
app.py
create_db.py
prestart.sh
requirements.txt
uwsgi.ini
readme.txt
 
但是最简单的目录是你自己开发的:
 
website/
app.py
create_db.py
prestart.sh
requirements.txt
uwsgi.ini
readme.txt

2 基本逻辑

基本镜像是基于tiangolo/uwsgi-nginx:python2.7,github地址
整体逻辑是:git clone 整体文件包,进入python 2.7,因为我是依赖python2.7,在你看不懂Dockerfile和docker-compose配置文件以及其他配置文件时候不要轻易修改。
所有的原来配置文件不要动,把你自己的程序根目录下的文件统一复制到app中去
 
命令启动的执行流程,详细看上面compose配置文件:docker-compose up 
(1)根据compose配置文件,web depends_on mongodb, 因此先用mongodb的纯镜像构造容器并且暴露mongodb的端口27017,等待连接
(2)build web(build dockerfile)构造主程序镜像,其次是执行入口脚本,enterstart.sh—>start.sh—>prestart.sh(处理docker纯镜像容器数据库,建立数据库,建表,设置索引)
(3)启动主程序的命令传递:supervisor->uwsgi->flask
 

3 具体脚本配置

(1) Dockerfile:

FROM tiangolo/uwsgi-nginx:python2.7

RUN pip install flask
RUN apt-get update && apt-get install docker

# By default, allow unlimited file sizes, modify it to limit the file sizes
# To have a maximum of 1 MB (Nginx's default) change the line to:
# ENV NGINX_MAX_UPLOAD 1m
ENV NGINX_MAX_UPLOAD 0

# By default, Nginx listens on port 80.
# To modify this, change LISTEN_PORT environment variable.
# (in a Dockerfile or with an option for `docker run`)
ENV LISTEN_PORT 80

# Which uWSGI .ini file should be used, to make it customizable
ENV UWSGI_INI /app/uwsgi.ini

# URL under which static (not modified by Python) files will be requested
# They will be served by Nginx directly, without being handled by uWSGI
ENV STATIC_URL /static
# Absolute path in where the static files wil be
ENV STATIC_PATH /app/static

# If STATIC_INDEX is 1, serve / with /static/index.html directly (or the static URL configured)
# ENV STATIC_INDEX 1
ENV STATIC_INDEX 0

# Add demo app
COPY ./app /app
WORKDIR /app

RUN pip install -r /app/requirements.txt
RUN cd /app/aliyunapi/dysms_python && python setup.py install

# Make /app/* available to be imported by Python globally to better support several use cases like Alembic migrations.
ENV PYTHONPATH=/app

# Copy start.sh script that will check for a /app/prestart.sh script and run it before starting the app
COPY start.sh /start.sh
RUN chmod +x /start.sh

# Copy the entrypoint that will generate Nginx additional configs
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

# Run the start script, it will check for an /app/prestart.sh script (e.g. for migrations)
# And then will start Supervisor, which in turn will start Nginx and uWSGI
CMD ["/start.sh"]

(2) entrypoint.sh

#! /usr/bin/env bash
set -e
# Get the maximum upload file size for Nginx, default to 0: unlimited
USE_NGINX_MAX_UPLOAD=${NGINX_MAX_UPLOAD:-0}
# Generate Nginx config for maximum upload file size
echo "client_max_body_size $USE_NGINX_MAX_UPLOAD;" > /etc/nginx/conf.d/upload.conf

# Get the number of workers for Nginx, default to 1
USE_NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1}
# Modify the number of worker processes in Nginx config
sed -i "/worker_processes\s/c\worker_processes ${USE_NGINX_WORKER_PROCESSES};" /etc/nginx/nginx.conf

# Get the URL for static files from the environment variable
USE_STATIC_URL=${STATIC_URL:-'/static'}
# Get the absolute path of the static files from the environment variable
USE_STATIC_PATH=${STATIC_PATH:-'/app/static'}
# Get the listen port for Nginx, default to 80
USE_LISTEN_PORT=${LISTEN_PORT:-80}

# Generate Nginx config first part using the environment variables
echo "server {
    listen ${USE_LISTEN_PORT};
    location / {
        try_files \$uri @app;
    }
    location @app {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
    location $USE_STATIC_URL {
        alias $USE_STATIC_PATH;
    }" > /etc/nginx/conf.d/nginx.conf

# If STATIC_INDEX is 1, serve / with /static/index.html directly (or the static URL configured)
if [[ $STATIC_INDEX == 1 ]] ; then 
echo "    location = / {
        index $USE_STATIC_URL/index.html;
    }" >> /etc/nginx/conf.d/nginx.conf
fi
# Finish the Nginx config file
echo "}" >> /etc/nginx/conf.d/nginx.conf

exec "$@"

(3) start.sh

#! /usr/bin/env bash
set -e

# If there's a prestart.sh script in the /app directory, run it before starting
PRE_START_PATH=/app/prestart.sh
echo "Checking for script in $PRE_START_PATH"
if [ -f $PRE_START_PATH ] ; then
    echo "Running script $PRE_START_PATH"
    source $PRE_START_PATH
else 
    echo "There is no script $PRE_START_PATH"
fi

# Start Supervisor, with Nginx and uWSGI
exec /usr/bin/supervisord

(4) uwsgi.ini

[uwsgi]
module = app
callable = application

(5) prestart.sh

#!/bin/bash
python create_db.py

(6) create_db.py

from pymongo import MongoClient
import datetime
client = MongoClient('mongodb://mongodb:27017')
try:
    client
except Exception as e:
    raise e

if client:
    db_test = client.get_database('test')
    users = db_test.get_collection('users')
    users.insert_one({'title': 't1'})

    print(users)

#我简单写的,自己要改

(7) app.py

import os
import sys
from flask import Flask
from website.app import create_app

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, base_dir)
print(sys.path)

application = create_app({
    'SECRET_KEY': '123456',
    'UPLOAD_FOLDER': '/static/tmp/uploads',
    'ALLOWED_EXTENSIONS': set(['bmp', 'png', 'jpg', 'jpeg', 'gif']),
    'MONGO_URI': 'mongodb://mongodb:27017/test',
    'MONGO_USERNAME': 'root',
    'MONGO_PASSWORD': 'root',
    'MONGO_CONNECT': False,
})

if __name__ == '__main__':
    application.run(host='0.0.0.0', port=6000,debug=True)

(8) requirements.txt

flask>=1.0.2
flask-pymongo>=0.5.2
pymysql>=0.8.1
flask_cors
pymongo
PyMySQL>=0.8.1
authlib

4 运行指令

docker-compose up -d 启动

docker-compose down 终止

docker-compose stop web

docker-compose start web

 

 

 

 

 

 

 

 

posted @ 2018-06-15 17:36  Adamanter  阅读(1778)  评论(0编辑  收藏  举报