主頁 > 知識庫 > Docker部署Django應(yīng)用的示例

Docker部署Django應(yīng)用的示例

熱門標簽:新鄉(xiāng)人工智能電話機器人加盟 400電話申請找哪家公司 臨汾電銷機器人費用 昆明外呼系統(tǒng) 七大洲地圖標注 地圖標注需要提交啥資料入駐 地圖標注w是什么方向 福州呼叫中心外呼系統(tǒng)哪家好 河南省鄭州市地圖標注

之前部署Web應(yīng)用,沒用docker,直接在服務(wù)器上部署,使用了fabric+nginx+supervisor+gunicorn部署,可查看我寫過的一片博客:部署Web應(yīng)用。但后來了解了docker,為其“Build,Ship and Run Any App,Anywhere”的思想所折服,覺得這個太牛逼了,所以我也嘗試一下自己用docker部署Web應(yīng)用。本篇文章為了記錄我用docker部署web應(yīng)用的過程和心得。

一、網(wǎng)絡(luò)架構(gòu)

我用Visio大概畫了一下我的網(wǎng)絡(luò)架構(gòu)圖:

我構(gòu)建的容器:

  1. Nginx容器;
  2. Web server容器
  3. Redis容器
  4. memcached容器
  5. MySQL容器

如果把所有應(yīng)用都部署到一個應(yīng)用中,可能會更簡單,但不同容器之間就稍微復(fù)雜點。首先你要考慮好容器之間的依賴關(guān)系,比如nginx要依賴web服務(wù)器,如果web服務(wù)器不正常工作,那nginx就不能正常工作;web服務(wù)器要依賴于數(shù)據(jù)庫等等;其次,要設(shè)置好容器間的數(shù)據(jù)共享問題。比如對于web應(yīng)用的靜態(tài)資源,怎么讓nginx實現(xiàn)反向代理。

帶著這些疑問,開始部署。

二、環(huán)境:

準備docker的環(huán)境。

  • Ubuntu 16.04 (主機環(huán)境)
  • docker 17.06.0
  • docker-compose 1.14.0
  • compose file 版本: version 3

對于docker的作用和介紹可參考官網(wǎng):Docker service。

要注意你的docker版本以及composefile版本,因為不同的版本,語法可能略有不同。我之前在配置共享數(shù)據(jù)卷的時候就遇到過坑,比如在version 3中刪掉了volumes_from,我還不知道有版本差異,所以怎么配置都不對。更詳細的請看官網(wǎng):dockerfile 版本。

1、工程結(jié)構(gòu)

├── blog 
│ ├── account
│ ├── blog
│ ├── dailyblog
│ ├── Dockerfile
│ ├── gunicorn.conf
│ ├── manage.py
│ ├── media
│ ├── requirements.txt
│ ├── start.sh
│ └── static
├── docker-compose.yml
└── nginx
 ├── Dockerfile
 └── nginx.conf

blog是我的django應(yīng)用,內(nèi)有Dockfile文件;nginx文件里也有一個Dockfile。blog和nginx分別是一個service,我們通過docker-compose.yml文件的配置來創(chuàng)建鏡像和容器。也就是說你必須要做幾件事:

  1. 在每個服務(wù)(應(yīng)用)下編寫Dockerfile;
  2. 在docker-compose.yml文件中配置相關(guān)的服務(wù);
  3. 執(zhí)行docker-compose命令 build和up

2、Django應(yīng)用的配置(blog包):

1)Dockfile

FROM ubuntu:16.04

#更新軟件源,必須要執(zhí)行,否則可能會出錯。-y就是要跳過提示直接安裝。
RUN apt-get -y update

RUN apt-get install -y python-dev python-pip
RUN apt-get install -y python-setuptools
#MySQL-Python必須得先安裝這個庫
RUN apt-get install -y libmysqlclient-dev 
RUN mkdir /blog
#設(shè)置工作目錄
WORKDIR /blog
#將當前目錄加入到工作目錄中
ADD . /blog
#install any needed pacakges in requirements.txt,你要把所有需要安裝的Python模塊加到這文件中。
RUN pip install -r requirements.txt
#對外暴露端口
EXPOSE 80 8080 8000 5000
#設(shè)置環(huán)境變量
ENV SPIDER=/blog

我的基礎(chǔ)鏡像選擇了Ubuntu,是因為我覺得我可能更習慣一些。

2)啟動腳本 start.sh

#!/bin/bash
#命令只執(zhí)行最后一個,所以用 &&

python manage.py collectstatic --noinput &&
python manage.py migrate &&
gunicorn blog.wsgi:application -c gunicorn.conf

在你初次部署時,你要收集各個app的static目錄到工程static目錄中,同時要創(chuàng)建數(shù)據(jù)庫。上面的3個命令通過 && 拼接,相當于一個命令。

