CentOS上Docker部署Django項目記錄

概念

Docker 使用 Google 公司推出的 Go 語言進行開發實現(k8s也是Go語言),基於 Linux 內核的cgroup,namespace,以及 AUFS 類的 Union FS 等技術,對進程進行封裝隔離,屬於操作系統層面的虛擬化技術。由於隔離的進程獨立於宿主和其它的隔離的進程,因此也稱其爲容器。最初實現是基於 LXC,從 0.7 版本以後開始去除 LXC,轉而使用自行開發的 libcontainer,從 1.11 開始,則進一步演進爲使用 runC 和 containerd

docker應該是目前最流行的容器解決方案,它的思想來源於集裝箱,集裝箱的作用是什麼?封存、隔離貨物。我們把海鮮和水果分別裝在不同的集裝箱裏,由同一艘大船去運輸。這是不是要比分兩艘船來的方便、快捷、高效呢。舉例:公司的開發環境和生產環境不一致,開發出來的程序在開發人員本地能運行,上了生產卻運行不了。你懂得,這個時候就要開始甩鍋了。這中情況如果用docker就不一樣了,我們直接把開發環境build成一個鏡像,然後由運維去把這個docker鏡像部署上就OK了。環境一毛一樣

如下圖所示,運行一個容器的過程:

  • 去registry中拉取鏡像,如果本地已經存在,則直接使用本地鏡像
  • 根據鏡像創建容器
  • 給容器分配文件系統,並在最上層掛載一個可讀寫層。
  • 分配網絡接口,創建一個允許容器和宿主機訪問得網絡接口
  • 運行指定的程序
  • 收集容器的運行狀態

docker,最核心的是理解三個概念,分別是:倉庫(Registry)、鏡像(image)和容器(Container)

docker-io, docker-engin

是以前早期的版本,版本號是 1.x,默認centos7 安裝的是docker-io,最新版是 1.13

docker-ce

是社區版本,適用於剛剛開始docker 和開發基於docker研發的應用開發者或者小型團隊。Ubuntu默認安裝的是docker-ce

docker-ee

是docker的企業版,適用於企業級開發,同樣也適用於開發、分發和運行商務級別的應用的IT 團隊

安裝

Docker手冊

Docker 要求 CentOS 系統的內核版本高於 3.10 ,驗證你的CentOS 版本是否支持 Docker

uname -a
[root@VM_0_14_centos ~]# uname -a
Linux VM_0_14_centos 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

CentOS 7,正好可以支持

安裝命令

yum install docker-ce -y
[root@VM_0_14_centos ~]# yum install docker-ce -y
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
...   
No package docker-ce available.
Error: Nothing to do

需要先安裝yum源

# 安裝需要的軟件包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的

yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置Docker的yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

