目录
Blue留言机:
学习视频以及参考资料 :
1、学习之前的必备操作:
第一步:购买服务器
选择一台免费的云服务器(包白嫖的)
配置服务器的一点说明:
查看自己是否购买成功:
第一种查看方式:
第二种查看方式:
第二步:对服务器配置做点更改
第三步:下载xshell
第四步:使用xshell
第五步:下载XFTP
第六步:设置xshell常用快捷键:cv
1、打开Xshell找到工具
2、找到选项并打开
3、点击鼠标与键盘
4、点击编辑
5、点击查找
6、输入组合键(直接按就行)
7、类型选择菜单 菜单往下选
8、其余同理,然后点击确定,保存这样你就拥有你的CV了 .
2、安装docker
2.1、前提工作:
第一步:删除docker
第二步:配置yum工具
第三步:安装成功后,执行命令,配置Docker的yum源(已更新为阿里云源):
第四步:更新yum,建立缓存
2.2、开始安装:
2.3、启动和校检docker
2.4、配置镜像加速
2.4.1、注册阿里云账号
2.4.2、开通镜像服务
2.4.3、配置镜像加速
3、部署
3.1、部署mysql
3.2、利用mysql的可视化工具来连接
3.3、部署nginx
4、docker知识点
4.1、命令解读
4.2、镜像命名规范
4.3、常见命令
4.4、数据卷挂载
4.4.1、引言:
4.4.2、什么是数据卷?
4.4.3、数据卷命令
4.4.4、演示一下nginx的html目录挂载
4.5、挂载本地目录或文件
4.5.1、基础概念
4.5.2、案例:
第一步:删除原来的mysql容器
第二步:在宿主机建立三个文件夹,命名为data、init、conf,并且其位置是在/root/mysql。
第三步:挂载本地目录
第四步:检查
4.6、自定义镜像
4.6.1、必看知识前景
4.6.2、dockerfile语法
4.6.3、实战制作自定义镜像(两种方式)
准备一个jar包拿来测试(前提)
简单方式制作镜像
前提需要
制作镜像
第二种制作自定义镜像
4.7、容器网络
4.7.1、问题引入概念
4.7.2、测试各容器是否可以互相访问
4.7.3、docker的网络功能
4.7.4、常见命令有:
4.7.4、自定义网络:
5、项目部署
5.1、部署java应用
5.2、部署前端
结言:
Blue留言机:
好久不见啊!各位看客老爷们,距离我上一篇非水文已经将近一个多月了。
嘿嘿~,有点忙,而且还不知道写什么,巴拉巴拉。好了回归正题,本篇文章,俺Blue将会从三个方面:
- 学习docker部署项目前的必备操作(不限于购买服务器、快捷键设置)
- docker基础知识
- 实战去部署项目
手把手的去教会各位部署项目,保证各位观众老爷们一定可以学会的。加油加油!废话不多说,和我一起开始学习之旅吧!👊👊👊
学习视频以及参考资料 :
学习视频:http://【黑马程序员Docker快速入门到项目部署,MySQL部署+Nginx部署+docker自定义镜像+DockerCompose项目实战一套搞定】https://www.bilibili.com/video/BV1HP4118797?p=9&vd_source=bb412cc25ca27e171f8e17085daad038
资料参考:
http://t.csdnimg.cn/QpAMD
http://t.csdnimg.cn/2EoT8
1、学习之前的必备操作:
本篇文章是结合云服务器和docker的,所以你需要一个cenos7的云服务器:
那么如何去选择云服务器呢?或者如何去购买呢?作为小白文,接下来我将手把手教会你去购买服务器。
第一步:购买服务器
现在的云服务器平台提供了很多可以免费拿来试用的云服务器
腾讯云最新活动腾讯云促销优惠代金券-腾讯云官网入口 (tencent.com)
以腾讯云为例子:
选择一台免费的云服务器(包白嫖的)
配置服务器的一点说明:
实际上:我推荐centos7的系统
查看自己是否购买成功:
第一种查看方式:
第二种查看方式:
第二步:对服务器配置做点更改
点击重置密码:
第三步:下载xshell
下载链接:XSHELL - NetSarang Website
使用免费版本:
下载:
第四步:使用xshell
点击:
填写主机ip:
该ip在:
填写服务器账号和密码
点击确认后:
第五步:下载XFTP
同xshell
第六步:设置xshell常用快捷键:cv
1、打开Xshell找到工具
2、找到选项并打开
3、点击鼠标与键盘
4、点击编辑
5、点击查找
6、输入组合键(直接按就行)
7、类型选择菜单 菜单往下选
8、其余同理,然后点击确定,保存这样你就拥有你的CV了 .
2、安装docker
2.1、前提工作:
第一步:删除docker
安装之前我们先卸载一下以防自己有docker,但是自己不知道。
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-selinux
第二步:配置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
2.2、开始安装:
执行命令,安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
出现这个就可以了
验证一下是否安装上了输入一下命令:
docker -v
ok了老铁!!
当然docker是一个服务,自然是要启动的,所以宝子们,接下来我们来启动docker
2.3、启动和校检docker
# 启动Docker
systemctl start docker
# 停止Docker
systemctl stop docker
# 重启
systemctl restart docker
# 设置开机自启
systemctl enable docker
# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps
2.4、配置镜像加速
这里以阿里云镜像加速为例。
2.4.1、注册阿里云账号
首先访问阿里云网站:
阿里云-计算,为了无法计算的价值
注册一个账号。
2.4.2、开通镜像服务
在首页的产品中,找到阿里云的容器镜像服务:
点击后进入控制台:
2.4.3、配置镜像加速
找到镜像工具下的镜像加速器:
页面向下滚动,即可找到配置的文档说明:
具体命令如下:
# 创建目录
mkdir -p /etc/docker
# 复制内容,注意把其中的镜像加速地址改成你自己的
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
# 重新加载配置
systemctl daemon-reload
# 重启Docker
systemctl restart docker
3、部署
3.1、部署mysql
直接代码cv:
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
当然这个时候你会发现有这样一个错误:
docker: error pulling image configuration: download failed after attempts=6: dial tcp 128.242.240.93:443: i/o timeout.
原因就不说了,自己问ai吧,解决很简单。
- 输入下面命令
vi /etc/docker/daemon.json
- 用下面的内容覆盖原有的内容,如果原来没有内容就直接加进去
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.jianmuhub.com",
"https://huecker.io",
"https://dockerhub.timeweb.cloud",
"https://dockerhub1.beget.com",
"https://noohub.ru"
]
}
i
建切换输入模式,删除掉之前的全部内容,将上面代码cv进去,然后按esc
,再按:wq!
这几个键就好了。
-
重启daemon
systemctl daemon-reload
-
重启docker
systemctl restart docker
在执行原来的代码就好了。
现在我们利用mysql的可视化工具来连接一下吧!
3.2、利用mysql的可视化工具来连接
我们先让服务器对mysql的端口地址开放
开始连接
成功:
3.3、部署nginx
非常简单,我们先去pull别人的镜像:
#默认最新版本
docker pull nginx
拉去到本地镜像后我们给做成容器:
docker run -d --name nginx -p 80:80 nginx
然后看看好了没,输入服务器ip地址带端口
4、docker知识点
那么这里就产生了一些我的项目,既然我们docker在安装应用是下载应用镜像的,那么最开始的
docker images
该指令就应该可以看所谓的镜像里面有那些应用了。
很显然我的想法是对了,那么怎么指定版本了?我们留个悬念,慢慢看。
4.1、命令解读
我们来看之前的代码:
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
为了便于理解:我们先简单的看一下大概
以下为具体的解读:
解读:
docker run -d
:创建并运行一个容器,-d
则是让容器以后台进程运行
--name mysql
: 给容器起个名字叫mysql
,你可以叫别的
-p 3306:3306
: 设置端口映射。
容器是隔离环境,外界不可访问。但是可以将宿主机端口映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。
容器内端口往往是由容器内的进程决定,例如MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。
格式:
-p 宿主机端口:容器内端口
,示例中就是将宿主机的3306映射到容器内的3306端口
-e TZ=Asia/Shanghai
: 配置容器内进程运行时的一些参数
格式:
-e KEY=VALUE
,KEY和VALUE都由容器内进程决定案例中,
TZ=Asia/Shanghai
是设置时区;MYSQL_ROOT_PASSWORD=123
是设置MySQL默认密码
mysql
: 设置镜像名称,Docker会根据这个名字搜索并下载镜像
格式:
REPOSITORY:TAG
,例如mysql:8.0
,其中REPOSITORY
可以理解为镜像名,TAG
是版本号在未指定
TAG
的情况下,默认是最新版本,也就是mysql:latest
镜像的名称不是随意的,而是要到DockerRegistry中寻找,镜像运行时的配置也不是随意的,要参考镜像的帮助文档,这些在DockerHub网站或者软件的官方网站中都能找到。
如果我们要安装其它软件,也可以到DockerRegistry中寻找对应的镜像名称和版本,阅读相关配置即可。
4.2、镜像命名规范
在镜像与容器我们留了个悬念,如何指定应用程序的版本?接下来这一节我们来解决这个问题。
完整的镜像名称是两部分的及以下写法:
[repository] :tag
其中repository也就是镜像名,也是前面代码的Mysql而tag是镜像的版本
注意:在没有指定版本的也就是tag时,默认是最新(latest)
4.3、常见命令
先看一张图:
对照图片:
命令 | 说明 | 文档地址 |
---|---|---|
docker pull | 拉取镜像 | docker pull |
docker push | 推送镜像到DockerRegistry | 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 | 查看容器 | docker ps |
docker logs | 查看容器运行日志 | docker logs |
docker exec | 进入容器 | 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]
4.4、数据卷挂载
4.4.1、引言:
容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题:
-
如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了?
-
MySQL、Nginx容器运行后,如果我要修改其中的某些配置该怎么办?
-
我想要让Nginx代理我的静态资源怎么办?
因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦。
4.4.2、什么是数据卷?
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
以Nginx为例,我们知道Nginx中有两个关键的目录:
-
html
:放置一些静态资源 -
conf
:放置配置文件
如果我们要让Nginx代理我们的静态资源,最好是放到html
目录;如果我们要修改Nginx的配置,最好是找到conf
下的nginx.conf
文件。
但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:
在上图中:
-
我们创建了两个数据卷:
conf
、html
-
Nginx容器内部的
conf
目录和html
目录分别与两个数据卷关联。 -
而数据卷conf和html分别指向了宿主机的
/var/lib/docker/volumes/conf/_data
目录和/var/lib/docker/volumes/html/_data
目录
这样以来,容器内的conf
和html
目录就 与宿主机的conf
和html
目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data
就是在操作容器内的/usr/share/nginx/html/_data
目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。
小提示:
/var/lib/docker/volumes
这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data
。
小提示:
/var/lib/docker/volumes
这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data
。
为什么不让容器目录直接指向宿主机目录呢?
-
因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。
-
但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。
不过,我们通过由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷。
4.4.3、数据卷命令
命令 | 说明 | 文档地址 |
---|---|---|
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 |
注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。
4.4.4、演示一下nginx的html目录挂载
# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER VOLUME NAME
local 29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local html
# 3.查看数据卷详情
docker volume inspect html
# 结果
[
{
"CreatedAt": "2024-05-17T19:57:08+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/html/_data",
"Name": "html",
"Options": null,
"Scope": "local"
}
]
# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html
# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html
# 6.打开页面,查看效果
# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash
4.5、挂载本地目录或文件
4.5.1、基础概念
可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件
注意:本地目录或文件必须以 /
或 ./
开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。
例如:
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
4.5.2、案例:
第一步:删除原来的mysql容器
第二步:在宿主机建立三个文件夹,命名为data、init、conf,并且其位置是在/root/mysql。
-
先创建mysql文件夹
-
在刚创建mysql文件夹下创建data、init、conf文件夹
tips:如果不会liunx指令怎么办?不要急小伙伴,xftp可以可视化的。
妈妈再也不用担心我不会操作centos系统了!!
第三步:挂载本地目录
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
mysql
第四步:检查
在mysql的可视化连接器如:datagrip、navicat 去连接云服务器上的3306端口,在会话中写这个代码
show variables like "%char%";
出现这个说明本地挂载成功!!
4.6、自定义镜像
4.6.1、必看知识前景
在来自定义镜像前,先提问,什么是镜像?
Docker镜像是一个轻量级、可执行的独立软件包,包含运行某个软件所需的所有代码、库、依赖项和配置文件。镜像是Docker容器的基础,容器是镜像的运行实例。
镜像的特点包括:
可移植性:镜像可以在任何支持Docker的环境中运行,无论是本地开发环境、测试环境还是生产环境。
版本控制:镜像可以被标记和版本化,方便管理和回滚。
分层结构:镜像采用分层文件系统,允许多个镜像共享相同的基础层,从而节省存储空间。
不可变性:一旦创建,镜像的内容不会改变,任何修改都会生成新的镜像。
通过Docker镜像,开发者可以轻松地打包和分发应用程序,确保在不同环境中具有一致的运行效果。
那么镜像的层次结构是什么?
镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。
因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。
举个例子,我们要从0部署一个Java应用,大概流程是这样:
-
准备一个linux服务(CentOS或者Ubuntu均可)
-
安装并配置JDK
-
上传Jar包
-
运行jar包
那因此,我们打包镜像也是分成这么几步:
-
准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
-
安装并配置JDK
-
拷贝jar包
-
配置启动脚本
上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合。
但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。
例如,第一步中需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:
4.6.2、dockerfile语法
由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。
而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档:
https://docs.docker.com/engine/reference/builder/
其中的语法比较多,比较常用的有:
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像 | FROM centos:6 |
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 |
4.6.3、实战制作自定义镜像(两种方式)
准备一个jar包拿来测试(前提)
在这里我写了一个接口返回“成功”这个字符串:
接口没问题
进入maven里面,执行clean与package
执行成功:
简单方式制作镜像
防止我先教难的,会被骂。这里我先起手简单的制作自定义镜像
前提需要
以下为Dockerfile的内容:
# 基础镜像
FROM openjdk:17
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY testwufu.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
注意:我的jdk是17,打包的jar包叫testwufu.jar,这两个地方请按照你自己的来
-
划重点:Dockerfile文件的命名一定要叫Dockerfile
我的demo文件是以下两个东西,我将该文件夹上传到云服务上面去
上传成功
制作镜像
先cd进demo文件里面
执行命令:
cd demo
注意:demo文件在root文件下
切换进demo文件内:
执行打包成镜像的代码:
docker build -t docker-demo .
现在打包成镜像了,我们该将其镜像弄成容器
docker run -d --name dd -p 8081:8081 docker-demo
打印一下后台日志
docker logs -f dd
再测试一下,能不能访问
注意:你需要去开放你的服务器8081端口
第二种制作自定义镜像
4.7、容器网络
4.7.1、问题引入概念
最开始我们在谈论docker容器的时候不是说,它是隔离的环境吗?那我们自定义的镜像做出来的java项目容器怎么去访问访问其它各种中间件,例如MySQL、Redis等?现在,我们的容器之间能否互相访问呢?ping一下试试。
4.7.2、测试各容器是否可以互相访问
首先,我们查看下MySQL容器的详细信息,重点关注其中的网络IP地址:
# 1.用基本命令,寻找Networks.bridge.IPAddress属性
docker inspect mysql
# 也可以使用format过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
# 得到IP地址如下:
172.17.0.2
# 2.然后通过命令进入dd容器
docker exec -it dd bash
# 3.在容器内,通过ping命令测试网络
ping 172.17.0.2
# 结果
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.058 ms
发现可以互联,没有问题。哇有点神奇,明明是独立的容器为啥可以联通呢?我们来看看下面这张图。
解释:
我们发现虽然我们创造的容器是相互独立的,但他们可以通过ip地址来进行通信的话,不过有个问题,一旦有容器重启,重启的容器将不再能被访问到。容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。
所以,我们必须借助于docker的网络功能来解决这个问题。
官方文档:
https://docs.docker.com/engine/reference/commandline/network/
4.7.3、docker的网络功能
Docker 网络主要有以下两个作用:
-
容器间的互联和通信以及端口映射
-
容器IP变动时候可以通过服务名直接网络通信而不受到影响
因此只要是处于同一个Docker 网络下的容器就可以使用服务名进行直接访问,而无需担心重启。
这也是Docker 网络最基本和常用的应用场景。
4.7.4、常见命令有:
命令 | 说明 | 文档地址 |
---|---|---|
docker network create | 创建一个网络 | docker network create |
docker network ls | 查看所有网络 | docs.docker.com |
docker network rm | 删除指定网络 | docs.docker.com |
docker network prune | 清除未使用的网络 | docs.docker.com |
docker network connect | 使指定容器连接加入某网络 | docs.docker.com |
docker network disconnect | 使指定容器连接离开某网络 | docker network disconnect |
docker network inspect | 查看网络详细信息 | docker network inspect |
4.7.4、自定义网络:
# 1.首先通过命令创建一个网络
docker network create hmall
# 2.然后查看网络
docker network ls
# 结果:
NETWORK ID NAME DRIVER SCOPE
639bc44d0a87 bridge bridge local
403f16ec62a2 hmall bridge local
0dc0f72a0fbb host host local
cd8d3e8df47b none null local
# 其中,除了hmall以外,其它都是默认的网络
# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!
# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect hmall mysql --alias db
# 3.2.dd容器,也就是我们的java项目
docker network connect hmall dd
# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash
# 4.2.用db别名访问
ping db
# 结果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms
# 4.3.用容器名访问
ping mysql
# 结果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
5、项目部署
5.1、部署java应用
hmall
项目是一个maven聚合项目,使用IDEA打开hmall
项目,查看项目结构如图:
我们要部署的就是其中的hm-service
,其中的配置文件采用了多环境的方式:
其中的application-dev.yaml
是部署到开发环境的配置,application-local.yaml
是本地运行时的配置。
查看application.yaml,你会发现其中的JDBC地址并未写死,而是读取变量:
这两个变量在application-dev.yaml
和application-local.yaml
中并不相同:
在dev开发环境(也就是Docker部署时)采用了mysql作为地址,刚好是我们的mysql容器名,只要两者在一个网络,就一定能互相访问。
我们将项目打包:
结果:
将hm-service
目录下的Dockerfile
和hm-service/target
目录下的hm-service.jar
一起上传到虚拟机的root
目录:
部署项目:
# 1.构建项目镜像,不指定tag,则默认为latest
docker build -t hmall .
# 2.查看镜像
docker images
# 结果
REPOSITORY TAG IMAGE ID CREATED SIZE
hmall latest 0bb07b2c34b9 43 seconds ago 362MB
docker-demo 1.0 49743484da68 24 hours ago 327MB
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
# 3.创建并运行容器,并通过--network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name hmall --network hmall -p 8080:8080 hmall
测试,通过浏览器访问:http://你的云服务器:8080/search/list
5.2、部署前端
hmall-portal
和hmall-admin
是前端代码,需要基于nginx部署。在课前资料中已经给大家提供了nginx的部署目录:
其中:
-
html
是静态资源目录,我们需要把hmall-portal
以及hmall-admin
都复制进去 -
nginx.conf
是nginx的配置文件,主要是完成对html
下的两个静态资源目录做代理
我们现在要做的就是把整个nginx目录上传到虚拟机的/root
目录下:
然后创建nginx容器并完成两个挂载:
-
把
/root/nginx/nginx.conf
挂载到/etc/nginx/ng``inx.conf
-
把
/root/nginx/html
挂载到/usr/share/nginx/html
由于需要让nginx同时代理hmall-portal和hmall-admin两套前端资源,因此我们需要暴露两个端口:
-
18080:对应hmall-portal
-
18081:对应hmall-admin
命令如下:
docker run -d \
--name nginx \
-p 18080:18080 \
-p 18081:18081 \
-v /root/nginx/html:/usr/share/nginx/html \
-v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
--network hmall \
nginx
测试,通过浏览器访问:http://你的虚拟机ip:18080
结言:
你好,我是Blue. 为帮助别人少走弯路而写博客 !!!
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
如果你遇到了问题,自己没法解决,可以私信问我。
感谢订阅专栏 三连文章!!