一、Docker的基本概念
Docker 是一个开源的应用容器引擎,基于Go 语言并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
这里可移植指的是,可以直接将镜像保存为镜像压缩文件,然后可以将这个镜像压缩文件发送到任何一台机器上重新加载成镜像,然后根据该镜像创建容器即可完成移植。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
沙箱是一个虚拟系统程序,沙箱提供的环境相对于每一个运行的程序都是独立的,而且不会对现有的系统产生影响。
沙箱具有非常良好的独立性、隔离性,所以能够搭建一些具有高风险的软件进行测试。比如,你可以在沙箱里面运行一个病毒程序,也是安全的。
Docker容器应用场景:
- Web应用的自动化打包和发布,web应用在本地构建好之后,可以通过文件挂载绑定,即本地与容器目录进行绑定,实现本地项目打包构建,docker中自动发布。
- 自动化测试和持续集成、发布,使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试;
- 在服务型环境中部署和调整数据库或其他的后台应用
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境
Docker容器的优点:
- 快速,一致地交付您的应用程序
- 响应式部署和扩展
- 在同一硬件上运行更多工作负载
二、Docker的基本架构
镜像相当于是一个root文件系统,可以理解成一个软件安装包。比如nginx镜像,有了nginx镜像文件,就相当于有了nginx软件安装包,我们就可以对nginx进行安装运行了。
容器相当于是一个镜像运行的环境,可以理解为我们的电脑操作系统。所以我们可以将我们的镜像文件安装到我们的容器中,当我们启动容器的时候,可以通过指定CMD在容器运行后所要执行的命令,来运行我们的镜像。
仓库,用于保存镜像的一个仓库,有本地镜像仓库和官方的远程镜像仓库(Docker Hub),类似于代码提交的仓库,我们可以从远程镜像仓库下载镜像到本地,也可以将本地创建的镜像推送到远程仓库中。
三、Docker的基本使用
① 镜像的基础操作
我们要创建容器必须要基于镜像。当我们安装好Docker之后,我们就可以直接在终端中通过docker命令从远程镜像仓库(Docker Hub)进行镜像的下载,下载无需登录即可,Docker账号只有将本地镜像推送到Docker Hub才需要登录。
镜像的搜索,即查找Docker Hub上有哪些可用的镜像,可使用search命令传入镜像名称即可。
docker search image_name
// 搜索nginx镜像资源 docker search nginx
- 镜像过滤,即对查找的镜像进行过滤,可通过--filter选项指定过滤规则,如:
// 搜索官方发布的ngnix镜像
docker search --filter "is-official=true" nginx
// 搜索自动化发布的镜像
docker search --filter "is-automated=true" nginx
// 搜索星星数量在2000以上的镜像
docker search --filter "stars=2000" nginx
下载镜像,即将远程Docker Hub上的镜像资源下载到本地仓库中,可通过pull命令传递镜像名称即可,如:
// 从远程Docker Hub中下载nginx镜像 docker pull nginx
查看已下载镜像,即查看本地仓库中存在的镜像,可通过images命令查看,如:
// 查看本地仓库中有哪些镜像 docker images
本地镜像删除,即从本地仓库中删除镜像,可通过rmi命令进行删除,i即image,需要注意的是,如果要删除的镜像被某个容器所使用,不管这个容器是处于运行还是停止状态,那么必须带上-f选项才能删除。
// 从本地仓库中删除nginx镜像 docker rmi nginx // 从本地仓库中强制删除vuenginx镜像 docker rmi -f vuenginx
保存镜像,即将docker中的本地镜像以tar压缩包的形式保存到宿主机中,可以通过save命令保存,如:
// 将docker中的vuenginx镜像导出到宿主机上 docker save -o vuenginx.tar vuenginx
-o即--output,指定保存后的镜像名称,之后的参数为docker中要被导出的镜像名
加载镜像,即将保存到宿主机指定镜像压缩包加载到docker的本地镜像仓库中,可以使用load命令,如:
// 加载宿主主机当前目录下的images目录下的名为vuenginx的镜像压缩包 docker load -i ./images/vuenginx.tar
需要注意的是,压缩包的名称并不会影响加载后镜像的名称,即镜像保存的时候是基于哪个镜像,加载后显示的也是哪个镜像。
导入镜像,即将保存到宿主机指定镜像压缩包导入到docker的本地镜像仓库中,可以使用import命令,如:
// 基于宿主机上./images/vuenginx.tar镜像压缩包导入到docker中并命名为test docker import ./images/vuenginx.tar test
注意,镜像名称必须全小写。
二者的区别:
docker import:丢弃了所有的历史记录和元数据信息,仅保存容器当时的快照状态。在导入的时候可以重新制定标签等元数据信息。
docker load:将保存完整记录,体积较大。
② 容器的基础操作
有了镜像,我们就可以基于镜像来创建、运行容器了。
创建容器,即基于某个镜像来创建容器,但是创建的容器不会被运行,可以通过create命令,如:
// 基于nginx镜像创建名为nginxContainer容器 docker create --name nginxContainer nginx docker create --name "nginxContainer" nginx docker create --name=nginxContainer nginx docker create --name="nginxContainer" nginx
--name指定容器名称的时候,以上四种方式都可以。通过created命令创建的容器会处于Created状态,同名的容器不能重复创建。
运行容器,即将创建好的容器启动起来,可以通过restart命令,如:
// 重新启动、运行指定的容器 docker restart nginxContainer
运行的容器会处于Up状态。
- 创建并运行容器,即创建容器后立即运行起来,可以通过run命令,如:
docker run -itd --name=container_name image_name
-i 表示以交互模式运行容器,通常与-t同时使用;
-t 表示为容器重新分配一个伪输入终端,通常与-i同时使用;
-d 表示后台运行容器,并返回容器ID
--name 为容器指定名称,同create命令,如果没有指定名称,那么docker为创建的容器自动生成一个名称。
// 基于nginx容器创建并运行容器
docker run nginx
docker run -i nginx
docker run -t nginx
docker run -it nginx
以上四个命令执行后终端会停住无法输入,因为容器在前台运行,并且由于没有通过--name指定,所以创建的容器名由docker自动生成,结束终端之前,创建的容器会一直处于运行状态,结束终端后容器会立即进行停止状态。
// 基于nginx容器创建并运行名为nginxContainer的容器
docker run -itd --name nginxContainer nginx
以上命令执行后,终端会立即返回容器的id,并且容器在后台运行,此时终端可以继续输入,并且容器也处于运行状态。
在run容器的时候,还可以传递一个COMMAND,即在容器运行起来之后执行指定的命令,并且这个命令会影响创建的容器的状态。
如果这个命令是可以持续运行的,那么容器也可以进入到运行状态。
如果这个命令是执行完成后就结束的,那么容器也会随着命令的结束而进入停止状态。
也就是说,如果想让创建的容器处于一直运行状态,那么我们必须在容器启动后执行一个可持续运行的命令。如:
# 容器基于nginx镜像创建并启动并且容器启动后执行 echo "hello docker"命令
docker run -itd --name test nginx echo "hello docker"
由于容器启动后执行的命令是执行完成后就结束的命令,所以创建的test容器也随之进入停止状态。
# 容器基于nginx镜像创建并启动并且容器启动后执行 sleep 10
docker run -itd --name test nginx sleep 10
由于容器启动后执行的命令是可以持续执行10秒的命令,所以创建的test容器会运行10秒后再进入停止状态。
- 查看容器,即查看创建的容器信息,可以通过ps和container命令,如:
// 查看运行中的容器信息
docker ps
// 查看所有容器信息包括已经停止运行的
docker ps -a
// 查看运行中的容器信息
docker container list
// 查看所有容器信息包括已经停止运行的
docker container list -a
根据命令输出结果,我们可以看到容器id只显示了一部分,而我们的容器id的值其实是一个64位的字符串,如果我们想要完整的显示出来,可以加上--no-trunc
参数,如:
# 查看容器各字段详细信息
docker ps -a --no-trunc
停止容器,即让运行中的容器停止运行,可以通过stop命令,后面传入容器名或者容器id,如:
// 停止正在运行的名为nginxContainer的容器 docker stop nginxContainer
重启容器,即让停止运行的的容器重新运行起来,可以通过restart命令,后面传入容器名或者容器id,如:
// 重新运行的名为nginxContainer的容器 docker restart nginxContainer
删除容器,只能删除已经停止运行的容器,可以通过rm命令,后面传入容器名或者容器id,如:
// 删除已经停止运行的名为nginxContainer的容器,如果该容器还在运行,必须先stop掉,再删 docker rm nginxContainer
进入容器,指的是进入容器的终端,我们可以在容器中执行一些命令,比如执行bash命令就可以进入到容器的终端界面,可以通过exec命令,后面传入容器名或者容器id,如:
// 进入容器的终端界面,其实就是在容器中执行了bash命令 docker exec -it nginxContainer bash
需要注意的是,必须带上-i和-t,-t只能进入到容器的终端界面,但无法进行命令交互,-i只能够进行命令交互,但是没有终端界面,不是很好用,所以-it才能进行正常命令交互。
- 退出容器,即退出容器的终端界面,可以在容器终端中输入exit即可退出。
提交容器,即我们在容器中进行操作后,比如拷贝了一些文件,修改了nginx的配置文件,我们可以直接将这些修改提交,提交后会创建一个新的镜像,我们可以基于这个新的镜像创建容器,创建的容器将会带上这些修改,可以通过commit命令,如:
// 提交nginxContainer容器上的修改,并且将提交而产生的镜像命名为new_nginxontainer docker commit -m "create a new image" nginxContainer new_nginxontainer
导出容器,即将容器进行导出成镜像压缩包,这个镜像压缩包还可以再次导入回来,但是导入回来的是镜像而不是容器了,可以通过export命令进行导出,通过import命令进行导入,如:
# 将vueApp这个容器进行导出并且保存为vueApp.tar镜像压缩包 docker export vueApp > vueApp.tar
# 将vueApp.tar镜像压缩包导入并保存为镜像,名字为vueappimage docker import vueApp.tar vueappimage # 同一个镜像可以被导入保存为镜像多次 docker import vueApp.tar vueappimage2
③ 容器的进阶操作
容器的进阶操作,主要是指docker容器和宿主机之间端口、文件的绑定,实现宿主机中修改能够立即同步到docker容器中。
端口映射,我们可以在运行容器的时候,将docker中的端口和宿主机的端口进行关系映射,比如,当我们通过浏览器访问某个8080端口的时候,我们可以将8080端口的请求转发到docker的80端口上,我们就可以访问到docker中nginx服务器下的页面了,可以在执行run命令的时候,加上-p选项传入宿主机端口号:docker容器端口号,如:
// 将宿主机的8080端口与docker的80端口进行映射 docker run -itd --name nginxContainer -p 8080:80 nginx
此时浏览器地址栏中输入http://localhost:8080/,请求就会被转发到docker的80端口上,就能查看到nginx提供的默认首页了
文件挂载,即将宿主机中的某个文件或目录与docker容器中的某个文件或目录,可以在执行run命令的时候,加上-v选项传入宿主机文件目录或文件(绝对路径):docker容器目录或文件
// 将宿主主机下指定目录与docker容器目录进行关联 docker run -itd --name vueApp -p 8080:80 -v /**/**/test-docker/dist:/usr/share/nginx/html/ vuenginx
需要注意是,本地宿主主机目录必须是绝对路径,并且如果宿主主机上该目录文件发生变化,那么需要执行restart命令重启容器才会生效。
此时本地宿主主机中的目录和容器中的目录就被关联起来了,关联目录下本地文件一旦被修改,用户再次访问页面的时候就会显示修改过的页面了。
宿主主机与docker容器之间文件拷贝,可以通过cp命令进行拷贝,容器目录或文件需要指定容器名,如:
// 将容器中的/etc/nginx/conf.d/default.conf文件拷贝到宿主主机的/**/**/target_dir/目录中 docker cp nginxContainer:/etc/nginx/conf.d/default.conf /**/**/target_dir/ // 将宿主主机中的/www/index.html 拷贝到容器的/usr/share/nginx/html/ 目录下 docker cp /www/index.html nginxContainer:/usr/share/nginx/html/
四、Dockerfile
Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
Dockerfile文件结构一般分为四部分,基础镜像信息、维护者信息 镜像操作指令和容器启动时执行的指令,dockerfile文件中可以通过#号进行注释。
指令详解
FORM: 指定基础镜像名,必须是第一个指令,因为后续指令都是基于该镜像镜像操作。
# 以nginx镜像为基础进行构建 FROM nginx
- MAINTAINER: 维护者信息,可选。
# lihb维护该dockerfile文件
MAINTAINER lihb
- RUN: 构建镜像时执行的指令
# 执行命令安装项目所需依赖
RUN npm install
dockerfile的指令每执行一次都会在docker上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
# 以上执行会创建3层镜像。可简化为以下格式:
FROM centos
RUN yum install wget \
&& wget -O redis.tar.gz"http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
上面的\仅表示换行,如果命令短的话,其实可以不需要换行,但是换行必须加上斜杠。
# 不换行写法
FROM nginx
RUN echo "test" && pwd && ls
COPY: 将dockerfile文件所在目录下的本地文件或目录添加到容器中,压缩类型文件不会自动解压文件
# dockfile文件所在目录下的dist目录下的所有文件添加到docker容器中指定目录下 COPY dist/ /usr/share/nginx/html/ COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY指令中,宿主主机上的目录必须是相对于构建时所用的dockerfile所在的目录。
- ADD: 同COPY,但是其会自动解压文件。
相同功能下,建议使用COPY。
CMD: 也是执行一条命令,不过这条命令是在容器启动后调用,即指定容器默认要运行的程序,程序运行结束,容器也就结束,CMD指令指定的程序可被docker run命令行参数中指定要运行的程序所覆盖。即docker run命令中传递的COMMAND优先级更高。如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
# 执行命令安装项目所需依赖 RUN npm install # 执行npm start脚本 CMD ["npm", "start"]
- ENTRYPOINT: 只允许一个,如果有多个,会发生覆盖,只执行最后一个。
ENTRYPOINT ["nginx", "-g", "daemon off;"]
- LABEL: 用于为镜像添加元数据。
ENV: 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH # 后续的指令中可以通过 $NODE_VERSION 引用 ENV NODE_VERSION 7.2.0
- EXPOSE: 用于指定与外界交互的端口号,但并不会关联,需要在运行容器时通过-p来关联这些端口号
# 声明容器可以使用80和443端口
EXPOSE 80 443
- VOLUME: 用于指定容器运行时创建的匿名数据卷路径,在启动容器docker run的时候,我们可以通过-v参数修改挂载点。即容器运行时,会创建VOLUME指定的目录,任何向该目录中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化,可以避免容器不断变大。
# 容器运行时,会创建一个/foo目录
VOLUME /foo
WORKDIR: 工作目录,类似于cd命令,会进入到指定目录下
# 相当于执行了cd /usr/src/docker-server WORKDIR /usr/src/docker-server
- USER: 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
- ARG: 指定构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量
ARG NGINX_VERSION=1.15.0
- ONBUILD: 用于设置镜像触发器,延迟构建命令的执行。
通过dockerfile文件构建镜像
可以通过docker build 命令进行镜像的构建,-f指定dockerfile文件的路径,-t指定构建好的镜像名称,最后加一个.
// 千万不要少了最后面的那个点
docker build -f /path/to/dockerfile -t image_name .
dockerfile文件的名称或后缀可以任意,只要里面的指令正确就行。如果没有通过-f指定dockerfile文件的路径,那么默认会找当前终端所在目录下的dockerfile文件,没有则构建失败。
五、通过Docker部署vue项目
① 通过Vue CLI创建Vue项目
这一步比较简单,直接通过vue create 命令创建即可,如:
# 创建一个名称为test-docker的项目
vue create test-docker
# 进入到test-docker项目根目录
cd test-docker
# 构建vue项目
npm run build
执行完npm run build
后,会在项目根目录下创建一个dist目录,里面存放的就是vue项目打包后的结果,用于生产发布。我们只需要将dist目录中的内容部署到静态资源站点就可以直接访问到该项目了。下面我们将以nginx服务器为例,在docker中创建一个nginx的容器来运行我们的nginx服务器,同时将dist目录中的内容放到nginx服务器的静态资源站点下。
② 创建包含dist目录中内容的nginx镜像
这里我们以官方的nginx镜像为基础,同时将dist目录中的内容拷贝到nginx静态资源站点下,并构建出一个新的镜像,然后再根据这个新的镜像去创建容器,那么创建好的容器中就会带上dist目录下的内容。当然也在容器创建好之后再将dist中的目录拷贝进去也是可以的。
- 获取官方nginx镜像
通过docker pull nginx 从官方下载一个最新的nginx镜像。 编写dockerfile文件
在vue项目根目录下新建一个名为dockerfile的文件,内容如下:# 以官方的nginx镜像为基础进行构建 FROM nginx # 将当前dockerfile所在目录下的dist目录的内容拷贝到容器的/usr/share/nginx/html/下 COPY dist/ /usr/share/nginx/html/
根据该dockerfile构建出带有dist目录内容的nginx镜像。
# 进入到vue项目根目录 cd /path/to/vue项目根目录 # 构建镜像,镜像名为vuenginx docker build -t vuenginx .
当我们在vue项目根目录下执行docker build命令的时候,docker会自动在当前目录下寻找dockerfile文件,然后根据dockerfile文件中的指令进行镜像的构建,构建出的镜像名为 -t指定的名称,需要注意的是最后的点号不能少。
打开终端输入以下命令检查镜像是否创建成功,如:
# 打开终端直接输入以下命令
docker images | grep "vuenginx"
③ 创建并运行vueApp容器
创建好镜像之后,我们就可以基于该镜像创建并运行容器了,如:
# 基于vuenginx运行容器
docker run -itd --name vueApp -p 8080:80 vuenginx
# 查看容器信息
docker ps -a
运行容器并且将本地主机的8080端口与容器的80端口绑定,当我们在本地主机上访问8080端口的时候,请求就会被转发到容器的80端口上,从而被容器中的nginx服务器处理。
此时我们在本地主机浏览器上访问http://localhost:8080/,即可看到我们的vue项目首页了,说明我们已经成功在docker容器中部署了一个静态资源服务器。为了能够让我们的vueApp能够发起异步请求数据,我们还需要在docker中创建node服务器容器,提供web服务器功能。
④ 新建node应用作为vue应用的web服务器
新建一个node项目,并在node项目根目录下创建一个index.js作为node应用启动入口文件,如下:
# 创建docker-server目录
mkdir docker-server
# 初始化package.json文件
npm init --yes
# 新建index.js文件
index.js内容如下
const express = require("express");
const app = express();
app.get("/docker", (req, res, next) => {
res.send("hello, welcome to docker web server for vueApp.");
});
app.listen(3000);
package.json内容如下:
{
"name": "docker-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
}
}
⑤ 创建nodeserver镜像
这里我们以官方的node镜像为基础,同时将node应用根目录下的内容拷贝到镜像中,并安装项目依赖,并构建出一个新的镜像,然后再根据这个新的镜像去创建容器,那么创建好的容器中就会带上node应用的源码了。
- 获取官方node镜像
通过docker pull node 从官方下载一个最新的node镜像。 编写dockerfile文件
在vue项目根目录下新建一个名为dockerfile的文件,内容如下:# 构建node镜像 FROM node # 找一个目录存放我们的server代码, 相当于执行了cd /usr/src/docker-server WORKDIR /usr/src/docker-server # 复制当前目录内容 到容器中指定的应用根目录下 COPY . . # 执行命令安装项目所需依赖 RUN npm install # 让容器可以使用3000端口 EXPOSE 3000 # 容器启动后执行npm start脚本 CMD ["npm", "start"]
这里node_modules和dockerfile文件中的东西就不需要拷贝到镜像里去了,我们直接在镜像里面安装即可,可以添加一个.dockerignore文件进行忽略,如:
# .dockerignore文件内容
node_modules
npm-debug.log
dockerfile
Dockerfile
根据该dockerfile构建出带有node应用node镜像。
# 进入到docker-server项目根目录
cd /path/to/docker-server项目根目录
# 构建镜像,镜像名为nodeserver
docker build -t nodeserver .
⑥ 创建并运行vueServer容器
# 基于nodeserver创建并运行容器
docker run -itd --name vueServer -p 8888:3000 nodeserver
这里将本地主机的8888端口与docker容器的3000端口进行了映射。
容器运行后,在本地主机访问http://localhost:8888/test,检测docker下的node服务器是否部署成功。
说明docker下的node服务器已经部署成功了,接下来我们需要修改vue项目,让其访问这个node服务器。
⑦ 修改Vue项目
在HelloWorld.vue组件的created生命周期中添加一个向服务器异步获取数据的接口,如:
# 安装axios并引入
import axios from "axios"
created() {
axios.get("/api/docker").then((res) => {
this.msg = res.data;
});
}
现在我们在本地主机访问vue项目的时候,会发起http://localhost:8080/api/docker的请求,请求会被转发到docker容器的80端口,即http://localhost/api/docker,但是我们docker中的服务器是3000端口,所以需要进行跨域,所以我们还要修改nginx的配置文件添加代理。
由于vueApp和vueServer是在两个不同的容器中,就相当于是在两台不同的电脑上,所以我们不能再使用localhost进行请求转发了,必须找到vueServer的ip地址,有两种方式,如:
- 进入容器并执行bash命令,然后通过查看/etch/hosts文件获取到,如:
- 通过inspect命令直接查看容器信息,然后搜索Networks,即可,如:
可知其ip地址为172.17.0.2
在vue项目根目录下新建一个nginx目录,然后新建一个default.conf,配置文件内容如下:
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/ {
rewrite /api/(.*) /$1 break;
proxy_pass http://172.17.0.2:3000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
此时我们在本地主机修改后,重启容器,发现修改并没有应用我们刚刚的修改,我们还得按上面的步骤重新创建镜像和容器,这样显然是非常麻烦,我们可以将本地主机的文件或目录与docker容器中的文件或目录进行挂载,这样当本地主机修改后,容器重启即可应用本地主机的修改。
# 停止并删除之前的vueApp容器
docker stop vueApp
docker rm vueApp
# 重新创建运行容器并进行文件挂载绑定
docker run -itd --name vueApp -p 8080:80 \
--mount type=bind,source=/path/to/test-docker/dist,target=/usr/share/nginx/html \
--mount type=bind,source=/path/to/test-docker/nginx,target=/etc/nginx/conf.d \
nginx
当然我们也可以通过-v进行文件的挂载,如:
# 停止并删除之前的vueServer容器
docker stop vueServer
docker rm vueServer
# 重新创建运行容器并进行文件挂载绑定
docker run -itd --name vueServer -p 8888:3000 \
-v /Users/banma-798/Documents/learn/docker-server:/usr/src/docker-server nodeserver
此时再次访问http://localhost:8080,页面如下显示,表示跨域请求成功。
⑧ 配置负载均衡
为了能够让后端服务器能够处理更多请求,通常我们会配置多台服务器,以保证后端服务器的稳定,提高吞吐量和减少延迟,最大化资源利用率。所以我们可以再创建一个vueServer容器,如:
# 再次创建并运行一个node服务器,容器名为vueServer2
docker run -itd --name vueServer2 -p 9999:3000 \
-v /Users/banma-798/Documents/learn/docker-server:/usr/src/docker-server nodeserver
此时我们在本地主机上访问http://localhost:9999/docker,如果请求成功表示第二台服务器启动成功。
查看新建的vueServer2的ip地址为172.17.0.4
修改配置文件,如下:
upstream backend{
server 172.17.0.4:3000;
server 172.17.0.2:3000
}
location /api/ {
rewrite /api/(.*) /$1 break;
proxy_pass backend;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。