Docker下的Flask开发,集成Postgres+Redis

许多Python库,都需要Linux环境,比如uvloop、gunicorn、Tensorflow、Postgres、eventlet等等。
有时不得不在Windows下开发Flask app时,借助Cygwin也只能完成一小部分任务(Windows环境(Cygwin)下,使用PostgreSQL, Redis
所以,还是拥抱Docker吧!

repo: https://github.com/kevinqqnj/flask-template-postgres-redis-in-docker

目标:

无论什么环境,只要有Docker,执行一行docker-compose命令,就能建立起一模一样的开发环境,省却了各种繁琐配置。
当然,数据库要能执久化,同一台电脑上不需要重复建数据

前提:

  • 电脑安装好Docker环境
    • 我是用的Win7 + VirtualBox
    • 安装Docker-Toolbox
  • psql (Postgresql命令行工具) - 可选
  • VirtualBox设置 -> 网络 -> 端口转发(有时网页调试打不开,试试这个)


    image.png

步骤:

1. git clone 模板,到你的本地目录

注:VirtualBox默认设置的共享文件夹是 C:\User\<yourID>\,如果想让Docker挂载你本地目录的话,本地目录必须要在C:\User\<yourID>\文件夹内。不然你就要设置其它的共享文件夹。

git clone https://github.com/kevinqqnj/flask-template-postgres-redis-in-docker.git
cd flask-template-postgres-redis-in-docker

2. 运行Docker Quickstart Terminal

先用国内速度快的镜像,预先下载好images:

docker pull registry.docker-cn.com/library/python:3
docker pull registry.docker-cn.com/library/postgres:9
docker pull registry.docker-cn.com/library/redis

3. 创建本地Volume,postgres数据库内容存放在此,可以执久化保存,就算电脑重启,数据库也不会丢

docker volume create pgdata

4. 开始 docker-compose,创建本地开发环境:

$ docker-compose up --build
Building web
Step 1/7 : FROM python:3
 ---> 500d0dca385d
Step 2/7 : ENV PYTHONUNBUFFERED 1
 ---> Using cache
 ---> 4f24d910ee44
Step 3/7 : ENV LANG C.UTF-8
 ---> Using cache
 ---> 9439fe70bc16
Step 4/7 : RUN mkdir /code
 ---> Using cache
 ---> fc838cf209fb
Step 5/7 : WORKDIR /code
 ---> Using cache
 ---> e3817459d383
Step 6/7 : ADD requirements.txt /code/
 ---> 7889368fb93a
Step 7/7 : RUN pip install -r requirements.txt
。。。
Successfully built 41ea5f76c4ec
Successfully tagged flasktemplateadvanced_web:latest
Recreating flasktemplateadvanced_db_1 ...
Recreating flasktemplateadvanced_db_1 ... done
Recreating flasktemplateadvanced_web_1 ... done
Attaching to flasktemplateadvanced_redis_1, flasktemplateadvanced_db_1, flasktemplateadvanced_web_1
redis_1  | 1:C 21 Mar 13:35:05.952 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 21 Mar 13:35:05.955 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=1, just started
db_1     | LOG:  database system was shut down at 2018-03-21 13:33:09 UTC
db_1     | LOG:  MultiXact member wraparound protections are now enabled
redis_1  | 1:C 21 Mar 13:35:05.958 # Warning: no config file specified, using the default config. In order to specify a
config file use redis-server /path/to/redis.conf
db_1     | LOG:  database system is ready to accept connections
redis_1  | 1:M 21 Mar 13:35:05.967 * Running mode=standalone, port=6379.
redis_1  | 1:M 21 Mar 13:35:05.971 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/co
re/somaxconn is set to the lower value of 128.
redis_1  | 1:M 21 Mar 13:35:05.971 # Server initialized
redis_1  | 1:M 21 Mar 13:35:05.972 # WARNING overcommit_memory is set to 0! Background save may fail under low memory co
ndition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl
 vm.overcommit_memory=1' for this to take effect.
redis_1  | 1:M 21 Mar 13:35:05.972 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This
will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/t
ransparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Re
dis must be restarted after THP is disabled.
redis_1  | 1:M 21 Mar 13:35:05.978 * DB loaded from disk: 0.006 seconds

这时,Redis服务已经正常工作了。打开浏览器:http://localhost:5000

image.png

5. Postgres服务:

环境变量文件在 .env里,

POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DB=myapp_db
DB_SERVICE=db
REDIS_SERVICE=redis

推荐不同的项目使用不同的database,比如这里用了:myapp_db
需要使用psql工具创建database:

$ psql -h localhost -p 5432 -U postgres
psql (9.6.6, 服务器 9.6.8)
输入 "help" 来获取帮助信息.

postgres=# \l
                                    数据库列表
   名称    |  拥有者  | 字元编码 |  校对规则  |   Ctype    |       存取权限
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 行记录)

