如何将 Vue 项目打包为 docker

本文在安装了 Docker 的 Linux 或 WSL 环境下可用

配置文件

Vue 配置

首先需要在 Vue 项目的 .env 文件中配置项目路径,以保证建项目后资源路径正确。同时特别关注配置的端口号,接下来将用 Nginx 监听该端口

1
2
3
4
5
6
7
8
# port 端口号
VITE_PORT = 8888

# open 运行 npm run dev 时自动打开浏览器
VITE_OPEN = false

# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
VITE_PUBLIC_PATH = ./

然后,在 Vue 项目目录输入 npm run bulid ,随后会生成 dist 文件夹,内容是 Vue 项目的静态文件,拷贝该文件到你喜欢的任意目录文件夹下。下文假设该文件夹叫做 /docker-bulid

Nginx 配置

docker-bulid 文件夹中新建 nginx.conf 文件,内容配置如下

注意,Nginx 监听的端口号必须与你在 Vue 项目中配置的一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;
}

http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

include /etc/nginx/conf.d/*.conf;

server {
listen 8888 default_server; # 让 Nginx 监听你的 Vue 项目所配置的那个端口
listen [::]:8888 default_server;# IPv6: 让 Nginx 监听你的 Vue 项目所配置的那个端口
server_name localhost;
root /usr/share/nginx/html;
index index.html;
include /etc/nginx/default.d/*.conf;

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

}

Dockerfile 配置

docker-bulid 文件夹中新建 Dockerfile 文件,内容配置如下

注意,Dockerfile 一定不要写错,”D”是大写,”f”是小写,且没有文件扩展后缀

1
2
3
4
5
6
7
8
9
10
11
12
13
# 基础镜像使用Nginx
FROM nginx
# 作者
LABEL maintainer=="lgh"
# 添加时区环境变量,亚洲,上海
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' > /etc/timezone \
# 将前端dist文件中的内容复制到nginx目录
COPY ./dist/ /usr/share/nginx/html/
# 用本地的nginx配置文件覆盖镜像的Nginx配置
COPY nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 5438

文件树

最后,你的 docker-bulid 文件夹应该是这样的:

1
2
3
4
5
6
7
docker-bulid
├── dist
│   ├── assets
│   ├── favicon.ico
│   └── index.html
├── Dockerfile
└── nginx.conf

生成镜像

请保证已经用 systemctl start docker 指令开启了 docker,通过 systemctl status docker 可以确认

通过 cd 指令确保控制台在 docker-bulid 目录下,输入指令 sudo docker build -t my_project ./ 以生成镜像。其中,my_project 是镜像名,./ 是 Dockerflie 所在的目录。以下是一个运行的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@localhost vue_project]# docker build -t vue_project ./
Sending build context to Docker daemon 8.062MB
Step 1/6 : FROM nginx
latest: Pulling from library/nginx
3f4ca61aafcd: Pull complete
50c68654b16f: Pull complete
3ed295c083ec: Pull complete
40b838968eea: Pull complete
88d3ab68332d: Pull complete
5f63362a3fa3: Pull complete
Digest: sha256:0047b729188a15da49380d9506d65959cce6d40291ccfb4e039f5dc7efd33286
Status: Downloaded newer image for nginx:latest
---> 1403e55ab369
Step 2/6 : LABEL maintainer=="lgh"
---> Running in 8839c3da3940
Removing intermediate container 8839c3da3940
---> 7bf71c93c97e
Step 3/6 : ENV TimeZone=Asia/Shanghai
---> Running in 100ad607f2a4
Removing intermediate container 100ad607f2a4
---> 6a31f88af644
Step 4/6 : COPY ./dist/ /usr/share/nginx/html/
---> 220ce4e38858
Step 5/6 : COPY nginx.conf /etc/nginx/nginx.conf
---> f8eefdf56042
Step 6/6 : EXPOSE 5438
---> Running in a4387c21f14a
Removing intermediate container a4387c21f14a
---> 7e1f6c0fb0da
Successfully built 7e1f6c0fb0da
Successfully tagged vue_project:latest

然后,通过 docker image lsdocker images 指令来查看镜像是否创建成功

1
2
3
4
[root@localhost vue_project]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
vue_project latest 40037756824a 3 seconds ago 150MB
nginx latest 1403e55ab369 2 weeks ago 142MB

启动容器

上一节我们已经创建了镜像,接下来需要根据这个镜像启动容器,使用以下命令以 vue_project 镜像启动一个容器:

1
sudo docker run -itd -p 5438:80 --name="vue_test" vue_project:latest
  • -i: 以交互模式运行容器,通常与 -t 同时使用;
  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  • -d: 后台运行容器,并返回容器 ID;
  • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
  • –name=”{str}”: 为容器指定一个名称;

运行完毕后控制台会返回一个容器 id ,可使用指令 docker ps -a 查看所有容器的基本情况

1
2
3
[root@localhost vue_project]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f69524fd34a vue_project:latest "/docker-entrypoint.…" 7 seconds ago Up 5 seconds 5438/tcp, 0.0.0.0:5438->80/tcp, :::5438->80/tcp vue_test

在这个例子中,我们用 docker 将 5438 端口映射到了 Nginx 代理的 80 端口上。因此容器确认运行以后,浏览器访问运行该容器的服务器的 5438 端口即可访问这个 Vue 生成的网页。

至此,Vue 项目的 docker 部署过程久结束了。

如何更新镜像

最好的更新容器方式是使用 docker hub 或自建 docker 仓库,通过和 git 类似的 push/pull 模式进行版本控制。但是有时时间紧迫或环境不支持,可用以下方式更新容器内容。下文同样以上一节的项目为例。

停止容器并删除旧的容器/镜像

以下操作需要按照顺序执行

停止容器

通过 docker ps -a 找到需要停止的容器 id,例子中是 3f69524fd34a ,然后运行以下指令

1
sudo docker stop 3f69524fd34a

删除容器

运行以下指令

1
sudo docker rm 3f69524fd34a

删除镜像

通过 docker images 找到需要停止的镜像 id,例子中是 40037756824a ,然后运行以下指令

1
sudo docker rmi 40037756824a

替换 dist 文件夹

将更新后重新构建的新 dist 文件夹替换 /docker-bulid 中的旧文件夹即可,一般 nginx.confDockerfile 无需改动

重新生成镜像/容器

参考生成镜像部分操作即可