此外,django應(yīng)用選擇gunicorn做web服務(wù)器,gunicorn的配置文件如下:

workers=4
bind=['0.0.0.0:8000']
proc_name='blog'
pidfile='/tmp/blog.pid'
worker_class='gevent'
max_requests=6000

gunicorn中host選擇 0.0.0.0:8000。

3、Nginx配置(nginx目錄)

1)Dockfile

FROM nginx

#對外暴露端口
EXPOSE 80 8000

RUN rm /etc/nginx/conf.d/default.conf

ADD nginx.conf /etc/nginx/conf.d/

RUN mkdir -p /usr/share/nginx/html/static
RUN mkdir -p /usr/share/nginx/html/media

nginx的基礎(chǔ)鏡像選擇docker倉庫中的基礎(chǔ)鏡像nginx即可,同時要把自己的配置文件添加到相關(guān)目錄中。這里有一點要注意,就是我自己曾經(jīng)在主機配置nginx的時候,一般/etc/nginx/nginx.conf會從 /etc/nginx/conf.d,和/etc/nginx/site-enabled/兩個文件目錄尋找conf文件,我之前都是添加到/etc/nginx/site-enabled/,這次也是這么做的,但是我配置運行之后,nginx沒有正常工作,我進入nginx容器看了一下,想看看為啥我的配置沒有加載,打開/etc/nginx/nginx.conf一看,果然,它只include了/etc/nginx/conf.d中的conf文件。Bingo!改了我的配置文件,OK。

后面創(chuàng)建的static和media是為了web應(yīng)用的靜態(tài)文件存儲。

2)nginx.conf

server {
 listen  80;
 server_name localhost;
 charset  utf-8;

 error_log /tmp/nginx_error.log;
 access_log /tmp/nginx_access.log;


 location /media {
  alias /usr/share/nginx/html/media;
 }

 location /static {
  alias /usr/share/nginx/html/static;
  }

 location / {
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_pass http://web:8000;
 }

}

關(guān)于nginx配置,要注意以下兩點,是非常重要的:

location

靜態(tài)文件配置,nginx指定的靜態(tài)文件原目錄是在/usr/share/nginx/html/,而該目錄下的靜態(tài)文件是從web容器中通過volumes同步的。所以,等下docker-compose是非常非常重要的。

proxy_pass

這和你直接在主機上配置是不一樣的,host不能寫成具體的IP,要寫服務(wù)名,這里要寫web service的name,web是在docker-compose中定義的web應(yīng)用的service名稱。后面要寫docker-compose的配置。

4、docker-compose.yml配置

version: "3"

services:


 db:
 image: mysql
 environment:
  MYSQL_DATABASE: app_blog
  MYSQL_ROOT_PASSWORD: admin
 volumes:
  - /srv/db:/var/lib/mysql
 restart: always

 redis:
 image: redis
 restart: always

 memcached:
 image: memcached
 restart: always

 web:
 build: ./blog
 ports:
 - "8000:8000"
 volumes:
 - ./blog:/blog
 - /tmp/logs:/tmp
 command: bash start.sh
 links:
 - redis
 - memcached
 - db
 depends_on:
  - db
 restart: always


 nginx:
 build: ./nginx
 ports:
 - "80:80"
 volumes:
 - ./blog/static:/usr/share/nginx/html/static:ro
 - ./blog/media:/usr/share/nginx/html/media:ro
 links:
 - web
 depends_on:
 - web
 restart: always

 這個文件是非常重要的?。。?/p>

定義了5個服務(wù):

  • db。 MySQL數(shù)據(jù)庫;
  • Redis。 緩存,NoSQL數(shù)據(jù)庫;
  • memcached。 緩存;
  • web。 web應(yīng)用;
  • nginx。 反向代理。

服務(wù)名稱對于容器間的溝通是非常重要的。我們這里一個一個說。

1)db

配置的幾個方面:

  • 基礎(chǔ)鏡像從docker倉庫中獲得(配置image);
  • 配置了環(huán)境變量,創(chuàng)建一個數(shù)據(jù)庫(該數(shù)據(jù)庫名為app_blog,django在執(zhí)行migrate操作時會用);
  • volumes。數(shù)據(jù)卷,為了實現(xiàn)備份用的,/srv/db,是主機目錄,/var/lib/mysql是MySQL容器內(nèi)目錄;
  • restart 默認是no,意思是在任何情況都不會重啟;如果設(shè)成always,就是如果stop了,就會重啟;
  • root用戶的密碼;你在django應(yīng)用的settings.py里也要寫成響應(yīng)的配置,具體如下:
DATABASES = {
'default': {
 'ENGINE': 'django.db.backends.mysql',
 'NAME': 'app_blog',
 'USER': 'root',
 'PASSWORD':'admin',
 'PORT':3306,
 'HOST':'db',
}
}