postgres=# create database myapp_db;
CREATE DATABASE

6. 初始化数据库表格

当前Docker里,已经有名字是"web"的container了。另外打开一个“Docker Quickstart Terminal”窗口,执行命令行:

$ docker-compose run web bash
Starting flasktemplateadvanced_db_1 ... done
Starting flasktemplateadvanced_redis_1 ... done
root@7bc24648a3fc:/code# ls
Dockerfile  Procfile   __pycache    docker-compose.yml  manage.pyadmin.p    runtime.txts.txt
root@7bc24648a3fc:/code# python manage.py deploy
Importing environment from .env...
  Creating directory /code/migrations ... done
  Creating directory /code/migrations/versions ... done
  Generating /code/migrations/alembic.ini ... done
  Generating /code/migrations/env.py ... done
  Generating /code/migrations/script.py.mako ... done
  Generating /code/migrations/README ... done
  Please edit configuration/connection/logging settings in '/code/migrations/alembic.ini' before proceeding.
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'roles'
INFO  [alembic.autogenerate.compare] Detected added table 'users'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_users_username' on '['username']'
INFO  [alembic.autogenerate.compare] Detected added table 'roles_users'
  Generating /code/migrations/versions/a300240f4694_.py ... done
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> a300240f4694, empty message
root@7bc24648a3fc:/code#
root@7bc24648a3fc:/code# python manage.py initrole
Importing environment from .env...
Pls input Flask admin pwd:XXXXXXX
Roles added!
root@7bc24648a3fc:/code#

7. 非首次运行docker-compose

非首次运行docker-compose,只要运行docker-compose up就够了。
除非image内容修改,才需要重新docker-compose up --build
注意看gunicorn,配置过后,发现文件改动,能热重启,logging模式也可以在docker-compose.yml里设置。
这时,打开http://localhost:5000/admin,就能登录Flask后台,说明postgres服务正常连接了。

image.png

$ docker-compose up
Starting flasktemplateadvanced_db_1 ...
Starting flasktemplateadvanced_redis_1 ... done
Starting flasktemplateadvanced_web_1 ... done
Attaching to flasktemplateadvanced_db_1, flasktemplateadvanced_redis_1, flasktemplateadvanced_web_1
db_1     | LOG:  database system was interrupted; last known up at 2018-03-21 13:37:59 UTC
db_1     | LOG:  database system was not properly shut down; automatic recovery in progress
db_1     | LOG:  invalid record length at 0/14EEE38: wanted 24, got 0
db_1     | LOG:  redo is not required
db_1     | LOG:  MultiXact member wraparound protections are now enabled
db_1     | LOG:  database system is ready to accept connections
redis_1  | 1:C 21 Mar 13:40:41.171 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 21 Mar 13:40:41.179 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 21 Mar 13:40:41.180 # Warning: no config file specified, using the default config. In order to specify a
config file use redis-server /path/to/redis.conf
redis_1  | 1:M 21 Mar 13:40:41.200 * Running mode=standalone, port=6379.
redis_1  | 1:M 21 Mar 13:40:41.202 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/co
re/somaxconn is set to the lower value of 128.
redis_1  | 1:M 21 Mar 13:40:41.203 # Server initialized
redis_1  | 1:M 21 Mar 13:40:41.203 # WARNING overcommit_memory is set to 0! Background save may fail under low memory co
ndition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl
 vm.overcommit_memory=1' for this to take effect.
