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.7RUN pip install flaskRUN 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 1mENV 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 customizableENV 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 uWSGIENV STATIC_URL /static# Absolute path in where the static files wil beENV STATIC_PATH /app/static# If STATIC_INDEX is 1, serve / with /static/index.html directly (or the static URL configured)# ENV STATIC_INDEX 1ENV STATIC_INDEX 0# Add demo appCOPY ./app /appWORKDIR /appRUN pip install -r /app/requirements.txtRUN 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 appCOPY start.sh /start.shRUN chmod +x /start.sh# Copy the entrypoint that will generate Nginx additional configsCOPY entrypoint.sh /entrypoint.shRUN chmod +x /entrypoint.shENTRYPOINT ["/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 uWSGICMD ["/start.sh"]
(2) entrypoint.sh
#! /usr/bin/env bashset -e# Get the maximum upload file size for Nginx, default to 0: unlimitedUSE_NGINX_MAX_UPLOAD=${NGINX_MAX_UPLOAD:-0}# Generate Nginx config for maximum upload file sizeecho "client_max_body_size $USE_NGINX_MAX_UPLOAD;" > /etc/nginx/conf.d/upload.conf# Get the number of workers for Nginx, default to 1USE_NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1}# Modify the number of worker processes in Nginx configsed -i "/worker_processes\s/c\worker_processes ${USE_NGINX_WORKER_PROCESSES};" /etc/nginx/nginx.conf# Get the URL for static files from the environment variableUSE_STATIC_URL=${STATIC_URL:-'/static'}# Get the absolute path of the static files from the environment variableUSE_STATIC_PATH=${STATIC_PATH:-'/app/static'}# Get the listen port for Nginx, default to 80USE_LISTEN_PORT=${LISTEN_PORT:-80}# Generate Nginx config first part using the environment variablesecho "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.conffi# Finish the Nginx config fileecho "}" >> /etc/nginx/conf.d/nginx.confexec "$@"
(3) start.sh
#! /usr/bin/env bashset -e# If there's a prestart.sh script in the /app directory, run it before startingPRE_START_PATH=/app/prestart.shecho "Checking for script in $PRE_START_PATH"if [ -f $PRE_START_PATH ] ; then echo "Running script $PRE_START_PATH" source $PRE_START_PATHelse echo "There is no script $PRE_START_PATH"fi# Start Supervisor, with Nginx and uWSGIexec /usr/bin/supervisord
(4) uwsgi.ini
[uwsgi]module = appcallable = application
(5) prestart.sh
#!/bin/bashpython create_db.py
(6) create_db.py
from pymongo import MongoClientimport datetimeclient = MongoClient('mongodb://mongodb:27017')try: clientexcept Exception as e: raise eif client: db_test = client.get_database('test') users = db_test.get_collection('users') users.insert_one({ 'title': 't1'}) print(users)#我简单写的,自己要改
(7) app.py
import osimport sysfrom flask import Flaskfrom website.app import create_appbase_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.2flask-pymongo>=0.5.2pymysql>=0.8.1flask_corspymongoPyMySQL>=0.8.1authlib
4 运行指令
docker-compose up -d 启动
docker-compose down 终止
docker-compose stop web
docker-compose start web