說來慚愧,寫了好幾個flask django項目都是在原型階段直接python app.py 運行的,涉及到部署用nginx和gunicorn 都是讓別人幫我部署的,聽說好像說很麻煩的樣子,我就沒本身作。python
如今本身有時間了,搞了一下,發現也沒什麼複雜的,花半天搞定。哞哈哈哈。nginx
心得:git
1 不要怕。(要麼怕滿屏洋文,要麼怕新知識新技術一個坑接一個坑。其實比看論文/寫論文容易多了吧!)由於怕而逃避,拖延,最要不得github
2 不要本身zuan3。技術問題若是路數不對,可能很吃時間,搞N天搞不定;但其實都是一層窗戶紙。docker
不是搞科研,犯不上本身再發明一遍輪子耽誤時間。其實搞研究同樣要多讀別人的文獻,技術就更須要多讀多練了。空想空談的「空疏」,比學了一堆技能的「支離」更要不得。django
1 徹底不懂的技術框架,有官方文檔看官方文檔和demoflask
2幾種本身不太懂的技術配合的解決方案組合問題,如「OO+XX」這種:先去github找現成的solutionubuntu
3 1和2照作中,遇到具體問題,先stackoverflow,沒有再googleapi
要善於藉助外網的力量,並造成習慣。緩存
github上有現成的demo,仍是比較容易的。我fork下來,又稍微修改了幾點,厚臉皮pull request了。
# nginx-gunicorn-flask with python3 FROM python LABEL author="" LABEL purpose = '' RUN apt update RUN apt install -y nginx supervisor RUN pip3 install gunicorn RUN pip3 install setuptools ENV PYTHONIOENCODING=utf-8 # Build folder RUN mkdir -p /deploy/app WORKDIR /deploy/app #only copy requirements.txt. othors will be mounted by -v COPY app/requirements.txt /deploy/app/requirements.txt RUN pip3 install -r /deploy/app/requirements.txt # Setup nginx RUN rm /etc/nginx/sites-enabled/default COPY nginx_flask.conf /etc/nginx/sites-available/ RUN ln -s /etc/nginx/sites-available/nginx_flask.conf /etc/nginx/sites-enabled/nginx_flask.conf RUN echo "daemon off;" >> /etc/nginx/nginx.conf # Setup supervisord RUN mkdir -p /var/log/supervisor COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY gunicorn.conf /etc/supervisor/conf.d/gunicorn.conf # run sh. Start processes in docker-compose.yml #CMD ["/usr/bin/supervisord"] CMD ["/bin/bash"]
和原做者不一樣的幾處修改,說明一下:
官方源如今也能夠apt update 也帶了pip3了,只不過setuptools仍是要手動裝(MD都裝利索了會死啊),就不必本身用ubuntu裝python3.6了
dockerfile語法有些過期了,改爲LABEL author了
把gunicorn改爲了用pip3安裝,而不是apt安裝,不然,用supervisord運行,會報錯:
gunicorn gunicorn (exit status 1; not expected)
或者
FATAL Exited too quickly (process log may have details)
原做者是在build鏡像的時候把代碼全都COPY進去了,我改爲只copy requirements.txt 用於安裝python包就能夠了。代碼之類的我仍是喜歡用-v掛載。
結尾,把 supervisord 改爲bash。由於不免要調試一下。這樣起container以後,attach進去能夠手動啓動flask。
把自動的supervisord 放在docker-compose.yml裏,更靈活一些。
幾個配置文件,其實沒有太多可說的:
server { listen 80; location / { proxy_pass http://localhost:5000/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ^~ /static/ { root /deploy/app/; } }
照着別人的demo增長static(其實不加的話,是否是也能緩存呢?)
注意^~ 有空格 和路徑寫法 root /deploy/app/ 不要多寫static
[program:gunicorn] command=gunicorn --workers=3 app:app -b localhost:5000 directory=/deploy/app
[supervisord] nodaemon=true [program:nginx] command=/usr/sbin/nginx
而後,用docker-compose管理容器
version: "3.3"
services:
api:
#restart: always
stdin_open: true
tty: true
build: ./dockerfile
image: nginx-gunicorn-flask:latest
volumes:
- ./app:/deploy/app
- ./nginx_flask.conf:/etc/nginx/sites-available/nginx_flask.conf
- ./gunicorn.conf:/etc/supervisor/conf.d/gunicorn.conf
- ./supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
ports:
- "80:80"
#command: '/bin/bash'
command: '/usr/bin/supervisord'
若是是調試,不但願自動運行,就把最後一句command註釋了。啓動以後attach進去
4個掛載點,第1個是所有代碼;後面是3個conf文件,各掛到各自該去的地方。
惟一注意的是這種掛單文件的時候,冒號先後不能加空格,不然報錯。(以前實驗了絕對路徑,加雙引號。。。覺得是yml版本過低…但都不對),如今這樣寫最簡單。
如今這樣啓動以後,代碼在host,用IDE修改代碼後,容器裏躲在Nginx和gunicorn以後的flask同樣自動熱更新,oyeah!