redis_1  | 1:M 21 Mar 13:40:41.204 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This
will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/t
ransparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Re
dis must be restarted after THP is disabled.
web_1    | [2018-03-21 13:40:43 +0000] [1] [INFO] Starting gunicorn 19.7.1
web_1    | [2018-03-21 13:40:43 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
web_1    | [2018-03-21 13:40:43 +0000] [1] [INFO] Using worker: sync
web_1    | [2018-03-21 13:40:43 +0000] [7] [INFO] Booting worker with pid: 7
web_1    | Importing environment from .env...

web_1    | [2018-03-21 13:45:31 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:16)
web_1    | [2018-03-21 13:45:31 +0000] [16] [INFO] Worker exiting (pid: 16)
web_1    | [2018-03-21 13:45:31 +0000] [19] [INFO] Booting worker with pid: 19
web_1    | Importing environment from .env...
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:15 +0000] "POST /login HTTP/1.1" 302 209 "http://localhost:5000/login" "Mozil
la/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:15 +0000] "GET / HTTP/1.1" 200 859 "http://localhost:5000/login" "Mozilla/5.0
 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:18 +0000] "GET /admin/ HTTP/1.1" 200 2181 "http://localhost:5000/" "Mozilla/5
.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:21 +0000] "GET /admin/user/ HTTP/1.1" 200 13160 "http://localhost:5000/admin/
" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:24 +0000] "GET /admin/role/ HTTP/1.1" 200 14853 "http://localhost:5000/admin/
user/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.
36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:25 +0000] "GET /admin/user/ HTTP/1.1" 200 13160 "http://localhost:5000/admin/
role/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.
36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:49 +0000] "GET /admin/ HTTP/1.1" 200 2181 "http://localhost:5000/admin/user/"
 "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:52 +0000] "GET / HTTP/1.1" 200 859 "http://localhost:5000/admin/" "Mozilla/5.
0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:55 +0000] "GET / HTTP/1.1" 200 859 "http://localhost:5000/admin/" "Mozilla/5.
0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | 10.0.2.2 - - [21/Mar/2018:13:46:57 +0000] "GET / HTTP/1.1" 200 860 "http://localhost:5000/admin/" "Mozilla/5.
0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
web_1    | [2018-03-21 14:03:12 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:19)
web_1    | [2018-03-21 14:03:12 +0000] [19] [INFO] Worker exiting (pid: 19)
web_1    | [2018-03-21 14:03:12 +0000] [22] [INFO] Booting worker with pid: 22

docker-compose.yml文件解析:

volumes::映射了源代码目录到Docker里。你在本地修改了任何源代码,立马能看到新的运行结果,无需重启build
command::gunicorn会热重启、logging level可设置
depends_on:依赖于db, redis两个服务,Docker会内部自动关联连接

services:
  web:
    build: .
    command: gunicorn -b 0.0.0.0:5000 --reload --access-logfile '-' --log-level info manage:app
    env_file: .env
    volumes:
      - ./:/code
    ports:
      - "5000:5000"
    depends_on:
      - db
      - redis

db, redis是服务名字,在Flask config.py文件里,也会使用这名字,来连接postgres/redis

  redis:
    image: redis
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"

  db:
    restart: always
    image: postgres:9
    env_file: .env
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

必须要有独立的volumes字段,这样才能数据执久化。

volumes:
  redis_data:
  pgdata:

注:docker python:3 是用的Debian系统

好了,小伙伴们,只需愉快地关注开发,不用操心环境的事了!

计划:deployment, 关注下k8s - kubernetes

觉得好用,github点个赞哦~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,002评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,777评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,341评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,085评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,110评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,868评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,528评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,422评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,938评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,067评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,199评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,877评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,540评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,079评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,192评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,514评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,190评论 2 357

推荐阅读更多精彩内容