咱們所在的內網環境須要部署一個相似CMS的應用,就是一些表格的CRUD,數據導出,人員權限管理等功能。想到Django作這方面的工做挺擅長的,並且開發量不大,因而選擇Django做爲開發基礎。開發功能比較簡單,差很少就是使用xadmin等插件實現以上功能。但有一個問題咱們是很差繞過去的,那就是部署到一個內網環境,在內網pip等工具是不能使用的,但好在內網有一個yum服務器可使用,因此咱們決定在內網服務器上安裝Docker,而後把開發環境的容器複製到生產環境實現部署。如下是主要的步驟:python
注意:我這裏的開發環境是Ubuntu18.04,生產環境是Centos7.2。若是你是其餘環境請本身檢查差別,使用適合本身系統的命令。mysql
Docker 和 Docker-compose是咱們此次部署須要重點演示的內容,Django 的應用部分我會盡可能縮減的。Docker 負責容器虛擬化的底層部分,Docker-compose 是一個容器編排工具,有了它我們就不用手寫 shell 實現容器之間的鏈接了。咱們先安裝 Docker-ce,這裏主要是參考 Docker 的官方文檔,若是我寫的不夠詳細或者已通過時,各位看官可到官方查看更權威更新的文檔。linux
在安裝以前須要卸載舊版本的 docker,若是你是新系統,能夠忽略這一步。git
$ sudo apt remove docker docker-engine docker.io containerd runc
複製代碼
$ sudo apt update
複製代碼
$ sudo apt install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
複製代碼
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
複製代碼
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
複製代碼
作好以上的準備後安裝Docker-ce就簡單了,熟悉Ubuntu的話,很快就能裝好。github
$ sudo apt update
$ sudo apt install -y docker-ce
複製代碼
安裝完成後,啓動 docker 服務並使其可以在每次系統引導時啓動。web
$ sudo systemctl start docker
$ sudo systemctl enable docker
複製代碼
Docker-ce安裝完成後,Docker-compose就好辦了。若是你是在Linux等平臺上直接下載Docker-compose的編譯好的二進制文件便可使用。sql
$ 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
複製代碼
下載完成後修改權限加上可執行docker
$ sudo chmod +x /usr/local/bin/docker-compose
複製代碼
最後可執行一下查看Docker-compose的版本號驗證一下是否成功安裝shell
$ docker-compose --version
docker-compose version 1.24.0-rc1, build 0f3d4dda
複製代碼
這裏的開發環境是Django的環境,演示的項目爲了方便演示我儘可能使用一個新建的Django項目。數據庫
新建一個Django項目,先建立一個上層文件夾來把項目文件放到這個文件夾中。目錄結構大體以下:
--project
--Dockerfile
--docker-compose.yml
--mysite
--manage.py
--requirements.txt
複製代碼
先建立project文件夾
$ mkdir project
複製代碼
而後新建Django項目,或者你也能夠把已有的項目拷貝過來。
$ django-admin.py startproject mysite
複製代碼
上一步已經有了一個叫mysite的Django項目,假設咱們把requirements.txt放到這個文件夾下,內容大體以下:
$ 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
複製代碼
固然這是個人項目須要的依賴,你的依賴可能和個人不同。
項目有了,項目的依賴文件也有了,下一步就是建立咱們的Django項目的運行環境的docker鏡像了,先建一個Dockerfile來構建docker鏡像。 在project文件夾新建Dockerfile,內容以下:
$ cat Dockerfile
複製代碼
FROM 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
複製代碼
我簡單解釋一下這個文件
FROM python:3.6.8
複製代碼
這裏我使用的基礎鏡像是python:3.6.8,它的基礎鏡像是Ubuntu我比較熟悉,若是你對alpine比較熟悉的話也可使用alpine,那個鏡像要小的多。
ENV PYTHONUNBUFFERED 1
複製代碼
你可使用 Env 關鍵字建立任意的操做系統的環境變量
ENV PYTHONUNBUFFERED 1
複製代碼
例如,若是你使用它來存儲你的 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就是在容器裏面運行命令,這裏RUN命令建立了兩個文件夾/config和/src,以及安裝Python的依賴環境。
RUN mkdir /config
RUN mkdir /src
RUN pip install -r /config/requirements.txt
複製代碼
ADD
ADD /mysite/requirements.txt /config/
複製代碼
增長本地的文件到容器中 WORKDIR
WORKDIR /src/mysite
複製代碼
是指定後面全部在容器裏運行命令的默認路徑,要運行的命令在稍後的docker-compose文件這種能夠看到。
docker-compose能夠用來管理多個容器,之前手動加海量參數運行容器並鏈接容器的活均可以讓docker-compose來作了。個人docker-compose.yml內容大體以下:
$ cat docker-compose.yml
複製代碼
version: '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
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']
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"
複製代碼
再簡單解釋一下這個docker-compose文件吧。
version: '3'
複製代碼
指的是docker-compose的版本,不一樣版本支持的配置項目稍有不一樣。 services 管理的服務,咱們的例子中是兩個服務:db和web。兩個服務中的配置項目我分開解釋一下 db:
image 直接使用docker hub或者本地的已有鏡像,這個使用的是MySQL5.7 container_name 指定容器的名稱 ports 指定容器對宿主機的端口映射,前面的是宿主機端口,後面的是容器端口 environment 指定當前服務運行時候的環境,環境的細節參考當前鏡像的說明,那上面說支持哪些,咱們就能夠配置哪些。這個案例中咱們指定了MySQL的root密碼、默認數據庫和數據庫的字符集。 command 容器啓動後的命令,這裏加入了mysql默認字符集的參數 web: build 編譯鏡像,這裏是使用當前文件夾下的Dockerfile command 容器啓動後執行的命令 depends_on 當前容器要依賴的服務,也就是說必須依賴中的服務成功啓動當前服務才能啓動 volumes 當前容器要掛載的卷,前面指的是宿主機的目錄,後面是容器目錄 restart 指定容器的重啓策略,當前案例是若是出錯就一直重啓。 這裏把容器的8000端口映射到宿主機的8002端口,web服務就是從8002端口訪問。
如今針對當前的容器環境修改一下mysite項目的settings.py文件。
$ vim mysite/mysite/settings.py
複製代碼
找到文件中的ALLOW_HOSTS部分,添加「web」到其中,內容以下:
ALLOW_HOSTS = [
...
'web'
]
複製代碼
而後修改settings.py中的DATABASES部分,把參數改成MySQL服務db的參數,內容大體以下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysite',
'USER': 'root',
'PASSWORD': 'mysite',
'HOST': 'db'
}
}
複製代碼
這裏的MySQL鏈接參數都是docker-compose.yml文件中db部分的environment中定義的。值得指出的是參數HOST值爲db,docker-compose啓動容器後,會鏈接這些容器,容器之間可使用服務名稱互相ping通,就像使用域名那樣,因此這裏的「HOST」可直接填寫「db」。
通過以上的努力,基本準備齊備了,咱們能夠構造咱們的鏡像了,這裏有兩個服務,db只須要在運行的時候下載或者使用本地鏡像就行,web還須要使用Dockerfile構建一下。
$ docker-compose build
複製代碼
通過一陣兒下載或者構建,就能看到成功構建鏡像的信息了。
構建完成後,就有了web服務的鏡像了,咱們如今使用docker-compose來啓動服務。
$ docker-compose up -d
複製代碼
這個過程可能也須要執行一陣兒,取決於你的網速,它會下載MySQL的鏡像,而且根據db和web的鏡像構造容器,並運行容器。完成後可使用docker-compose ps和docker-compose images來查看咱們生成的容器和鏡像
$ docker-compose ps
複製代碼
Name 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 images
複製代碼
Container Repository Tag Image Id Size
--------------------------------------------------------
mysite_db mysql 5.7 e47e309f72c8 355 MB
mysite_web mysite_web latest 3989acbcc3c9 938 MB
複製代碼
也可以使用docker-compose來中止和開始服務,其餘更具體的使用方法,請參考官方文檔吧。
$ docker-compose start
Starting db ... done
Starting web ... done
複製代碼
$ docker-compose stop
Stopping mysite_web ... done
Stopping mysite_db ... done
複製代碼
你看這裏的服務中止和啓動的順序都是有規律的啓動的時候被依賴的服務先啓動而後啓動依賴它的服務,挺值服務的時候恰好相反。待服務正常運行後,能夠訪問瀏覽器測試一下服務是否正常啓動。
若是服務一切正常,咱們就要把當前的容器保存起來,爲部署到新平臺上作準備。注意: 這裏要使用save保存鏡像,使用save是包括容器之間的鏈接狀態等信息的,若是用export導出鏡像到生產環境是不能使用docker-compose恢復服務的。
$ docker save -o mysql.tar mysql:5.7
$ docker save -o mysite.tar mysite_web:latest
複製代碼
當以上命令執行成功後會在當前目錄生成兩個tar文件,再加上project目錄的Dockerfile和docker-compose.yml文件放在一塊兒準備遷移到生產機器上。
因爲生產環境是CentOS,能夠直接使用yum安裝
$ sudo yum install docker-ce
複製代碼
安裝成功後,參考開發環境把docker-compose部署到生產服務器上。
使用scp或者其餘工具把mysql.tar、mysite.tar、Docker-compose.yml以及項目文件夾發送到生產服務器,並找一個合適的文件夾存放這些文件,保持原來的目錄結構。 咱們先把兩個鏡像恢復到生產服務器上
$ docker load -i mysql.tar
$ docker load -i mysite_web.tar
複製代碼
等待一小會兒執行完成,能夠看到當前服務器已經有這兩個鏡像了。
REPOSITORY TAG IMAGE ID CREATED SIZE
mysite_web latest 3989acbcc3c9 2 days ago 983MB
mysql 5.7 e47e309f72c8 3 weeks ago 372MB
複製代碼
在執行構建容器之前咱們還要對docker-compose.yml作個簡單的修改。你也注意到,生產服務器沒有互聯網,因此不能再build鏡像了,並且咱們還把開發環境的鏡像原樣照搬了過來,因此此次web服務改成從鏡像運行就好了,內容大體以下:
version: '3'
services:
db:
...
web:
image: mysite_web:latest
...
複製代碼
只要更改web中的build項刪除,並加上一個image項,內容就是咱們拷貝過來的那個鏡像。稍後咱們就能夠構建容器並啓動服務了。
$ docker-compose up -d
複製代碼
結果
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
複製代碼
再打開瀏覽器看看,是否正常啓動了。
docker-compose 還有更多的用法,我會在之後的項目中作些其餘方向的更深刻的介紹。謝謝你們賞光看個人做品,但願你幫到你一點。