我們所在的內(nèi)網(wǎng)環(huán)境需要部署一個(gè)類似cms的應(yīng)用,就是一些表格的crud,數(shù)據(jù)導(dǎo)出,人員權(quán)限管理等功能。想到django做這方面的工作挺擅長(zhǎng)的,而且開發(fā)量不大,于是選擇django作為開發(fā)基礎(chǔ)。開發(fā)功能比較簡(jiǎn)單,差不多就是使用xadmin等插件實(shí)現(xiàn)以上功能。但有一個(gè)問題我們是不好繞過去的,那就是部署到一個(gè)內(nèi)網(wǎng)環(huán)境,在內(nèi)網(wǎng)pip等工具是不能使用的,但好在內(nèi)網(wǎng)有一個(gè)yum服務(wù)器可以使用,所以我們決定在內(nèi)網(wǎng)服務(wù)器上安裝docker,然后把開發(fā)環(huán)境的容器復(fù)制到生產(chǎn)環(huán)境實(shí)現(xiàn)部署。以下是主要的步驟:
安裝開發(fā)環(huán)境的 docker-ce安裝開發(fā)環(huán)境的 docker-compose配置開發(fā)環(huán)境保存容器安裝生產(chǎn)環(huán)境的 docker-ce 和 docker-compose發(fā)送容器文件并運(yùn)行注意:我這里的開發(fā)環(huán)境是ubuntu18.04,生產(chǎn)環(huán)境是centos7.2。如果你是其他環(huán)境請(qǐng)自己檢查差異,使用適合自己系統(tǒng)的命令。
安裝開發(fā)環(huán)境的 docker-ce
docker 和 docker-compose是我們這次部署需要重點(diǎn)演示的內(nèi)容,django 的應(yīng)用部分我會(huì)盡量縮減的。docker 負(fù)責(zé)容器虛擬化的底層部分,docker-compose 是一個(gè)容器編排工具,有了它咱們就不用手寫 shell 實(shí)現(xiàn)容器之間的連接了。我們先安裝 docker-ce,這里主要是參考 docker 的官方文檔,如果我寫的不夠詳細(xì)或者已經(jīng)過時(shí),各位看官可到官方查看更權(quán)威更新的文檔。
卸載舊版本
在安裝之前需要卸載舊版本的 docker,如果你是新系統(tǒng),可以忽略這一步。
$ sudo apt remove docker docker-engine docker.io containerd runc安裝用用到的 apt 倉庫
更新apt包索引
$ sudo apt update允許apt通過https訪問倉庫
$ sudo apt install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
增加docker的官方gpg key
$ curl -fssl https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -增加docker的倉庫
$ sudo add-apt-repository \
deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable
安裝 docker-ce
做好以上的準(zhǔn)備后安裝docker-ce就簡(jiǎn)單了,熟悉ubuntu的話,很快就能裝好。
$ sudo apt update
$ sudo apt install -y docker-ce安裝完成后,啟動(dòng) docker 服務(wù)并使其能夠在每次系統(tǒng)引導(dǎo)時(shí)啟動(dòng)。
$ sudo systemctl start docker
$ sudo systemctl enable docker安裝開發(fā)環(huán)境的docker-compose
docker-ce安裝完成后,docker-compose就好辦了。如果你是在linux等平臺(tái)上直接下載docker-compose的編譯好的二進(jìn)制文件即可使用。
復(fù)制代碼 代碼如下:
$ sudo curl -l “https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose
下載完成后修改權(quán)限加上可執(zhí)行
$ sudo chmod +x /usr/local/bin/docker-compose最后可執(zhí)行一下查看docker-compose的版本號(hào)驗(yàn)證一下是否成功安裝
$ docker-compose --version
docker-compose version 1.24.0-rc1, build 0f3d4dda配置開發(fā)環(huán)境
這里的開發(fā)環(huán)境是django的環(huán)境,演示的項(xiàng)目為了方便演示我盡量使用一個(gè)新建的django項(xiàng)目。
新建django項(xiàng)目
新建一個(gè)django項(xiàng)目,先創(chuàng)建一個(gè)上層文件夾來把項(xiàng)目文件放到這個(gè)文件夾中。目錄結(jié)構(gòu)大致如下:
--project
--dockerfile
--docker-compose.yml
--mysite
--manage.py
--requirements.txt
先創(chuàng)建project文件夾
$ mkdir project然后新建django項(xiàng)目,或者你也可以把已有的項(xiàng)目拷貝過來。
$ django-admin.py startproject mysite生成requirements.txt文件
上一步已經(jīng)有了一個(gè)叫mysite的django項(xiàng)目,假設(shè)我們把requirements.txt放到這個(gè)文件夾下,內(nèi)容大致如下:
$ cat requirements.txt
defusedxml==0.5.0
diff-match-patch==20181111
django==2.1.7
django-crispy-forms==1.7.2
django-formtools==2.1
django-import-export==1.2.0
django-reversion==3.0.3
et-xmlfile==1.0.1
future==0.15.2
httplib2==0.9.2
jdcal==1.4
odfpy==1.4.0
openpyxl==2.6.0
pytz==2018.9
pyyaml==3.13
six==1.10.0
tablib==0.12.1
unicodecsv==0.14.1
xadmin==0.6.1
xlrd==1.2.0
xlwt==1.3.0
mysqlclient==1.4.2當(dāng)然這是我的項(xiàng)目需要的依賴,你的依賴可能和我的不一樣。
新建dockerfile
項(xiàng)目有了,項(xiàng)目的依賴文件也有了,下一步就是創(chuàng)建我們的django項(xiàng)目的運(yùn)行環(huán)境的docker鏡像了,先建一個(gè)dockerfile來構(gòu)建docker鏡像。 在project文件夾新建dockerfile,內(nèi)容如下:
$ cat dockerfilefrom python:3.6.8
env pythonunbuffered 1
run mkdir /config
add /mysite/requirements.txt /config/
run pip install -r /config/requirements.txt
run mkdir /src
workdir /src/mysite
我簡(jiǎn)單解釋一下這個(gè)文件
from python:3.6.8
這里我使用的基礎(chǔ)鏡像是python:3.6.8,它的基礎(chǔ)鏡像是ubuntu我比較熟悉,如果你對(duì)alpine比較熟悉的話也可以使用alpine,那個(gè)鏡像要小的多。
env pythonunbuffered 1
你可以使用 env 關(guān)鍵字創(chuàng)建任意的操作系統(tǒng)的環(huán)境變量
env pythonunbuffered 1
例如,如果你使用它來存儲(chǔ)你的 django 密鑰,你可以這樣寫:
env django_secret_key l!fafmjcqyn+j+zz1@2@wt$o8w8k(_dhgub%41l#k3zi2m-b%m
在你的代碼里這樣使用:
import os
secret_key = os.environ['django_secret_key']run顧名思義,run就是在容器里面運(yùn)行命令,這里run命令創(chuàng)建了兩個(gè)文件夾/config和/src,以及安裝python的依賴環(huán)境。
run mkdir /config
run mkdir /src
run pip install -r /config/requirements.txtadd
add /mysite/requirements.txt /config/增加本地的文件到容器中 workdir
workdir /src/mysite是指定后面所有在容器里運(yùn)行命令的默認(rèn)路徑,要運(yùn)行的命令在稍后的docker-compose文件這種可以看到。
新建docker-compose腳本
docker-compose可以用來管理多個(gè)容器,以前手動(dòng)加海量參數(shù)運(yùn)行容器并連接容器的活都可以讓docker-compose來做了。我的docker-compose.yml內(nèi)容大致如下:
$ cat docker-compose.ymlversion: '3'
services:
db:
image: mysql:5.7
container_name: mysite_db
ports:
- 3306:3306
environment:
mysql_root_password: mysite
mysql_database: mysite
lang: c.utf-8
web:
build: .
container_name: mysite_web
command: bash -c python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000
depends_on:
- db
volumes:
- ./mysite:/src
restart: always
ports:
- 8002:8000再簡(jiǎn)單解釋一下這個(gè)docker-compose文件吧。
version: '3'指的是docker-compose的版本,不同版本支持的配置項(xiàng)目稍有不同。 services 管理的服務(wù),我們的例子中是兩個(gè)服務(wù):db和web。兩個(gè)服務(wù)中的配置項(xiàng)目我分開解釋一下 db:
image 直接使用docker hub或者本地的已有鏡像,這個(gè)使用的是mysql5.7 container_name 指定容器的名稱 ports 指定容器對(duì)宿主機(jī)的端口映射,前面的是宿主機(jī)端口,后面的是容器端口 environment 指定當(dāng)前服務(wù)運(yùn)行時(shí)候的環(huán)境,環(huán)境的細(xì)節(jié)參考當(dāng)前鏡像的說明,那上面說支持哪些,我們就可以配置哪些。這個(gè)案例中我們指定了mysql的root密碼、默認(rèn)數(shù)據(jù)庫和數(shù)據(jù)庫的字符集。 web: build 編譯鏡像,這里是使用當(dāng)前文件夾下的dockerfile command 容器啟動(dòng)后執(zhí)行的命令 depends_on 當(dāng)前容器要依賴的服務(wù),也就是說必須依賴中的服務(wù)成功啟動(dòng)當(dāng)前服務(wù)才能啟動(dòng) volumes 當(dāng)前容器要掛載的卷,前面指的是宿主機(jī)的目錄,后面是容器目錄 restart 指定容器的重啟策略,當(dāng)前案例是如果出錯(cuò)就一直重啟。 這里把容器的8000端口映射到宿主機(jī)的8002端口,web服務(wù)就是從8002端口訪問。
配置django項(xiàng)目
現(xiàn)在針對(duì)當(dāng)前的容器環(huán)境修改一下mysite項(xiàng)目的settings.py文件。
$ vim mysite/mysite/settings.py找到文件中的allow_hosts部分,添加“web”到其中,內(nèi)容如下:
allow_hosts = [
...
'web'
]
然后修改settings.py中的databases部分,把參數(shù)改為mysql服務(wù)db的參數(shù),內(nèi)容大致如下:
databases = {
'default': {
'engine': 'django.db.backends.mysql',
'name': 'mysite',
'user': 'root',
'password': 'mysite',
'host': 'db'
}
}
這里的mysql連接參數(shù)都是docker-compose.yml文件中db部分的environment中定義的。值得指出的是參數(shù)host值為db,docker-compose啟動(dòng)容器后,會(huì)連接這些容器,容器之間可以使用服務(wù)名稱互相ping通,就像使用域名那樣,所以這里的“host”可直接填寫“db”。
使用docker-compose構(gòu)建項(xiàng)目
經(jīng)過以上的努力,基本準(zhǔn)備齊備了,我們可以構(gòu)造我們的鏡像了,這里有兩個(gè)服務(wù),db只需要在運(yùn)行的時(shí)候下載或者使用本地鏡像就行,web還需要使用dockerfile構(gòu)建一下。
$ docker-compose build經(jīng)過一陣兒下載或者構(gòu)建,就能看到成功構(gòu)建鏡像的信息了。
運(yùn)行項(xiàng)目并測(cè)試一下
構(gòu)建完成后,就有了web服務(wù)的鏡像了,我們現(xiàn)在使用docker-compose來啟動(dòng)服務(wù)。
$ docker-compose up -d這個(gè)過程可能也需要執(zhí)行一陣兒,取決于你的網(wǎng)速,它會(huì)下載mysql的鏡像,并且根據(jù)db和web的鏡像構(gòu)造容器,并運(yùn)行容器。完成后可以使用docker-compose ps和docker-compose images來查看我們生成的容器和鏡像
$ docker-compose psname command state ports
---------------------------------------------------------------------------------------
mysite_db docker-entrypoint.sh mysqld up 0.0.0.0:3306->3306/tcp, 33060/tcp
mysite_web bash -c python manage.py m ... up 0.0.0.0:8002->8000/tcp$ docker-compose imagescontainer repository tag image id size
--------------------------------------------------------
mysite_db mysql 5.7 e47e309f72c8 355 mb
mysite_web mysite_web latest 3989acbcc3c9 938 mb也可使用docker-compose來停止和開始服務(wù),其他更具體的使用方法,請(qǐng)參考官方文檔吧。
$ docker-compose start
starting db ... done
starting web ... done$ docker-compose stop
stopping mysite_web ... done
stopping mysite_db ... done你看這里的服務(wù)停止和啟動(dòng)的順序都是有規(guī)律的啟動(dòng)的時(shí)候被依賴的服務(wù)先啟動(dòng)然后啟動(dòng)依賴它的服務(wù),挺值服務(wù)的時(shí)候剛好相反。待服務(wù)正常運(yùn)行后,可以訪問瀏覽器測(cè)試一下服務(wù)是否正常啟動(dòng)。
保存容器
如果服務(wù)一切正常,我們就要把當(dāng)前的容器保存起來,為部署到新平臺(tái)上做準(zhǔn)備。 注意: ?這里要使用save保存鏡像,使用save是包括容器之間的連接狀態(tài)等信息的,如果用export導(dǎo)出鏡像到生產(chǎn)環(huán)境是不能使用docker-compose恢復(fù)服務(wù)的。
$ docker save -o mysql.tar mysql:5.7
$ docker save -o mysite.tar mysite_web:latest當(dāng)以上命令執(zhí)行成功后會(huì)在當(dāng)前目錄生成兩個(gè)tar文件,再加上project目錄的dockerfile和docker-compose.yml文件放在一起準(zhǔn)備遷移到生產(chǎn)機(jī)器上。
安裝生產(chǎn)環(huán)境的 docker-ce 和 docker-compose
由于生產(chǎn)環(huán)境是centos,可以直接使用yum安裝
$ sudo yum install docker-ce安裝成功后,參考開發(fā)環(huán)境把docker-compose部署到生產(chǎn)服務(wù)器上。
發(fā)送容器文件并運(yùn)行
使用scp或者其他工具把mysql.tar、mysite.tar、docker-compose.yml以及項(xiàng)目文件夾發(fā)送到生產(chǎn)服務(wù)器,并找一個(gè)合適的文件夾存放這些文件,保持原來的目錄結(jié)構(gòu)。 我們先把兩個(gè)鏡像恢復(fù)到生產(chǎn)服務(wù)器上
$ docker load -i mysql.tar
$ docker load -i mysite_web.tar等待一小會(huì)兒執(zhí)行完成,可以看到當(dāng)前服務(wù)器已經(jīng)有這兩個(gè)鏡像了。
repository tag image id created size
mysite_web latest 3989acbcc3c9 2 days ago 983mb
mysql 5.7 e47e309f72c8 3 weeks ago 372mb在執(zhí)行構(gòu)建容器以前我們還要對(duì)docker-compose.yml做個(gè)簡(jiǎn)單的修改。你也注意到,生產(chǎn)服務(wù)器沒有互聯(lián)網(wǎng),所以不能再build鏡像了,而且我們還把開發(fā)環(huán)境的鏡像原樣照搬了過來,所以這次web服務(wù)改為從鏡像運(yùn)行就行了,內(nèi)容大致如下:
version: '3'
services:
db:
...
web:
image: mysite_web:latest
...只要更改web中的build項(xiàng)刪除,并加上一個(gè)image項(xiàng),內(nèi)容就是我們拷貝過來的那個(gè)鏡像。稍后我們就可以構(gòu)建容器并啟動(dòng)服務(wù)了。
$ docker-compose up -d
結(jié)果
name command state ports
----------------------------------------------------------------------------------------
mysite_web bash -c python manage.py m ... up 0.0.0.0:8002->8000/tcp
mysite_db docker-entrypoint.sh mysqld up 0.0.0.0:3306->3306/tcp, 33060/tcp再打開瀏覽器看看,是否正常啟動(dòng)了。
后記
docker-compose 還有更多的用法,我會(huì)在以后的項(xiàng)目中做些其他方向的更深入的介紹。謝謝大家賞光看我的作品,希望你幫到你一點(diǎn)。
參考文檔
get docker ce for ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/
install docker compose:https://docs.docker.com/compose/install/