从 0 开始 之 Docker部署Vue项目

·  阅读 289

什么是Docker

  • 装应用的容器
  • 开发、测试、运维都偏爱的容器化技术
  • 轻量级
  • 扩展性
  • 一次构建、多次分享、随处运行

原理

对 Docker 最简单并且带有一定错误的认知就是 “Docker 是一种性能非常好的虚拟机”。

Docker 相比于传统虚拟机的技术来说先进了不少,具体表现在 Docker 不是在宿主机上虚拟出一套硬件后再虚拟出一个操作系统,而是让 Docker 容器里面的进程直接运行在宿主机上(Docker 会做文件、网络等的隔离),这样一来 Docker 会 “体积更轻、跑的更快、同宿主机下可创建的个数更多”。

Docker 中有三个核心概念:Image、Container、Repository。

  • Image: 有领“好人卡”倾向的广大程序猿一定对 镜像 的概念不会陌生。但和 windows 的那种 iso 镜像相比,Docker 中的镜像是分层的,可复用的,而非简单的一堆文件迭在一起(类似于一个压缩包的源码和一个 git 仓库的区别)。
  • Container: 容器的存在离不开镜像的支持,他是镜像运行时的一个载体(类似于实例和类的关系)。依托 Docker 的虚拟化技术,给容器创建了独立的端口、进程、文件等“空间”,Container 就是一个与宿机隔离 “容器”。容器可宿主机之间可以进行 port、volumes、network 等的通信。
  • Repository: Docker 的仓库和 git 的仓库比较相似,拥有仓库名、tag。在本地构建完镜像之后,即可通过仓库进行镜像的分发。常用的 Docker hub 有 hub.docker.com/cr.console.aliyun.com/ 等。

腾讯云云服务器安装Docker

腾讯云提供了开发者实验室帮助用户搭建 Docker 环境。

安装与配置 Docker

安装 Docker

添加镜像信息

在实际安装过程中,可能受限于国内网络问题,会出现安装缓存或者失败。

#官方给的镜像
#yum-config-manager --add-repo <https://download.docker.com/linux/centos/docker-ce.repo>

#建议使用阿里云的镜像进行加速,要不太慢了
yum-config-manager --add-repo <http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo> 
复制代码

Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。因此想要安装 docker,只需要运行下面的 yum 命令:

yum install docker-io -y

直接yum安装,安装成功后查看版本

docker -v

启动docker

service docker start

设置开机启动

chkconfig docker on

配置 Docker

因为国内访问 Docker Hub 较慢, 可以使用腾讯云提供的国内镜像源, 加速访问 Docker Hub

依次执行以下命令

echo "OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'" >> /etc/sysconfig/docker

systemctl daemon-reload

service docker restart
复制代码

报错

Docker 的简单操作

下载镜像

下载一个官方的 CentOS 镜像到本地

docker pull centos

下载好的镜像就会出现在镜像列表里

docker images

运行容器

这时我们可以在刚才下载的 CentOS 镜像生成的容器内操作了。

生成一个 centos 镜像为模板的容器并使用 bash shell

docker run -it centos /bin/bash

这个时候可以看到命令行的前端已经变成了 [root@(一串 hash Id)] 的形式, 这说明我们已经成功进入了 CentOS 容器。 在容器内执行任意命令, 不会影响到宿主机, 如下

mkdir -p /data/simple_docker

可以看到 /data 目录下已经创建成功了 simple_docker 文件夹

ls /data

退出容器

exit

查看宿主机的 /data 目录, 并没有 simple_docker 文件夹, 说明容器内的操作不会影响到宿主机

ls /data

保存容器

查看所有的容器信息, 能获取容器的id

docker ps -a

然后执行如下命令,保存镜像:

docker commit -m="备注" 你的CONTAINER_ID 你的IMAGE

请自行将 -m 后面的信息改成自己的容器的信息

Docker的镜像操作命令

Docker 镜像命令

下载docker镜像

docker pull centos

查看本地所有镜像

docker imagesdocker image ls -a

启动镜像

docker run -it NAME:TAG /bin/bash  // 格式

docker run -it centos /bin/bash // 案列

运行 Docker 镜像(守护态方式)

docker run -d {镜像名}

查看镜像详细信息

docker inspect NAME:TAG  // 格式

删除指定 Docker 镜像

docker image rm {镜像名}

清理镜像(临时镜像和没有被使用的镜像)

docker image prune

创建镜像别名

docker tag IMAGEID{镜像id} REPOSITORY:TAG(仓库:标签)     // 格式

docker tag ccbcea8a6757 test:test     // 案列

Docker 容器命令

查看所有正在运行容器

docker ps

docker ps -a

列出所有容器(包括已停止容器)

docker ps -l

查看所有容器ID

docker ps -a -q 

进入运行中的 Docker 容器

docker exec -it {容器ID} /bin/bash

容器重命名

docker rename nginx-1 web-1     // 将nginx-1重新命名为web-1

启动已存在容器

