從docker到docker-compose部署一個nginx+flask+mysql+redis應用
目的是把一個flask專案的mysql資料庫、redis資料庫、flask應用、nginx服務分別裝到四個容器中,然後用docker-compose命令同時啟動與關閉
一、安裝docker
Docker 執行在 CentOS 7 上,要求系統為64位、系統核心版本為 3.10 以上。通過 uname -r 命令檢視當前的核心版本
更新yum
sudo yum update
移除舊版本
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
安裝系統工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
新增軟體源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum快取
sudo yum makecache fast
安裝docker-ce,對所有選項選y
sudo yum -y install docker-ce
檢視docker版本
docker --version
啟動docker
sudo systemctl start docker
二、只用docker部署
注意區分:docker映象是一個模版,docker容器是一個例項,它可以被啟動與關閉。
1、首先先把mysql和redis資料庫跑起來
拉映象
docker pull mysql docker pull redis:3.2
執行,redis並不需要把埠暴露出來,因為只有flask應用需要訪問它,直接在啟動flask應用容器的時候link到redis就可以了
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=*** -d mysql docker run--name redis -d redis:3.2 redis-server --appendonly yes
2、部署flask應用
一開始我直接拉了一個centos映象,然後再裝python3、requirement.txt,但是後來發現直接用python:3.6的映象會簡單一點。
首先,把專案複製到伺服器
scp -r 本地資料夾 [email protected]伺服器公網ip:伺服器目標資料夾
然後,建立一個Dockerfile,用於將應用build成映象
目錄結構如下
Dockerfile的內容
FROM python:3.6 ADD ./my-chat-server /app WORKDIR /app RUN pip install -r requirement.txt CMD ["python", "run.py"]
RUN與CMD的區別在於,RUN是在建立映象的時候執行的,而CMD在這個映象建立的容器每次啟動時都會執行
ADD與COPY的區別在於,ADD可以寫成 ADD http://foo.com/bar.go /tmp/main.go 或
ADD /foo.tar.gz /tmp/ 用於下載一個檔案到容器中或者將一個壓縮檔案解壓到容器中。
然後,在flask目錄執行
docker build -t flask .
這會建立一個名為flask的映象
然後啟動這個映象
docker run --name flask -p 5000:5000 --link mysql:mysql --link redis:redis-server -d flask
注意應用中mysql和redis的host都要相應改變,改成資料庫容器在flask容器中的別名
--link 容器名:容器別名 可以實現容器間的通訊
如無意外現在可以從伺服器的5000埠訪問到flask應用了
3、部署nginx
先拉一個映象
docker pull nginx
然後啟動
docker run --name nginx -p 80:80 -d nginx
將裡面的nginx.conf檔案內容拿出來
docker exec -it nginx cat /etc/nginx/nginx.conf
然後建立一個nginx.conf,把這些內容複製進去,在http里加上
server { listen 80; server_name 伺服器公網ip; location / { proxy_pass http://flask:5000; } access_log /var/log/access_unicom.log main; }
然後把剛創的nginx映象刪掉,注意刪除容器是docker rm;刪除映象是docker rmi
建立一個以剛才建立的nginx.conf為配置的nginx容器
docker run --name nginx -p 80:80 -v /root/nginx.conf:/etc/nginx/nginx.conf --link flask -d nginx
現在通過伺服器的80埠就可以訪問到flask應用了
只使用docker的部署完成,下面我們來用docker-compose實現更方便的部署
三、docker-compose部署
docker-compose可以很方便地通過一個檔案構建多個映象、啟動多個容器。
安裝docker-compose(最新版
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
要使用docker-compose,首先要把每個部分的Dockerfile寫好,然後在docker-compose.yml檔案中統一構建和啟動
整個docker-compose專案的目錄結構為
三個目錄下分別有它們的Dockerfile和相關的配置檔案或程式碼
flask目錄的目錄結構和Dockerfile和之前是一樣的
mysql的Dockerfile
FROM mysql COPY ./init.sql /docker-entrypoint-initdb.d
init.sql是資料庫初始化檔案,它會把flask應用需要用到的庫和表創建出來。在mysql官方映象中提供了容器啟動時自動執行/docker-entrypoint-initdb.d
資料夾下的指令碼的功能(包括shell指令碼和sql指令碼) 。因此我們只要把初始化檔案在映象啟動時複製到/docker-entrypoint-initdb.d
資料夾就可以了
nginx的Dockerfile
FROM nginx COPY ./nginx.conf /etc/nginx/nginx.conf
在之前,我使用掛載的方式將nginx.conf匯入nginx容器,這個方法有一個問題就是如果我要把這一套生產環境打包到另一個系統,docker export並不會將掛載的內容一起打包,因此,最好還是在構建映象的時候就把相關配置加到映象裡。
redis沒有需要匯入的配置,因此沒有它的Dockerfile
docker-compose.yml檔案的內容
version: '3' services: mysql: build: ./mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=*** restart: always redis: image: redis:3.2 restart: always flask: build: ./flask ports: - "5000:5000" links: - mysql:mysql - redis:redis-server restart: always nginx: build: ./nginx ports: - "80:80" links: - flask
docker-compose會先從每個服務的build目錄下找到Dockerfile,然後依次映象。所有映象建立完畢後,再根據yml檔案中其他配置依次啟動映象的容器。
當docker-compose啟動一次後,只要不更改它自動生成的容器和映象,再次啟動,它就不會再建立映象,而是啟動之前生成的容器。
如果想要更改單個服務的內容,修改Dockerfile的內容、或者刪除docker-compose自動生成的容器和映象,再次啟動docker-compose的時候,它會重新構建修改後服務的容器,而其他沒有做過修改的服務不變
執行docker-compose up啟動所有服務
你的應用已經可以在80埠訪問了,enjoy!