docker是當下很熱門的技術,是對以前的部署系統方式的完全改變。以前部署系統,須要安裝數據庫、初始化數據庫,安裝jdk,配置jdk,部署應用程序,修改配置文件等,很繁瑣。通常現場運維人員很難搞定,現場也會出現不少公司開發環境沒有的問題。使用docker技術,只須要運行鏡像便可,省去了環境安裝、變量配置等繁瑣的事情,現場運維人員通過簡單培訓後能夠獨立部署系統。移植性好,公司開發環境直接能夠部署到現場。css
使用docker技術,主要有兩個個關鍵步驟:一、構建鏡像 二、運行鏡像。構建鏡像,須要將基礎支持軟件、業務系統打成鏡像包。運行鏡像,須要將構建的鏡像運行起來,外部能夠訪問。html
docker鏡像能夠理解爲一個高度內聚的應用包,包含運行環境、配置等,能夠移植到各個環境中運行。例如一個java應用鏡像,運行這個鏡像只須要準備一臺Linux服務器,服務器上不須要裝任何jdk,只須要安裝docker,就能夠運行該鏡像。省去了常規的安裝運行環境,配置環境變量,啓動各類服務等各類繁瑣步驟。前端
對於一個信息系統,鏡像通常包括:java
1. mariadb鏡像:包含數據庫安裝文件和業務數據庫。數據庫安裝文件,是數據庫基礎支持軟件。業務數據庫是業務系統須要的數據庫,業務系統須要提供初始化腳本。mysql
2. nginx鏡像:包含nginx基礎鏡像和業務前端代碼。nginx基礎鏡像是nginx運行軟件。做爲先後端分離的項目,nginx中存放前端靜態頁面。nginx
3. java鏡像:包含jdk和業務應用程序。jdk是java應用運行基礎環境。業務應用是後端系統,向前端提供展現數據。web
以上是信息系統一種部署方式,另外能夠將基礎鏡像和初始化鏡像分開,例如mariadb鏡像能夠分爲mariadb安裝鏡像和業務系統初始化鏡像。spring
先在本地環境安裝docker,docker中配置倉庫地址,指明瞭鏡像存放路徑,例如tim:5000,同時須要在hosts中配置tim的映射。sql
在系統的hosts文件中配置映射127.0.0.1 timdocker
一、 準備業務系統初始化腳本。
二、 修改數據庫配置文件等
須要準備的文件以下:
utf8mb4.cnf 修改數據庫編碼字符集爲utf8格式,解決中文漢字亂碼問題。
run.txt 運行鏡像命令。構建鏡像非必需文件,這裏只是記錄運行命令。
blog.sql 初始化腳本。業務系統的初始化鏡像,包含建庫腳本、建表腳本、初始化數據腳本等。
Dockerfile 生成鏡像說明文檔。說明鏡像如何生成,已經運行時執行的命令。
install_data.sh 數據庫啓動後執行的腳本。由於mariadb鏡像須要在鏡像運行後,初始化業務系統數據庫,須要該腳本執行業務系統初始化腳本。
Makefile 執行make命令後,執行的鏡像生成命令。通常是移除上次的鏡像,再生成新的鏡像。
重點是Dockerfile文件,內容以下:
#基礎鏡像使用daocloud.io/library/mysql:8,新構建的鏡像以此鏡像爲基礎 FROM daocloud.io/library/mysql:8 #定義工做目錄變量 ENV WORK_PATH /usr/local/work #定義會被容器自動執行的目錄 ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d #定義sql文件名,這裏指向業務系統初始化腳本 ENV FILE_0 blog.sql #定義shell文件名,指向待指向的shell腳本 ENV INSTALL_DATA_SHELL install_data.sh #執行shell命令,建立文件夾 RUN mkdir -p $WORK_PATH #把數據庫初始化數據的文件複製到工做目錄下 COPY ./$FILE_0 $WORK_PATH/ #把要執行的shell文件放到/docker-entrypoint-initdb.d/目錄下,高版本mysql容器會自動執行這個shell(5.7.4不能執行) COPY ./$INSTALL_DATA_SHELL $AUTO_RUN_DIR/ #mysql默認字符集是latain,而它是不支持中文的,utf8mb4 是 utf8 的超集並徹底兼容utf8。修改字符集 COPY utf8mb4.cnf /etc/mysql/conf.d/ #給執行文件增長可執行權限 RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DATA_SHELL
install_data.sh文件主要是鏡像在運行後,自動執行的命令,主要是登陸到已經啓動的mysql鏡像中,執行初始化腳本。內容以下:
#!/bin/bash mysql -uroot -p$MYSQL_ROOT_PASSWORD <<EOF source $WORK_PATH/$FILE_0;
utf8mb4.cnf內容以下:
# 設置服務器、客戶端編碼格式 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE # 忽略客戶端的字符集,使用服務器的設置 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
Makefile包含兩個命令,也能夠拿出來單獨執行,內容以下:
build-image: docker rmi tim:5000/blog-mariadb:dev-test docker build -t tim:5000/blog-mariadb:dev-test .
生成鏡像:
經過命令進入到鏡像生成命令中,執行make命令,或者拷貝Makefile文件中內容執行也能夠。例:
docker run --name mysql-blog -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d tim:5000/blog-mariadb:dev-test
--name mysql-blog 取名爲mysql-blog
-p 3306:3306 將容器的3306端口暴露到宿主機中,外部能夠經過3306訪問容器,如同訪問本機上的數據庫同樣
-e MYSQL_ROOT_PASSWORD=root 數據庫密碼爲root
-d 之後臺進程方式運行
tim:5000/blog-mariadb:dev-test 運行的鏡像
須要準備的文件以下:
static是開發的業務系統前端靜態頁面,先後端分離的,因此這裏是html、css、js之類的文件。
Dockerfile文件內容:
# 使用的基礎鏡像,這個是nginx運行軟件 FROM hub.c.163.com/library/nginx # 將業務系統靜態頁面拷貝到nginx的頁面目錄中,static會自動建立 COPY static/ /usr/share/nginx/html/static/ # 將blog站點nginx配置文件拷貝到nginx站點配置文件中,能夠拷貝多個,端口不一樣便可 COPY blog.conf /etc/nginx/conf.d/
blog.conf是nginx配置,內容以下:
# nginx支持配置多個站點,配置文件拷貝到/etc/nginx/conf.d下便可 server { listen 9001; # 監聽的端口 server_name localhost; # 服務器名稱 location / { # 靜態頁面拷貝到這裏來 root /usr/share/nginx/html/static; index index.html; # 跨域 if ($request_method ~* "(GET|POST|DELETE|PUT)") { add_header "Access-Control-Allow-Origin" *; } if ($request_method = OPTIONS ) { add_header "Access-Control-Allow-Origin" *; add_header "Access-Control-Allow-Methods" 'GET, POST, PUT, DELETE, OPTIONS'; add_header "Access-Control-Allow-Headers" 'Authorization,Content-Type'; return 200; } } }
一樣,進入到該目錄中,執行make命令。
運行命令:
docker run --name blog-web -d -p 8080:9001 tim:5000/blog-web:dev-test
blog站點nginx配置文件監聽端口是9001,暴露出來,外部能夠經過8080端口訪問系統。
須要準備的文件以下:
Dockerfile:生成鏡像的命令,指明瞭基礎鏡像來源,鏡像中包含的文件,鏡像運行的命令等。
下面兩個文件是java應用須要的文件,application.properties將應用的參數拿出來,能夠進行修改,運行時會覆蓋應用中的配置文件,不須要修改應用內部的配置文件,再從新生成jar包。
重點看下Dockerfile文件
# java應用須要java支持,先使用hub.c.163.com/library/java:8做爲基礎鏡像 FROM hub.c.163.com/library/java:8 # 運行的環境變量 ENV TZ Asia/Shanghai ENV LANG zh_CN.UTF-8 ENV LANGUAGE zh_CN:zh ENV LC_ALL zh_CN.UTF-8 # 工做目錄 WORKDIR /opt/project # 將文件加到鏡像中的目錄中。application.properties是配置文件,再也不須要進入jar包中修改配置。blog-1.0-SNAPSHOT.jar是業務應用運行jar ADD application.properties /opt/project/config/application.properties ADD blog-1.0-SNAPSHOT.jar /opt/project/ # 鏡像運行後執行的命令 CMD ["java", "-jar", "blog-1.0-SNAPSHOT.jar"]
生成鏡像:
進入到鏡像製做目錄中,執行命令: docker build -t tim:5000/tim-blog:dev-test . 或者執行make命令。
查看鏡像是否生成成功
docker images
運行鏡像
docker run -p 9091:9091 --link mysql-blog:mysql-blog --name blog tim:5000/blog:dev-test
將端口映射到9091。同時連接到mysql-blog數據庫,注意這裏是數據庫鏡像運行時的名稱,鏈接mysql:mysql(容器名:別名),應用名稱爲blog。
域名需使用鏈接的容器的別名(即上述所提的mysql-blog:mysql-blog中的第二個mysql-blog),例如應用中數據庫鏈接字符串寫法以下:
spring.datasource.url=jdbc:mysql://mysql-blog:3306/blog?useUnicode=true&characterEncoding=utf-8
查看容器運行狀況:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9f1a03cf3555 tim:5000/blog-web:dev-test "nginx -g 'daemon ..." 45 seconds ago Up 50 seconds 80/tcp, 0.0.0.0:8080->9001/tcp blog-web aec1c87b63ed tim:5000/blog:dev-test "java -jar blog-1...." 55 seconds ago Up About a minute 0.0.0.0:9091->9091/tcp blog 0c5dcc8543ca tim:5000/blog-mariadb:dev-test "docker-entrypoint..." About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp mysql-blog
這樣系統須要的3個鏡像就運行起來了,在瀏覽器經過8080端口就能訪問系統。
附docker經常使用命令:
docker images 查看全部鏡像
docker ps -a 查看全部容器
docker stop containerID 中止容器
docker rm containerID 移除容器
docker rmi imagesID 移除鏡像
docker exec -it containerId /bin/bash 進入到容器內部
看以上的運行過程,須要輸入三次命令,依次啓動數據庫、後端、nginx,命令中指明瞭端口、容器間的依賴等,很繁瑣。其實,這3個鏡像是構成這個項目不可分割的部分,相互之間有依賴,並且有前後啓動順序。就是說應該當成一個總體來看待。
docker-compose就誕生了。
docker-compose是一組組合命令,融合了鏡像生成和鏡像運行等一些列命令,用於須要使用多個鏡像才能使一個項目運行起來的狀況,例如web應用,須要數據庫、nginx、後端等服務,使用docker-compose組合這些鏡像,快速啓動項目。再也不須要依次輸入docker run命令啓動各個鏡像。甚至不須要依次構建各個鏡像。
下面以已經存在鏡像爲例,講解如何使用docker-compose。
一、首先編寫Dockfile,生成鏡像。
這一步上面已經講解過。須要手動依次調用docker build命令,獲得須要的3個鏡像,固然能夠在docker-compose中生成,不須要依次調用。可是按照通常的思路,先是有鏡像,而後纔是鏡像之間的組合,造成一個完整的項目。
二、編寫docker-compose.yml文件
主要包括兩部分:version、services。
services中就包括須要的3個鏡像,能夠看到services中各個服務其實就是docker run中的各個參數。
version: "3" services: mysql-blog: # 容器別名 image: tim:5000/blog-mariadb:dev-test # 使用的鏡像 volumes: - /opt/mysql/data:/var/lib/mysql # 掛載目錄,將容器內部的目錄掛載到外部宿主機上 ports: - 3306:3306 # 端口映射 restart: always environment: # 數據庫密碼 MYSQL_ROOT_PASSWORD: root blog: depends_on: - mysql-blog # 依賴mysql-blog,這個服務要求先運行 image: tim:5000/blog:dev-test links: - mysql-blog # 連接到數據庫,這裏使用數據庫容器的別名 ports: - 9091:9091 restart: always blog-web: depends_on: - blog image: tim:5000/blog-web:dev-test ports: - 8080:9001 restart: always
三、啓動
進入到docker-compose.yml目錄,運行:
docker-compose up -d
再使用docker ps -a 能夠看到services中的3個容器都運行起來了。
- 中止docker-compose down