docker start {容器ID}

停止指定容器

docker stop {容器ID}

删除指定容器

docker rm -f {容器ID}

删除停止的容器

docker container prune

所有容器的IP地址

docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

查看 Docker 容器历史运行日志

docker logs {容器名}

docker logs -f -t {容器ID} // -t 显示时间戳

Docker 文件操作命令

从主机复制文件到 Docker 容器中

sudo docker cp {主机内文件路径} {容器ID}:{容器内文件存储路径}

从 Docker 容器中复制文件到主机中

sudo docker cp {容器ID}:{容器内文件路径} {主机内文件存储路径}

Docker 数据卷命令

创建 Docker 数据卷

docker volume create {数据卷名}

列出所有 Docker 数据卷

docker volume ls

删除指定 Docker 数据卷

docker volume rm {数据卷名}

删除未关联(失效) Docker 数据卷

docker volume prune

docker volume rm $(docker volume ls -qf dangling=true)

删除指定容器

docker rm -f {容器ID}

删除停止的容器

docker container prune

查看 Docker 容器历史运行日志

docker logs {容器名}

docker启动镜像命令科普

docker run :创建一个新的容器并运行一个命令

语法

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
复制代码

OPTIONS说明:

  • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
  • -d: 后台运行容器,并返回容器ID;
  • -i: 以交互模式运行容器,通常与 -t 同时使用;
  • -P: 随机端口映射,容器内部端口随机映射到主机的端口
  • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  • --name="nginx-lb": 为容器指定一个名称;
  • --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
  • --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
  • -h "mars": 指定容器的hostname;
  • -e username="ritchie": 设置环境变量;
  • --env-file=[]: 从指定文件读入环境变量;
  • --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
  • -m :设置容器使用内存最大值;
  • --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
  • --link=[]: 添加链接到另一个容器;
  • --expose=[]: 开放一个端口或一组端口;
  • --volume , -v: 绑定一个卷

实例

使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。

docker run --name mynginx -d nginx:latest

使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。

docker run -P -d nginx:latest

使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。

docker run -p 80:80 -v /data:/data -d nginx:latest

绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。

docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。

docker run -it nginx:latest /bin/bash

Docker 部署 vue 项目

  1. 用 vue cli 创建一个vue项目,修改一下创建出来的项目,在页面上写一个前端接口请求,构建一版线上资源 ,基于nginx docker镜像构建成一个前端工程镜像,然后基于这个前端工程镜像,启动一个容器 vuenginxcontainer。
  2. 启动一个基于 node 镜像的容器 nodewebserver,提供后端接口。
  3. 修改 vuenginxcontainer 的 nginx 配置,使前端页面的接口请求转发到 nodewebserver 上。
  4. 稍作优化和改进。

创建 vue 应用

这里就不多说了,指路创建vue-cli3项目。注:项目中要有接口调用

打包项目

yarn build / npm run build

此时工程根目录下多出一个dist文件夹

如果将该dist目录整个传到服务器上,部署成静态资源站点就能直接访问到该项目。

构建vue应用镜像

nginx 是一个高性能的HTTP和反向代理服务器,此处我们选用 nginx 镜像作为基础来构建我们的vue应用镜像。

拉取Nginx的镜像

docker pull nginx

已经有了nginx镜像。我们根据nginx镜像运行容器

docker run --name=nginx -d -p 4030:80 nginx

然后在浏览器里面访问4030端口,验证容器是否运行正常

创建 nginx config配置文件

在项目根目录下创建nginx-docker文件夹,该文件夹下新建文件default.conf

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;
    error_log  /var/log/nginx/error.log  error;

    location /api/ {
        rewrite  /api/(.*)  /$1  break;
        proxy_pass http://172.18.0.3:9728;
    }
	
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
复制代码

该配置文件定义了首页的指向为 /usr/share/nginx/html/index.html, 所以我们可以一会把构建出来的index.html文件和相关的静态资源放到/usr/share/nginx/html目录下。

添加Dockerfile文件

FROM nginx
COPY dist/ /usr/share/nginx/html/
COPY nginx-docker/default.conf /etc/nginx/conf.d/default.conf
复制代码
  • 自定义构建镜像的时候基于Dockerfile来构建。
  • FROM nginx 命令的意思该镜像是基于 nginx:latest 镜像而构建的。
  • COPY dist/ /usr/share/nginx/html/ 命令的意思是将项目根目录下dist文件夹下的所有文件复制到镜像中 /usr/share/nginx/html/ 目录下。
  • COPY nginx/default.conf /etc/nginx/conf.d/default.conf 命令的意思是将nginx-docker目录下的default.conf 复制到 etc/nginx/conf.d/default.conf,用本地的 default.conf 配置来替换nginx镜像里的默认配置。

基于该Dockerfile构建vue应用镜像

文件上传以后 构建Vue程序的镜像(运行命令 注意不要少了最后的 “.” )