[root@VM_0_14_centos ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror, langpacks
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo

可以查看所有倉庫中所有docker版本,並選擇特定版本安裝

yum list docker-ce --showduplicates | sort -r

選擇下載最新版本

yum install docker-ce-19.03.5 -y

安裝成功

常用命令

啓動Docker

systemctl start docker

加入開機啓動

systemctl enable docker

查看版本,驗證是否安裝成功(有client和service兩部分表示docker安裝啓動都成功了)

docker version
[root@VM_0_14_centos ~]# docker version 
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
...

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
...

查看Docker的使用信息

docker info

搜索鏡像

docker search images_name

# NAME列:沒有斜線分隔的名字稱爲頂級倉庫,一般屬於docker hub官方所有;有斜線分隔符的稱爲用戶倉庫或者是項目倉庫,docker hub官方允許用戶個人註冊賬戶建立自己的倉庫。
# DESCRIPTION列:倉庫描述
# STARS列:用戶表示“贊”的個數 

下載鏡像

docker pull images_name

查看當前鏡像列表

docker images 

更多命令,參考:這裏

docker ps                       : 查看當前正在運行的容器
docker ps -a                    : 查看所有容器的狀態
docker start/stop id/name       : 啓動/停止某個容器
docker attach id                : 進入某個容器(使用exit退出後容器也跟着停止運行)
docker exec -ti id              : 啓動一個僞終端以交互式的方式進入某個容器(使用exit退出後容器不停止運行)
docker rm id/name               : 刪除某個容器
docker rmi id/name              : 刪除某個鏡像

# 複製ubuntu容器並且重命名爲test且運行,然後以僞終端交互式方式進入容器,運行bash
docker run --name test -ti ubuntu /bin/bash  

# 通過當前目錄下的Dockerfile創建一個名爲soar/centos:7.1的鏡像
docker build -t soar/centos:7.1 .  

# 以鏡像soar/centos:7.1創建名爲test的容器
# 並以後臺模式運行,並做端口映射到宿主機2222端口,P參數重啓容器宿主機端口會發生改變
docker run -d -p 2222:22 --name test soar/centos:7.1  

容器管理

命令幫助

docker run --help

-d                   # 後臺運行容器.
-i                   # 使用交互式訪問容器.
-t                   # 分配一個終端,需要與-i結合使用.
--name               # 給容器分配個名字.
--network string     # 使容器加入到一個網絡,如不指定,默認就是加到bridge網絡(可以使用docker network ls查看),使用docker0的虛擬網卡.
--rm                 # 容器一停,就自動刪除.

直接創建、啓動並登入容器(啓動容器的鏡像可以不用提前下載,執行run命令的時候會自動下載)

docker run --name bbox -it busybox:latest

啓動一個容器:

# 如果容器是一個後臺守護進程,那直接start就可以了,如果需要直接進入交互式接口,需要加-ai的參數
docker start -ai bbox 

停止一個容器:

# stop和kill區別就是:stop是發送15的信號,kill是發送9的信號。kill是強制殺死,有丟失數據的可能,所以一般不建議使用。
docker stop bbox

刪除一個容器:

docker rm bbox 

啓動一個後臺運行的容器:

docker run --name web01 -d nginx:1.14-alpine 

docker ps -a

docker inspect web01 | grep IPAddress

登入後臺運行的容器:

docker exec -it web01 /bin/bash

查看容器訪問日誌:

# 一般情況下容器只會運行程序這一個進程,日誌都是保存在於宿主機上的,可以用下面命令查看。
docker logs web01 

Django鏡像

所謂倉庫,其實是個鏡像倉庫,裏面有很多別人已經打包好的鏡像,可以直接使用docker,pull命令將倉庫中的鏡像拉到本地,默認的倉庫Docker的官方倉庫Docker Hub Registry

因爲牆的緣故,官方倉庫的速度會比較慢,可以配一個官方的中國加速鏡像,方法是:修改/etc/docker/daemon.json,加上如下的鍵值:

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

之後重啓docker服務即可生效

基於Python3容器製作新的Django鏡像

Python鏡像

在這裏找到想要下載的鏡像

# 下載
docker pull python:3.6.10-alpine

# 後臺運行
docker run --name django_v1 -itd python:3.6.10-alpine

# 登錄容器
docker exec -it django_v1 sh

# 退出
exit

這裏如果用/bin/bash會報錯:

[root@VM_0_14_centos ~]# docker exec -it django_v1 /bin/bash
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown

因爲:

我們一般可能會在容器啓動後進入容器,常用的是docker attach 鏡像id,但是啓動鏡像的時候如果沒有帶 參數 -it的話,attach進去後可能是日誌界面,並不能執行命令。所以我們會用docker exec -it 鏡像id /bin/bash/

平常的容器一般都可以執行/bin/bash,但是alpine沒有,改成docker exec -it 鏡像id sh就好了

進入容器後安裝其他依賴

cd ~

mkdir .pip

vi .pip/pip.conf

# 添加
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
# 添加爲信任的host
[install]
trusted-host = mirrors.aliyun.com

# 保存
# 安裝yum
wget http://yum.baseurl.org/download/3.2/yum-3.2.28.tar.gz
tar xvf yum-3.2.28.tar.gz

...

pip3 install django==2.2.7
pip3 install uwsgi

# 通過yum安裝nginx
yum install nginx -y

# 創建軟連接
ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi
ln -s /usr/local/python3/bin/django-admin.py /usr/bin/django-admin

這就有點麻煩,這個容器中很多Linux命令都沒有,需要你自己手動安裝很多東西,所以暫時不考慮這種方式

基於Dockerfile製作Django鏡像

在需要部署的Django項目的根目錄下,添加三個文件Dockerfilerequirements.txtpip conf

FROM python:3.6 這裏指定 Python 版本爲目前穩定的 python3.6

FROM python:3.6
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY pip.conf /root/.pip/pip.conf
COPY requirements.txt /usr/src/app/
RUN pip install -r /usr/src/app/requirements.txt
RUN rm -rf /usr/src/app
COPY . /usr/src/app
CMD [ "python3", "./manage.py", "runserver", "0.0.0.0:8089"]

使用鏡像 pip install 相關依賴

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
extra-index-url= https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=
	mirrors.aliyun.com
	pypi.tuna.tsinghua.edu.cn

通過這個命令即可生成requirements.txt

pip3 freeze > requirements.txt
...

同樣在Django根目錄下,也就是Dockerfile文件所在的目錄

docker build -t my_django:v1.0 .

其中-t my_django:v1.0表示打包的鏡像名爲my_django,tag爲v1.0,前面說過,tag是可以任意命名的,不一定要是這種格式,注意命令的最後有一個.,這個表示打包的上下文(其實就是Dockerfile所在目錄)是在當前目錄,然後目錄下的Dockerfile就會被編譯執行

執行完畢後運行docker images就會發現多了一個my_django鏡像

若build過慢,我的是騰訊雲下使用的centos7服務器,可以

# 使用騰訊雲dockerhub加速器
# 創建或修改 /etc/docker/daemon.json 文件,並添加如下:

{
   "registry-mirrors": [
       "https://mirror.ccs.tencentyun.com"
  ]
}

依次執行以下命令,重新啓動 Docker 服務

systemctl daemon-reload
systemctl restart docker

執行docker info命令,返回結果中包含以下內容,則說明配置加速成功

Registry Mirrors:
 https://mirror.ccs.tencentyun.com

生成鏡像成功

...

 ---> ec6c706a5f6e
Step 7/9 : RUN rm -rf /usr/src/app
 ---> Running in 318cc576230f
Removing intermediate container 318cc576230f
 ---> 21b97e82ebf7
Step 8/9 : COPY . /usr/src/app
 ---> 793452ffa1d7
Step 9/9 : CMD [ "python3", "./manage.py", "runserver", "0.0.0.0:8089"]
 ---> Running in a3448d5b9541
Removing intermediate container a3448d5b9541
 ---> f5bb78cebbc8
Successfully built f5bb78cebbc8
Successfully tagged my_django:v1.0

開啓容器

這裏的8089由上面的Dockerfile決定
這裏的 xxx.xxx.xxx.xxx 爲自己服務器公網IP地址

# http://xxx.xxx.xxx.xxx:8089
docker run -it --rm -p 8089:8089 --name django_v1 my_django:v1.0
# 或者 http://xxx.xxx.xxx.xxx:8000(端口號隨意映射,但要注意開啓對應安全組)
docker run -it --rm -p 8000:8089 --name django_v1 my_django:v1.0

結果報mysqlclient的錯:

...mysqlclient 1.3.13 or newer is required; you have 0.7.11.None

因爲是容器中的文件問題,所以只好到容器中修改

# 後臺運行
docker run --name django_v1 -d my_django:v1.0
# 登錄容器
docker exec -it django_v1 sh

find / -name base.py

# 因爲沒有vim以及vi,所以得安裝,時間有點久
apt-get update
apt-get install vim

vim /usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py

修改如下,這兩行註釋掉:

# if version < (1, 3, 3):
#     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

然後exit

爲了區別,並重新運行添加端口,commit一個新的my_django鏡像

# docker commit containerID/name images
docker commit -a 'joel' django_v1 my_django:v2.0

現在又多了一個鏡像

[root@VM_0_14_centos LVideo]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my_django           v2.0                82eb6e8ad0cc        3 minutes ago       1.08GB
my_django           v1.0                f5bb78cebbc8        About an hour ago   1.03GB
python              3.6                 62f74e9ce5f1        6 days ago          914MB

我們可以將鏡像提交到docker hub

註冊hub.docker.com的賬號,點擊"Repositories"菜單,然後點擊"Create Repository +"來創建一個倉庫,創建完成後瀏覽器的窗口不要關閉

docker login -u joelying
Password: 
Login Succeeded
# 驗證成功,開始進行push操作,此處加了tag,如果不加tag,就是將此鏡像的所有版本都push上去
docker push joelying/my_django:v2.0

若出現

denied: requested access to the resource is denied

實際上是因爲在將鏡像push到自己新建的賬戶之前,要用docker tag重命名一下,將鏡像命名你的用戶名/鏡像名這種形式,不然會push認證不通過,如:

[root@VM_0_14_centos LVideo]# docker tag my_django:v2.0 joelying/my_django:v2.0 

[root@VM_0_14_centos LVideo]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
joelying/my_django   v2.0                82eb6e8ad0cc        15 minutes ago      1.08GB
my_django            v2.0                82eb6e8ad0cc        15 minutes ago      1.08GB
...

# 注意時間很久
[root@VM_0_14_centos LVideo]# docker push joelying/my_django:v2.0

這下就push成功

參考

* Centos7下安裝Docker(詳細的新手裝逼教程)
Centos6.5下安裝docker+升級內核+禁用selinux
* Docker與Dockerfile極簡入門文檔(一目瞭然)
* docker(三):docker鏡像管理
* 編寫Dockerfile與項目實踐+各類項目dockerfile編寫
* docker版Django
* Python3.6 使用 Docker 快速部署 Django2.0 項目到阿里雲服務器上
包含鏡像分享至docker hub
Docker:發佈自己鏡像問題denied: requested access to the resource is denied解決方法
linux python3換pip 源
linux下yum安裝的最簡方法
linux如何安裝yum

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章