第15章 項目部署-Docker
Docker技術能夠避免部署對服務器環境的依賴,減少復雜的部署流程。
輕松部署各種常見軟件、Java項目
參考文檔:???????????????????第十五章:項目部署(Docker) - 飛書云文檔
15.1 Docker安裝
15.1.1 卸載舊版
首先如果系統中已經存在舊的Docker,則先卸載:
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine \docker-selinux
15.1.2 配置Docker的yum庫
首先要安裝一個yum工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
安裝成功后,執行命令,配置Docker的yum源(已更新為阿里云源):
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo ? sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
更新yum,建立緩存
sudo yum makecache fast
15.1.3 安裝Docker
最后,執行命令,安裝Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
15.1.4 啟動和校驗
# 啟動Docker systemctl start docker ? # 停止Docker systemctl stop docker ? # 重啟 systemctl restart docker ? # 設置開機自啟 systemctl enable docker ? # 執行docker ps命令,如果不報錯,說明安裝啟動成功 docker ps
15.1.5 配置鏡像加速
鏡像地址可能會變更,如果失效可以百度找最新的docker鏡像。
配置鏡像步驟如下:
# 創建目錄 rm -f /etc/docker/daemon.json ? # 復制內容 tee /etc/docker/daemon.json <<-'EOF' {"registry-mirrors": ["http://hub-mirror.c.163.com","https://mirrors.tuna.tsinghua.edu.cn","http://mirrors.sohu.com","https://ustc-edu-cn.mirror.aliyuncs.com","https://ccr.ccs.tencentyun.com","https://docker.m.daocloud.io","https://docker.awsl9527.cn"] } EOF ? # 重新加載配置 systemctl daemon-reload ? # 重啟Docker systemctl restart docker
15.2 部署-MySQL
傳統方式部署MySQL,大概的步驟有:
-
搜索并下載MySQL安裝包
-
上傳至Linux環境
-
解壓和配置環境
-
安裝
-
初始化和配置
而使用Docker安裝,僅僅需要一步即可,在命令行輸入下面的命令(建議采用CV大法):
docker run -d \--name mysql \-p 3307:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \mysql:8
如果沒有 mysql:8 鏡像會先下載鏡像image,再部署這個取名叫mysql的容器container
因此,Docker安裝軟件的過程,就是自動搜索下載鏡像,然后創建并運行容器的過程。
運行效果如圖(在給大家提供的資料中,已經下載好了mysql 8版本的鏡像):
MySQL安裝完畢!通過任意客戶端工具即可連接到MySQL。
15.3 docker命令解析
docker run
運行流程如下:
Docker鏡像交流的社區:https://hub.docker.com
利用Docker快速的安裝了MySQL,非常的方便,不過我們執行的命令到底是什么意思呢?
docker run -d \--name mysql \-p 3307:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \mysql:8
解讀:
-
docker run -d
:創建并運行一個容器,-d
則是讓容器以后臺進程運行 -
--name mysql
: 給容器起個名字叫mysql
,你可以叫別的 -
-p 3307:3306
: 設置端口映射。-
容器是隔離環境,外界不可訪問。但是可以將宿主機端口映射容器內到端口,當訪問宿主機指定端口時,就是在訪問容器內的端口了。
-
容器內端口往往是由容器內的進程決定,例如MySQL進程默認端口是3306,因此容器內端口一定是3306;而宿主機端口則可以任意指定,一般與容器內保持一致。
-
格式:
-p 宿主機端口:容器內端口
,示例中就是將宿主機的3307映射到容器內的3306端口
-
-
-e TZ=Asia/Shanghai
: 配置容器內進程運行時的一些參數-
格式:
-e KEY=VALUE
,KEY和VALUE都由容器內進程決定 -
案例中,
TZ=Asia/Shanghai
是設置時區;MYSQL_ROOT_PASSWORD=123
是設置MySQL默認密碼
-
-
mysql:8
: 設置鏡像名稱,Docker會根據這個名字搜索并下載鏡像-
格式:
REPOSITORY:TAG
,例如mysql:8.0
,其中REPOSITORY
可以理解為鏡像名,TAG
是版本號 -
在未指定
TAG
的情況下,默認是最新版本,也就是mysql:latest
-
15.4 docker常見命令
常見的命令有:
命令 | 說明 | 文檔地址 |
---|---|---|
docker pull | 拉取鏡像 | docker pull |
docker push | 推送鏡像 | docker push |
docker images | 查看本地鏡像 | docker images |
docker rmi | 刪除本地鏡像 | docker rmi |
docker run | 創建并運行容器 | docker run |
docker stop | 停止指定容器 | docker stop |
docker start | 啟動指定容器 | docker start |
docker restart | 重新啟動容器 | docker restart |
docker rm | 刪除指定容器 | docs.docker.com |
docker ps [-a] | 查看容器 | docker ps |
docker logs | 查看容器運行日志 | docker logs |
docker exec -it [containerName] bash | 進入容器 | docker exec |
docker save | 保存鏡像到本地壓縮文件 | docker save |
docker load | 加載本地壓縮文件到鏡像 | docker load |
docker inspect | 查看容器詳細信息 | docker inspect |
用一副圖來表示這些命令的關系:
補充:
默認情況下,每次重啟虛擬機我們都需要手動啟動Docker和Docker中的容器。通過命令可以實現開機自啟:
# Docker開機自啟 systemctl enable docker# Docker容器開機自啟 docker update --restart=always [容器名/容器id]
用Nginx為例給大家演示命令。
# 第1步,去DockerHub查看nginx鏡像倉庫及相關信息# 第2步,拉取Nginx鏡像 (比較耗時) docker pull nginx:1.20.2# 第3步,查看鏡像 docker images# 第4步,創建并允許Nginx容器 docker run -d --name nginx -p 80:80 nginx# 第5步,查看運行中容器 docker ps# 也可以加格式化方式訪問,格式會更加清爽 docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"# 第6步,訪問網頁,地址:http://虛擬機地址# 第7步,停止容器 docker stop nginx# 第8步,查看所有容器 docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"# 第9步,再次啟動nginx容器 docker start nginx# 第10步,再次查看容器 docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"# 第11步,查看容器詳細信息 docker inspect nginx# 第12步,進入容器,查看容器內目錄 docker exec -it nginx bash# 或者,可以進入MySQL docker exec -it mysql mysql -uroot -p# 第13步,刪除容器 docker rm nginx# 發現無法刪除,因為容器運行中,強制刪除容器 docker rm -f nginx
15.5 數據卷
數據卷(volume)是一個虛擬目錄,是容器內目錄與宿主機目錄之間映射的橋梁。
以Nginx為例,我們知道Nginx中有兩個關鍵的目錄:
-
html
:放置一些靜態資源 -
conf
:放置配置文件
我們可以配置這兩個關鍵目錄的數據卷。
數據卷的相關命令有:
命令 | 說明 | 文檔地址 |
---|---|---|
docker volume create | 創建數據卷 | docker volume create |
docker volume ls | 查看所有數據卷 | docs.docker.com |
docker volume rm | 刪除指定數據卷 | docs.docker.com |
docker volume inspect | 查看某個數據卷的詳情 | docs.docker.com |
docker volume prune | 清除數據卷 | docker volume prune |
注意:容器與數據卷的掛載要在創建容器時配置,對于創建好的容器,是不能設置數據卷的。而且創建容器的過程中,數據卷會自動創建。
教學演示環節:演示一下nginx的html目錄掛載
# 1.首先創建容器并指定數據卷,注意通過 -v 參數來指定數據卷 docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx:1.20.2# 2.然后查看數據卷 docker volume ls# 3.查看數據卷詳情 docker volume inspect html# 4.查看/var/lib/docker/volumes/html/_data目錄 ll /var/lib/docker/volumes/html/_data# 5.進入該目錄,并隨意修改index.html內容 cd /var/lib/docker/volumes/html/_data vi index.html# 6.打開頁面,查看效果# 7.進入容器內部,查看/usr/share/nginx/html目錄內的文件是否變化 docker exec -it nginx bash
數據卷的默認目錄是比較深的,在更多情況下,我們會直接將容器目錄與宿主機指定目錄掛載。
-v mysql:/var/lib/mysql # 會被識別為一個數據卷叫mysql,運行時會自動創建這個數據卷-v ./mysql:/var/lib/mysql # 會被識別為當前目錄下的mysql目錄,運行時如果不存在會創建目錄注意:本地目錄或文件必須以
/
或./
開頭,如果直接以名字開頭,會被識別為數據卷名而非本地目錄名。
15.6 自定義鏡像
鏡像中包含了程序運行需要的系統函數庫、環境、配置、依賴。
因此,自定義鏡像本質就是依次準備好程序運行的基礎環境、依賴、應用本身、運行配置等文件,并且打包而成。
所以鏡像就是一堆文件的集合。
15.6.1 Dockerfile
Dockerfile記錄了鏡像結構。
常用的指令:
指令 | 說明 | 示例 |
---|---|---|
FROM | 指定基礎鏡像 | FROM centos:7 |
ENV | 設置環境變量,可在后面指令使用 | ENV key value |
COPY | 拷貝本地文件到鏡像的指定目錄 | COPY ./xx.jar /tmp/app.jar |
RUN | 執行Linux的shell命令,一般是安裝過程的命令 | RUN yum install gcc |
EXPOSE | 指定容器運行時監聽的端口,是給鏡像使用者看的 | EXPOSE 8080 |
ENTRYPOINT | 鏡像中應用的啟動命令,容器運行時調用 | ENTRYPOINT java -jar xx.jar |
例如,要基于 centos:7 鏡像來構建一個Java應用,其Dockerfile內容如下:
# 使用 CentOS 7 作為基礎鏡像 FROM centos:7# 添加 JDK 到鏡像中 COPY jdk17.tar.gz /usr/local/ RUN tar -xzf /usr/local/jdk17.tar.gz -C /usr/local/ && rm /usr/local/jdk17.tar.gz# 設置環境變量 ENV JAVA_HOME=/usr/local/jdk-17.0.10 ENV PATH=$JAVA_HOME/bin:$PATH# 創建應用目錄 RUN mkdir -p /app WORKDIR /app# 復制應用 JAR 文件到容器 COPY app.jar app.jar# 暴露端口 EXPOSE 8080# 運行命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]
Dockerfile文件編寫好了之后,就可以使用如下命令來構建鏡像了。
docker build -t 鏡像名 .
-
-t :是給鏡像起名,格式依然是repository:tag的格式,不指定tag時,默認為latest
-
. :是指定Dockerfile所在目錄,如果就在當前目錄,則指定為"."
15.7 docker網絡
每一個容器再被創建出來都會被分配一個虛擬的IP地址,可以通過命令查看:
# 1.用基本命令,尋找Networks.bridge.IPAddress屬性 docker inspect mysql# 也可以使用format過濾結果 docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
容器網絡相關的常見命令有:
命令 | 說明 |
---|---|
docker network create | 創建一個網絡 |
docker network ls | 查看所有網絡 |
docker network rm | 刪除指定網絡 |
docker network prune | 清除未使用的網絡 |
docker network connect | 使指定容器連接加入某網絡 |
docker network disconnect | 使指定容器連接離開某網絡 |
docker network inspect | 查看網絡詳細信息 |
教學演示:自定義網絡
# 1.首先通過命令創建一個網絡 docker network create itheima# 2.然后查看網絡 docker network ls# 結果: NETWORK ID NAME DRIVER SCOPE 639bc44d0a87 bridge bridge local 403f16ec62a2 itheima bridge local 0dc0f72a0fbb host host local cd8d3e8df47b none null local # 其中,除了itheima以外,其它都是默認的網絡# 3.讓 myapp 和 mysql 都加入該網絡 # 3.1.mysql容器,加入 itheima 網絡 docker network connect itheima mysql# 3.2.myapp容器,也就是我們的java項目, 加入 itheima 網絡 docker network connect itheima myapp# 4.進入dd容器,嘗試利用別名訪問db # 4.1.進入容器 docker exec -it myapp bash# 4.2.用容器名訪問 ping mysql# 結果: PING mysql (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql.itheima (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms 64 bytes from mysql.itheima (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
也可以在docker run時用--network參數配置該容器的虛擬網絡。
15.8 部署-Java項目
需求:將我們開發的 tlias-web-management 項目打包為鏡像,并部署。
步驟:
-
修改項目的配置文件,修改數據庫服務地址(打包package)。
-
在logback.xml中修改lombok日志文件的文件輸出路徑
-
在application.properties文件中修改數據庫信息
-
-
編寫Dockerfile文件(AI輔助)。
Dockerfile(文件名):
# 使用 CentOS 7 作為基礎鏡像 FROM centos:7# 添加 JDK 到鏡像中 COPY jdk17.tar.gz /usr/local/ RUN tar -xzf /usr/local/jdk17.tar.gz -C /usr/local/ && rm /usr/local/jdk17.tar.gz# 設置環境變量 ENV JAVA_HOME=/usr/local/jdk-17.0.10 ENV PATH=$JAVA_HOME/bin:$PATH# 阿里云OSS環境變量 ENV OSS_ACCESS_KEY_ID=LTAI5tP6dc4cvccdvvySE39X ENV OSS_ACCESS_KEY_SECRET=ZSyIT31qhxIkS0dH1H9WzHqPiyM3Ot#統一編碼 ENV LANG=en_US.UTF-8 ENV LANGUAGE=en_US:en ENV LC_ALL=en_US.UTF-8# 創建應用目錄 RUN mkdir -p /tlias WORKDIR /tlias# 復制應用 JAR 文件到容器 COPY tlias.jar tlias.jar# 暴露端口 EXPOSE 8080# 運行命令 ENTRYPOINT ["java","-jar","/tlias/tlias.jar"]
-
構建Docker鏡像,部署Docker容器,運行測試。
-
除了Dockerfile文件外。
-
依賴基礎鏡像Linux
-
依賴jdk鏡像,將例如jdk17.tar.gz放到文件中。
-
構建Docker鏡像
docker build -t tlias:1.0 .
-
部署Docker容器
docker run -d --name tlias-server --network itheima -p 8080:8080 tlias:1.0
-
通過 docker logs -f 容器名
,就可以查看容器的運行日志。
這樣后端服務,就已經啟動起來了。
15.9 部署-Nginx前端
需求:創建一個新的nginx容器,將資料中提供的前端項目的靜態資源部署到nginx中。
步驟:
-
在宿主機上準備靜態文件及配置文件存放目錄(在
/usr/local
目錄下創建tlias-web
目錄)。-
-v /usr/local/tlias-web/html:/usr/share/nginx/html
-
-v /usr/local/tlias-web/conf/nginx.conf:/etc/nginx/nginx.conf
-
-
部署nginx容器
docker run -d \ --name nginx-tlias \ -v /usr/local/tlias-web/html:/usr/share/nginx/html \ -v /usr/local/tlias-web/conf/nginx.conf:/etc/nginx/nginx.conf \ --network itheima \ -p 80:80 \ nginx:1.20.2
15.10 DockerCompose自動部署
手動的逐一部署,太麻煩了。
而Docker Compose就可以幫助我們實現多個相互關聯的Docker容器的快速部署。
用戶通過一個單獨的 docker-compose.yml 模板文件定義一組相關聯的應用容器。
舉例來說,用docker run部署MySQL的命令如下:
docker run -d \ --name nginx-tlias \ -p 80:80 \ -v /usr/local/app/html:/usr/share/nginx/html \ -v /usr/local/app/conf/nginx.conf:/etc/nginx/nginx.conf \ --network itheima \ nginx:1.20.2
如果用docker-compose.yml
文件來定義,就是這樣:
services:mysql:image: "nginx:1.20.2"container_name: nginx-tliasports:- "80:80"volumes:- "/usr/local/app/html:/usr/share/nginx/html"- "/usr/local/app/conf/nginx.conf:/etc/nginx/nginx.conf"networks:- itheima networks:itheima:name: itheima
對比如下:
docker run 參數 | docker compose 指令 | 說明 |
---|---|---|
--name | container_name | 容器名稱 |
-p | ports | 端口映射 |
-e | environment | 環境變量 |
-v | volumes | 數據卷配置 |
--network | networks | 網絡 |
明白了其中的對應關系,相信編寫docker-compose
文件應該難不倒大家。
services:mysql:image: mysql:8container_name: mysqlports:- "3307:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- "/usr/local/app/mysql/conf:/etc/mysql/conf.d"- "/usr/local/app/mysql/data:/var/lib/mysql"- "/usr/local/app/mysql/init:/docker-entrypoint-initdb.d"networks:- tlias-nettlias:build: context: .dockerfile: Dockerfilecontainer_name: tlias-serverports:- "8080:8080"networks:- tlias-netdepends_on:- mysqlnginx:image: nginx:1.20.2container_name: nginxports:- "80:80"volumes:- "/usr/local/app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf"- "/usr/local/app/nginx/html:/usr/share/nginx/html"depends_on:- tliasnetworks:- tlias-net networks:tlias-net:name: itheima
編寫好docker-compose.yml文件,就可以部署項目了。語法如下:
docker compose [OPTIONS] [COMMAND]
其中,OPTIONS和COMMAND都是可選參數,比較常見的有:
類型 | 參數或指令 | 說明 |
---|---|---|
Options | -f | 指定compose文件的路徑和名稱 |
-p | 指定project名稱。project就是當前compose文件中設置的多個service的集合,是邏輯概念 | |
Commands | up | 創建并啟動所有service容器 |
down | 停止并移除所有容器、網絡 | |
ps | 列出所有啟動的容器 | |
logs | 查看指定容器的日志 | |
stop | 停止容器 | |
start | 啟動容器 | |
restart | 重啟容器 | |
top | 查看運行的進程 | |
exec | 在指定的運行中容器中執行命令 |
例如:基于DockerCompose部署項目
docker compose up -d