docker build -t dockervue .     // -t 是给镜像命名 . 是基于当前目录的Dockerfile来构建镜像

运行vue容器

基于 dockervue镜像启动容器,运行命令:

docker run --name=dockervue -d -p 9020:80 dockervue

  • docker run 基于镜像启动一个容器
  • -p 3000:80 端口映射,将宿主的3000端口映射到容器的80端口
  • -d 后台方式运行
  • --name 容器名 查看 docker 进程

可以看到容器在运行,我们在浏览器里面访问9020端口

目前为止,已经通过docker容器部署了一个静态资源服务,可以访问到静态资源文件。

构建node接口服务镜像

获取node镜像

docker pull node:alpine

编写Dockerfile将koa2项目docker化

# 引入node:alpine
FROM node:alpine
# 创建文件夹
RUN mkdir -p /usr/dockerfile/web/node
# 把当前目录所有内容拷贝到目录node  内容受.dockerignore影响
COPY . /usr/dockerfile/web/node
# 进入到app目录下面,类似cd
WORKDIR /usr/dockerfile/web/node
# 全局安装 pm2
RUN npm install pm2 -g
# 安装项目依赖
RUN npm install
# 暴露的端口
EXPOSE 9728
# 程序启动脚本
CMD ["npm", "prd"]
复制代码

构建镜像的时候 node_modules 的依赖直接通过 RUN npm install 来安装,项目中创建一个 .dockerignore文件来忽略一些直接跳过的文件:

node_modules
npm-debug.log
复制代码

构建镜像

docker build -t dockernode .

启动 docker-node 容器

#启动镜像 -d表示后台执行,-p 5000:9728 (9728:9728)表示(本机端口:容器端口),3000是笔者的nodejs代码中监听的访问端口,也是容器对外暴露的端口
docker run --name=dockernode -d -p 9728:9728 dockernode
#查看容器
docker ps
复制代码

跨域转发

想要将 vue容器 上的请求转发到 node 容器上。首先需要知道 node 容器的ip地址和端口,目前已知 node 容器内部服务监听在 9728端口,还需要知道ip即可。

查看 nodeserver 容器的 ip 地址

docker inspect [ containerId ] 直接查看容器信息:

 docker inspect 02277acc3efc

在其中找到 Networks 相关配置信息:

也可以查看所有容器的IP地址

docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

记录下node服务容器对应的ip,一会儿配置nginx转发的时候会用到。

修改 nginx 配置

  • Nginx 配置 location 指向 node 服务 default.conf (前端想要了解的Nginx,关于Nginx的配置已经 location 的具体写法可以参考(一文弄懂Nginx的location匹配))
  • 添加一条重写规则,将 /api/{path} 转到目标服务的 /{path} 接口上。 在前面的nginx-docker/default.conf文件中加入:
location /api/ {
  rewrite  /api/(.*)  /$1  break;
  proxy_pass http://172.17.0.2:8080;
}
复制代码

修改完了之后意识到一个问题:vue 容器是基于 dockervue这个镜像运行的,而在一开始构建镜像的时候是将 nginx配置 default.conf 直接构建进去了。因此如果需要修改 default.conf 还得再重新构建一个新的镜像,再基于新镜像来运行新的容器。

改进

能不能每次修改配置文件后直接重启容器就能让新配置生效,答案当然是有。

在构建镜像的时候 不把 Nginx 配置复制到镜像中,而是直接挂载到宿主机上,每次修改配置后,直接重启容器即可。

修改 Dockerfile 文件

把 vueclidemo 项目下的 Dockerfile 修改一下

FROM nginx
COPY dist/  /usr/share/nginx/html/
COPY nginx-docker/default.conf /etc/nginx/conf.d/default.conf
复制代码

COPY nginx-docker/default.conf /etc/nginx/conf.d/default.conf命令删除,nginx配置都通过挂载命令挂载在宿主机上。再看 COPY dist/ /usr/share/nginx/html/ 命令,如果每次构建的项目dist/下的内容变动都需要重新走一遍构建新镜像再启动新容器的操作,因此这条命令也可以删除,使用挂载的方式来启动容器。

新运行vue应用容器

直接基于nginx镜像来启动容器 vuenginxnew ,运行命令:

docker run \
-p 3000:80 \
-d --name vuenginxnew \
--mount type=bind,source=$HOME/SelfWork/docker/vueclidemo/nginx,target=/etc/nginx/conf.d \
--mount type=bind,source=$HOME/SelfWork/docker/vueclidemo/dist,target=/usr/share/nginx/html \
nginx
复制代码
  • --mount type=bind,source={sourceDir},target={targetDir} 将宿主机的sourceDir 挂载到容器的 targetDir 目录上。
  • 此处运行的命令较长,如果每次重新输入难免麻烦,我们可以将完整的命令保存到一个shell文件 vueapp.sh 中,然后直接执行 sh vueapp.sh

这样就能每次修改了nginx配置或者 重新构建了vue应用的时候,只需重启容器就能立马生效。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改