Docker 部署前后端项目
平生不会相思,才会相思,便害相思。
简介:都是被逼的,从零开始一个Docker 部署九个微服务和三个前端项目。其中,这些服务需要用到Nacos、MySQL、Nginx、ElasticSearch、Kibana、Redis、JDK和 Minio 文件存储服务器。当然真实环境不会在一台服务器上或者一个Docker中安装部署这么多东西,由于本机只开了一台虚拟机所以是在同一个虚拟机中安装部署的,到正式环境上就把几个存储数据的和运行项目的分别安装部署到多个服务器上即可。
一、准备工作:
1、九个微服务+三个前端项目。
2、一台虚拟机,Linux 和Ubuntu 都可以,本次选择的是带有图形界面的Ubuntu 系统。
二、简单了解Docker
解决的问题
由于不同的机器有不同的操作系统,以及不同的库和组件,在将一个应用部署到多台机器上需要进行大量的环境配置操作。
Docker 主要解决环境配置问题,它是一种虚拟化技术,对进程进行隔离,被隔离的进程独立于宿主操作系统和其它隔离的进程。使用 Docker 可以不修改应用程序代码,不需要开发人员学习特定环境下的技术,就能够将现有的应用程序部署在其它机器上。
与虚拟机的比较
虚拟机也是一种虚拟化技术,它与 Docker 最大的区别在于它是通过模拟硬件,并在硬件上安装操作系统来实现。
启动速度
启动虚拟机需要先启动虚拟机的操作系统,再启动应用,这个过程非常慢;
而启动 Docker 相当于启动宿主操作系统上的一个进程。
占用资源
虚拟机是一个完整的操作系统,需要占用大量的磁盘、内存和 CPU 资源,一台机器只能开启几十个的虚拟机。
而 Docker 只是一个进程,只需要将应用以及相关的组件打包,在运行时占用很少的资源,一台机器可以开启成千上万个 Docker。
优势
除了启动速度快以及占用资源少之外,Docker 具有以下优势:
1. 更容易迁移
提供一致性的运行环境。已经打包好的应用可以在不同的机器上进行迁移,而不用担心环境变化导致无法运行。
2. 更容易维护
使用分层技术和镜像,使得应用可以更容易复用重复的部分。复用程度越高,维护工作也越容易。
3. 更容易扩展
可以使用基础镜像进一步扩展得到新的镜像,并且官方和开源社区提供了大量的镜像,通过扩展这些镜像可以非常容易得到我们想要的镜像。
镜像与容器
镜像是一种静态的结构,可以看成面向对象里面的类,而容器是镜像的一个实例。
镜像包含着容器运行时所需要的代码以及其它组件,它是一种分层结构,每一层都是只读的(read-only layers)。构建镜像时,会一层一层构建,前一层是后一层的基础。镜像的这种分层存储结构很适合镜像的复用以及定制。
构建容器时,通过在镜像的基础上添加一个可写层(writable layer),用来保存着容器运行过程中的修改。
三、Docker 安装与使用
准备一台虚拟机,Linux 和Ubuntu 操作系统的都可以,本人在VMWare 上两个操作系统都有安装,但是Ubuntu 的是有图形操作界面,用起来更舒适,所以接下来的操作都是基于Ubuntu 系统的,但是Linux 和Ubuntu 系统区别不大,命令什么的大多也通用。
安装
查看docker是否安装:
docker version
1、更新ubuntu 的apt 源索引:
sudo apt-get update
2、设置 apt可以通过Https 使用存储库(repository)
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
3、添加Docker 官方GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
4、设置Stable存储库,即docker 稳定仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
5、再次更新apt 包索引并安装最新的Docker CE 版本
sudo apt-get update
sudo apt-get install -y docker-ce
6、查看Docker 是否安装成功并确认服务是否已经启动
docker version
systemctl status docker
查看docker 运行状态,已启动:
如果检查未启动执行一下
sudo systemctl start docker
7、经典Hello World
sudo docker run hello-world
使用
1、启动与停止
安装完成Docker 后,默认已经启动了docker服务,如需手动控制docker服务的启停,可执行如下命令。
# 启动docker
sudo service docker start
# 停止docker
sudo service docker stop
# 重启docker
sudo service docker restart
docker 安装完成,一般用户没有权限启动docker 服务,只能通过sudo 来通过root 用户权限来启动docker,此时对于一般用户而言,需要执行docker ps 或者docker images 命令查看容器或者镜像提示如题所示的错误。
解决办法:
1、使用sudo docker ps或者sudo docker images,但是每次都要输入密码。
2、把普通用户加入到docker 组中
这里的普通用户是tjt,组docker 在安装docker 的时候,就已经添加了,所以只需要执行两个操作即可:
1 sudo gpasswd -a $USER docker
2
3 newgrp docker
将tjt 用户加入docker 组之后,发现使用docker ps或者docker images 不会提示权限不足了。
2、 Docker 镜像操作
四、在Docker 中安装和配置nacos
1、查找nacos的镜像,执行命令
docker search nacos
2、拉取nacos 镜像
docker pull nacos/nacos-server:1.1.4
这边没有安装最新版,而是指定了版本号。
docker images 查看是否拉取nacos 镜像成功
3、启动nacos服务
指令:
docker run --env MODE=standalone --name nacos -d -p 8848:8848 nacos/nacos-server:1.1.4
查看是否启动成功:docker ps
4、打开浏览器测试访问nacos
初始账号/密码为:nacos/nacos
4、设置NACOS 自动启动
指令:docker update --restart=always 963217d51c36(最后一项为nacos容器的CONTAINER ID)
docker update --restart=always 963217d51c36
5、Nacos 配置
把每个微服务的bootstrap.yml 配置文件内容写到nacos.
连接虚拟机服务器,上传nacos 配置文件到服务器,解压后导入nacos 列表。
解压后单个加入,或者无需解压,点击“导入配置”按钮,以zip 压缩包形式批量导入所有微服务的bootstrap.yml 配置文件。
五、Docker 安装MySQL
1、查找Docker Hub 上的mysql 镜像
docker search mysql
2、拉取 MySQL 镜像
latest 这里拉取官方的最新版本的镜像:
docker pull mysql:latest
3、查看本地镜像
使用以下命令来查看是否已安装了 mysql:
docker images
4、运行容器
安装完成后,我们可以使用以下命令来运行 mysql 容器:
docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
参数说明:
- -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。
- MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
5、安装成功
通过 docker ps 命令查看是否安装成功:
至此,使用docker 安装mysql 的工作就已经完成了。
以后使用如下命令开启并执行名为mysqldb 的容器:
1 sudo docker start mysqldb
2 sudo docker exec -it mysqldb /bin/bash
使用如下命令关闭名为mysqldb 的容器:
sudo docker stop mysqldb
6、Docker 中mysql 简单交互
(1)输入命令连接mysql:
本机可以通过 root 和密码 123456 访问 MySQL 服务。
直接通过-u root 命令访问mysql 输入会报错,先安装mysql-server
sudo apt-get install mysql-server
弹框提示输入mysql 的root 密码和确认密码
输入密码后可以访问,但报了个mysql.socket 的错
修改/etc/my.cnf
tjt@tjt-virtual-machine:~$ vim /etc/my.cnf
添加以下内容到/etc/my.conf:
1 [client]
2
3 socket = /Data/mydata/mysql.sock
4
5 [mysqld]
6
7 socket = /Data/mydata/mysql.sock
我使用的不是root 用户编辑文件,无法保存,所以退出时强制保存:w ! sudo tee %
一顿操作后,发现还是不行-报错,白搞了。
原来,我们的mysql 是安装在docker 中,系统中并没有mysql,也是通过docker 命令启动的,所以要先进入docker容器,再能启动对应的mysql。
进入容器
docker exec -it 容器ID /bin/bash
进入mysql,启动容器的时候初始密码已经设置为了:123456
mysql -u root -p
简单测试MySQL 数据库是否可以用
7、MySQL 数据导入
由于待会运行后端项目,登录系统需要用到账号和密码,索性在这里把MySQL 数据导入Docker 容器中的MySQL。
1、从本地数据库导出SQL
2、进入mysql的docker容器
3、创建数据库
4、将sql 文件copy 到docker 容器里
进入容器,执行.sql 文件,完成数据导入初始化。
六、 docker 安装redis
1、获取 redis 镜像
这里我拉取官方的最新版本的镜像:
docker pull redis
2、查看本地镜像
docker images
3、运行容器
安装完成后,我们可以使用以下命令来运行 redis 容器:
docker run -itd --name redis-test -p 6379:6379 redis
参数说明:
- -p 6379:6379:映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。
4、安装成功
最后我们可以通过 docker ps 命令查看容器的运行信息:
通过 redis-cli 连接测试使用 redis 服务。
首先进入redis容器
docker exec -it redis-test /bin/bash
七、Docker 安装 jdk1.8
1、查找jdk
docker search jdk
2、下载 jdk
docker pull kdvolder/jdk8
3、查看是否下载成功
docker images
4、启动
docker run -di --name=jdk1.8 kdvolder/jdk8
5、查看是否启动成功
docker ps
6、查看JDK 版本
首先要进入jdk8 容器
docker exec -it jdk1.8 /bin/bash
再查看jdk 版本
八、Docker 安装ElasticSearch
1、拉取 es 的 docker 镜像
这里拉取 7.8.0 版本
docker pull elasticsearch:7.8.0
2、拉好镜像后,docker images查看镜像
3、接下来直接启动 docker 中的 es 镜像就好了
# -d : 后台运行
# -p : 指定宿主机与docker启动容器的端口映射
# --name : 为 elasticsearch 容器起个别名
# -e : 指定为单节点集群模式
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.8.0
启动后docker ps 查看是否成功
4、访问测试
浏览器输入: http://localhost:9200/ ,或者终端输入: curl http://localhost:9200/ 来检查es 是否安装成功。
在虚拟机内浏览器访问:
也可以带上IP 在非虚拟机内浏览器访问:
终端访问:
curl XGET "localhost:9200"
九、Docker 安装 Kibana
Kibana 是一款适用于 es 的数据可视化和管理工具, 可以提供实时的直方图、线形图、饼状图和地图。
需要注意的是, kibana 的版本最好与 elasticsearch 保持一致, 避免发生不必要的错误。
1、拉取Kinaba 镜像
直接和 es 版本保持一致:
docker pull kibana:7.8.0
2、查看Kibana 镜像是否拉取到本地docker images
3、Docker 启动 Kibana
7.8.0 版本的 kibana 包比较大, 启动较慢, 稍等个半分钟
# -e : 指定环境变量配置, 提供汉化
# --like : 建立两个容器之间的关联, kibana 关联到 es
docker run -d --name kibana --link elasticsearch:elasticsearch -e "I18N_LOCALE=zh-CN" -p 5601:5601 kibana:7.8.0
# kibana 的汉化我感觉做的并不好# 如果不习惯汉化, 可以把条件去除
docker run -d --name kibana --link elasticsearch:elasticsearch -p 5601:5601 kibana:7.8.0
docker ps 查看是否docker 启动成功:
4、访问测试
在虚拟机内的浏览器输入地址 http://localhost:5601/, 测试启动成功
在非虚拟机内浏览器打开需改变IP 地址:
发现输入地址后即可访问,下面还要配置下密码
5、修改ES 配置
1、进入容器&打开文件
docker exec -it 容器ID bash
tjt@tjt-virtual-machine:~$ docker exec -it 2ec6df4ed409 bash
cd config
vi elasticsearch.yml
2、编辑文件
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
3、设置密码
先重启下es 再执行
tjt@tjt-virtual-machine:~$ docker restart 2ec6df4ed409
tjt@tjt-virtual-machine:~$ docker exec -it 2ec6df4ed409 bash
[root@2ec6df4ed409 elasticsearch]# cd bin
[root@2ec6df4ed409 bin]# elasticsearch-setup-passwords interactive
逐个输入密码,这里都是123456 比较好记。
重启es 访问:
tjt@tjt-virtual-machine:~$ docker restart 2ec6df4ed409
到虚拟机内部浏览器访问es,http://localhost:9200/,提示输入密码
6、修改Kibana 配置
1、进入容器&打开文件
docker exec -it kibana bash
cd config
vi kibana.yml
添加下面三行:
elasticsearch.username: "elastic"
elasticsearch.password: "123456"
i18n.locale: "zh-CN
重启Kibana 访问:
因为es 配置了密码,所以Kibana 重启前的登录界面使用的是es 的:
重启后使用Kibana 登录密码界面风格:
十、DOCKER -MINIO 文件存储服务器安装
1.操作minio 镜像
tjt@tjt-virtual-machine:~$ docker search minio
2.拉取镜像
docker pull minio/minio
装错了minio,可以删除容器,再重新安装。
3、再战Minio,这次的Minio 安装是从官网搞来的命令
https://docs.min.io/docs/minio-docker-quickstart-guide.html
docker run \
-p 9000:9000 \
-p 9001:9001 \
-e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
minio/minio server /data --console-address ":9001"
4、访问测试
重启Minio,查看Minio 容器日志得到访问地址:http://127.0.0.1:9000
上面配置了端口,9000回调到9001
在虚拟机内访问Minio 登录页:
登录账号是刚刚自己写进去的:
1 账号:AKIAIOSFODNN7EXAMPLE
2 密码:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
可以在Account 下修改密码:
新建用户:
minio/minio123
赋予minio 用户策略权限,新建用户后没有授予对应的策略也形同虚设。
十一、Docker 安装 Nginx
1、docker search nginx 命令来查看可用版本。
docker search nginx
2、取最新版的 Nginx 镜像
这里我拉取官方的最新版本的镜像:
docker pull nginx:latest
3、查看本地镜像
使用以下命令来查看是否已安装了 nginx:
docker images
4、运行容器
安装完成后,我们可以使用以下命令来运行 nginx 容器:
docker run --name nginx-test -p 8080:80 -d nginx
参数说明:
--name nginx-test:容器名称。
-p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
-d nginx: 设置容器在在后台一直运行。
5、安装成功测试
最后我们可以通过浏览器可以直接访问 IP + 8080 端口的 nginx 服务:
在虚拟机中浏览器通过localhost 访问报错:
修改如下:
ssl错误,请求用http,不用https
6、如何在本地目录上挂载配置文件
我们安装完nginx 后会发现配置文件在哪,日志文件目录在哪,web项目放到那个目录下,等等。
docker run一个镜像会生成一个容器,而我们需要修改的配置文件日志文件等等都在这个容器里
进入容器bash
1. 进入容器bash
tjt@tjt-virtual-machine:~$ docker exec -it 06191d8f5fab /bin/bash
因为是在docker 容器中编辑,与外部隔绝,需要在docker 中安装vim
vim 安装好后,再次执行
root@06191d8f5fab:/# vim /etc/nginx/nginx.conf
按照自己的需要修改ngnix配置文件
7、ngnix 第二种安装方式-将配置文件等目录挂载到本地
这个操作对于以后修改很方便,推荐这一种
1. 首先在本地准备我们的挂载目录以及配置文件
如果是普通用户,先授予普通用户root 权限,才方便准备本地配置文件,否则会提示权限不足。
授予用户tjt root 权限
tjt ALL=(ALL:ALL) ALL
发现还是没有root 用户好使,直接su 切换到root 用户操作,新增 conf、conf.d、logs、html 四个文件夹
建好目录后还需要两修改两个配置文件
nginx.conf
default.conf
这两个配置文件可以从之前安装的docker nginx镜像中拷贝,也可以从其他环境中拷贝一份配置。
配置文件创建完成后我们再在html 目录下随便新建一个index.html 页面用于测试Nginx
html 的内容随便写一点:
2. 然后我们就可以在运行时指定挂载目录了
先要删除之前方法一安装的ngnix 镜像
挂载日志目录
挂载配置目录
挂载主配置文件
命令:
docker run --name docker_nginx -d -p 8080:80 \
> -v /home/docker/nginx/logs:/var/log/nginx \
> -v /home/docker/nginx/conf.d:/etc/nginx/conf.d \
> -v /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
> -v /home/docker/nginx/html:/usr/share/nginx/html nginx
解释下上面的命令:
--name 给你启动的容器起个名字,以后可以使用这个名字启动或者停止容器
-p 映射端口,将docker 宿主机的80 端口和容器的80 端口进行绑定
-v 挂载文件用的,第一个-v 表示将你本地的nginx.conf 覆盖你要起启动的容器的nginx.conf文件,第二个表示将日志文件进行挂载,就是把nginx 服务器的日志写到你docker 宿主机的/home/docker-nginx/log/ 下面
第三个-v 表示的和第一个-v 意思一样的。
-d 表示启动的是哪个镜像
通过docker ps 查看ngnix 是否安装成功
3、访问测试
在虚拟机内浏览器测试:localhost:8080
十二、安装docker-compose
安装docker-compose ,使用docker-compose.yml 编排微服务的启动。
0.查看是否安装
docker-compose --version
1.进入https://github.com/docker/compose/releases 查看最新版本,当前版本为1.23.1
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
2.git 下载docker-composer 太慢了,可以使用如下链接
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
3.设置权限
sudo chmod +x /usr/local/bin/docker-compose
4.查看是否安装成功
到此为止,所有的安装准备工作都就绪了,接下来就是工程部署了。总共安装了如下镜像:
十三、 后端工程发布
1、生成镜像,准备启动
在 src/main/ 路径下新建 docker 文件夹,并新建 Dockerfile 文件、docker-compose.yml 文件。
2、项目打 jar 包
通过Maven 工具install 打jar 包,在对应工程的在target 目录下得到 xxx.jar。
3、 使用 Dockerfile 制作 Docker 镜像
注意这里的 jar 包位置。将 target 目录下生成的 jar 包拷贝在src/main/docker 目录下。
在 Dockerfile 中写入以下内容:
# 基于哪个镜像
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
# 拷贝文件到容器
ADD common-gateway-0.0.1-SNAPSHOT.jar /gateway.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/gateway.jar"]
ENV TIMEZONE Asia/Shanghai
上传到服务器对应目录下:
到对应目录下,执行命令:
docker build -t gateway-service:0.0.1 .
再通过 docker images 可以发现,镜像已经存在。
现在可以去书写 docker-compose.yml。
4、使用 docker-compose.yml 编排微服务的启动
在 docker-compose.yml 里面写入:
version: '3'
services:
gateway-service:
image: gateway-service:0.0.1
ports:
- 9999:9999
iamge:连接的对应的镜像名字,必须和你生成的镜像一模一样,版本号也一定要加上(默认latest,因为之前我们加了0.0.1,没有latest)
ports: 就是暴漏端口映射。保持一致,不易混淆。但是前端包要保持映射到Nginx 端口上。
执行
docker-compose up -d
-d:仍然表示后台执行
成功后docker ps查看:
访问nacos 服务,查看服务列表,看到有一个微服务在Nacos 服务列表中:
接下来把剩下八个微服务分别按照第一个gateway 微服务的方式打包上传到Docker 中,只build 打包,不run 启动,打包好后通过编写docker-compose 脚本一起启动所有微服务。
5、工程打包
common-oauth2 打包上传:
mng-sys 打包上传:
mng-mall 打包上传:
api-mall 打包上传:
api-pay 打包上传:
api-customer 打包上传:
api-member 打包上传:
api-aiot 打包上传:
6、工程添加到容器
上传好后分别添加到容器:
已添加第一个gateway 服务:docker build -t gateway-service:0.0.1 .
docker build -t oauth2-service:0.0.1 .
docker build -t sys-service:0.0.1 .
docker build -t api-mall-service:0.0.1 .
docker build -t api-pay-service:0.0.1 .
docker build -t api-customer-service:0.0.1 .
docker build -t api-aiot-service:0.0.1 .
docker build -t api-member-service:0.0.1 .
docker build -t mng-mall-service:0.0.1 .
docker images 查看容器中的工程:
看到这九个工程都加到docker 容器中了,但并没有启动,还需要编辑docker-compose.yml 编排微服务的启动。
执行docker-compose 命令:
docker-compose up -d
多次执行该命令,有变动的工程会重新部署:
再通过docker ps -a 查看docker 容器中的运行状态:
到nacos 服务列表下查看运行状况:
有十个微服务只跑了九个,担心电脑扛不住,之前用公司的电脑IDEA开超过五个微服务每次都会闪退。
心累啊,终于九个服务都跑通了:
再到ES中查看是否有索引,项目启动会自动生成es索引和字段:
到此为止,后端服务的部署就告一段落了,接下来就是三个前端项目了。
十四、前端工程发布
1、编写VUE 前端项目的Dockerfile
FROM nginx:latest
MAINTAINER 302665496@qq.com
COPY dist/ /usr/share/nginx/html/
第一行写的是设置基础镜像,也就是我们刚刚pull 下来的nginx 镜像,
第二行是写一个作者,写上自己的邮箱就好,
第三行的意思就是将dist 文件夹下面的内容拷贝到/usr/share/nginx/html/ 这个目录下。
这个目录是不是很眼熟?这个路径就是nginx 一般的项目地址路径。还记得nginx 的测试页面在哪儿吗?就是这个路径下的index.html 啦。
2、创建镜像
上传dist 目录下的static 和index.html 文件和Dockerfile 到虚拟机对应目录
在Dockerfile 的目录下执行
docker build -t admin-mall-vue:v1 .
admin-mall-vue:v1 是你镜像的名字。 特别注意后页面那个点不能省略。
然后在docker images 一下,你就能看到自己创建的VUE镜像了。
3、创建容器
执行命令:
# -d 后台运行
# -p 端口映射
docker run -d -p 9090:80 admin-mall-vue:v1
然后执行docker ps 查看:
4、访问测试
在内部浏览器访问:
到虚拟机外部,使用ip 访问能否正常登陆:
再试着更换图片,看下minio 文件服务器能不能用。
后面还有两个前端项目的部署,一个IM 客服聊天,一个手机APP商城,部署方式同后台管理vue 项目类似。3个前端工程,九个微服务的发布到此。
前面的一些步骤可以写成脚本,比如build 装载镜像等。
另外两个前端项目结构如下:
执行h5 APP前端项目的build 脚本:
执行im 客服聊天系统的build 脚本:
通过docker images 查看build 结果
执行docker-compose 运行两个前端项目:
docker-compose up -d
docker ps -a 查看发布状态:
使用虚拟机ip 172.16.114.135 加上端口号9091/9092 分别访问客服IM页面和H5商城页面:
平生不会相思
才会相思
便害相思