2)redis,memcached

這兩個就一起說了,因為不需要重新配置,直接用倉庫中的鏡像即可。

3)web應(yīng)用

配置的幾個方面:

  • build。 根據(jù)Dockerfile重新build一個鏡像;
  • ports。 格式為HOST:CONTAINER。相當于一個nat轉(zhuǎn)換,設(shè)置內(nèi)部的端口向外轉(zhuǎn)發(fā)的端口;
  • volumes。同樣是設(shè)置數(shù)據(jù)文件備份,也可以說成是同步,web容器的工作目錄/blog備份到主機上的目錄;
  • links. 創(chuàng)建和其他容器中的service的鏈接,指定服務(wù)名字即可。有了這個連接,服務(wù)之間就可以通過service名字通信了,在前面nginx配置中的proxy_pass就用了web服務(wù);
  • depends_on. 它有兩層含義,一是在啟動服務(wù)的時候,會先啟動db,然后再啟動web;二是如果執(zhí)行ocker-compose up web也會創(chuàng)建和啟動db.

4)nginx

  • build。 根據(jù)Dockerfile重新build一個鏡像;
  • ports。 格式為HOST:CONTAINER。相當于一個nat轉(zhuǎn)換,設(shè)置內(nèi)部的端口向外轉(zhuǎn)發(fā)的端口; http默認端口
  • links. 上面已經(jīng)介紹了;
  • depends_on. 上面也介紹了;
  • volumes。 這個我認為是最重要的,重點說一下。

關(guān)于如何實現(xiàn)nginx容器和web容器間的數(shù)據(jù)共享,即靜態(tài)文件共享的問題,真是把我困擾住了。我先是按照官網(wǎng)配置,在頂級配置了volumes,在服務(wù)下配置type,source,之類的,但一直沒成功(如果有配成功的,拿出來分享下哈);后來網(wǎng)上搜了一堆資料,容器間共享他們都用了volumes_from,這在version3中已經(jīng)取消了,退回舊版本還不行。上周五真是煩得我頭疼啊。后來看了一篇文章,才突然開竅,我本應(yīng)該早點想到啊。邏輯是這樣的:

首先,我在web應(yīng)用中就已經(jīng)設(shè)置volumes數(shù)據(jù)的備份,即將容器中的文件同步到主機上,然后主機就可以充當這個中間者,nginx容器再從主機上同步靜態(tài)文件。這就相當于celery中,生產(chǎn)者將任務(wù)消息寫到消息中間件中,然后消費者從中間件中取消息來消息,而這里面web應(yīng)用就類似生產(chǎn)者,nginx是消費者。

這樣問題就迎刃而解了?。?!

到目前為止,所有部署相關(guān)的配置都已經(jīng)寫完了。

首先執(zhí)行:

docker-compose build

然后執(zhí)行:

docker-compose up -d 

題外話:我是在周六晚上11點跑的第一個build命令,執(zhí)行各種鏡像下載,軟件源更新,Get資源比較慢,我太困了,就睡覺了。晚上睡覺做夢感覺都是docker,然后不到6點我就起了,到了客廳看電腦build已經(jīng)成功。我就開始執(zhí)行up命令,當我打開瀏覽器,輸入localhost,然后成功返回結(jié)果的那一刻,甭提多有成就感啦?。?!

隨意幾個知識點:

Docker刪除所有容器:

docker rm docker ps -a -q

最重要的是后面的 -q選項,表示只顯示ID。

刪除none鏡像:

docker rmi docker images -f "dangling=true" -q

更新。dockerfile要加上apt-get update,否則后面的命令不能正常執(zhí)行;

command命令只執(zhí)行最后一個,在腳本中寫了三個命令,但最后只執(zhí)行最后一個。后來把三個命令用 && 拼接起來。

docker鏡像內(nèi)的文件互相拷貝

1、將本地文件拷貝到docker 鏡像內(nèi)

docker cp /Users/howey/Documents/apache-maven-3.5.2/ 749056ea1637:/opt
docker cp 本地路徑 容器Id或name:容器目錄

2、將docker內(nèi)文件拷貝到本地文件夾內(nèi)

docker cp 749056ea1637:/Users/howey/Documents/apache-maven-3.5.2 /opt/
docker cp 容器Id:本地路徑 鏡像路徑

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

標簽:岳陽 烏海 四川 鎮(zhèn)江 紅河 臨沂 股票

巨人網(wǎng)絡(luò)通訊聲明:本文標題《Docker部署Django應(yīng)用的示例》,本文關(guān)鍵詞  Docker,部署,Django,應(yīng),用的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Docker部署Django應(yīng)用的示例》相關(guān)的同類信息!
  • 本頁收集關(guān)于Docker部署Django應(yīng)用的示例的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章