前言
在linux环境下,使用docker和nginx发布vue项目。假设你已配置好一台装有docker的linux虚拟机或者云服务器。
1. 打包vue项目
1.1. 创建vue项目
vue create myapp
创建好的项目结构如下:
1.2. 使用VS Code打开,并在终端执行npm run build命令打包vue项目:
执行完之后会在项目根目录生成一个dist文件夹,dist文件夹中包含了打包后的所有静态资源:
注意:
这里有个坑,打包好的index.html文件中引用的js、css文件可能是用的绝对路径,从而引用不到js和css文件,导致页面无法运行,如下图:
我们只需要去掉前面的/,或者在前面加个.就好了:
至此,vue项目就打包好了,接下来开始制作镜像。
2. 制作镜像
2.1. 编写Dockerfile
在项目根目录下创建一个Dockerfile文件,注意,Dockerfile文件必须以大写的D开头,且没有文件扩展名。
Dockerfile内容如下:
FROM nginx:latest
WORKDIR /app
COPY ./dist ./
RUN rm -rf /etc/nginx
EXPOSE 80
- FROM nginx:latest 表示docker容器使用的基镜像是nginx:latest,latest表示nginx的镜像版本为最新,你也可以使用指定版本,例如:nginx:1.25.3
- WORKDIR /app 设置工作目录为根目录下的app文件夹,如果根目录没有app文件夹,则会自动创建一个
- COPY ./dist ./ 将dist文件夹的发布文件拷贝到当前目录,由于WORKDIR /app指定了工作目录为/app,所以这里的./就等于/app
- RUN rm -rf /etc/nginx 表示删除/etc/nginx目录下的文件,该目录包含了nginx.conf文件,为什么要删除,是因为nginx.conf文件是经常要修改的文件,需要挂载到宿主机,修改时只需要修改宿主机的nginx.conf,不用每次都进入到容器中去修改。这里制作镜像时删除它会使镜像体积更小
- EXPOSE 80 设置容器的端口为80
2.2. 根据Dockerfile创建镜像
在Dockerfile文件所在目录打开终端,输入以下命令创建镜像:
docker build -t my-vue-app ./
- docker build 创建镜像的基本命令
- -t my-vue-app 设置镜像的名称为my-vue-app
- ./ Dcokerfile文件所在的目录,因为我们是在Dockerfile文件所在目录打开的终端,所以直接用./就可以了,如果在Dockerfile上一层,则可以写成:../
执行成功后使用docker images命令查看镜像列表:
镜像构建成功!
3. 运行容器
由于我们是在window上构建的镜像,那怎么把镜像弄到linux服务器中去呢?有两种方式,第一种,使用docker push命令将镜像推送到镜像仓库,然后在linux中使用docker pull命令拉取镜像;第二种,使用docker save命令将镜像保存为tar文件,将tar文件拷贝到linux服务器中,然后使用docker load还原成镜像。由于我这里做实验是用的云服务器,所以采用第二种方式。
3.1 保存镜像为tar文件
执行命令:
docker save -o my-vue-app.tar my-vue-app:latest
- docker save 导出镜像文件的基本命令
- -o my-vue-app.tar 输出到my-vue-app.tar文件
- my-vue-app:latest 从my-vue-app:latest这个镜像导出。注意,唯一确定一个镜像是:镜像名:tag ,一个镜像名可能对应多个tag。所谓的tag就是指镜像的版本。
如上图所示,执行成功后会在终端所在目录生成my-vue-app.tar文件,将这个拷贝到linux服务器中,可以借助WinSCP、WindTerm等远程连接工具来上传。
如上图所示,在linux中创建了目录/docker/image,并将my-vue-app.tar文件拷贝到该目录中。
3.2 从my-vue-app.tar还原镜像
运行以下命令:
docker load -i my-vue-app.tar
- docker load 从tar文件还原镜像的基本命令
- -i my-vue-app.tar 表示从my-vue-app.tar文件还原镜像
使用docker images命令查看是否还原成功
可以看到,镜像列表中已经包含my-vue-app镜像。
3.3 运行容器
运行以下命令:
docker run -d -p 80:80 --name=my-vue-app-container -v /docker/volume/nginx:/etc/nginx my-vue-app:latest
- docker run 运行容器的基本命令
- -d 表示在后台执行,如果你想将终端焊住,可以用-it
- -p 80:80 将宿主机的80端口映射到容器中的80端口,格式是:-p 宿主机端口:容器端口
- –name=my-vue-app-container 设置容器的名称为my-vue-app-container
- -v /docker/volume/nginx:/etc/nginx 挂卷,/docker/volume/nginx表示挂载的主机目录,/etc/nginx表示容器内的数据卷。这里的挂卷主要是把容器中/etc/nginx目录下的nginx.conf配置文件挂载出来。以便于后面直接在宿主机上修改。这样,修改宿主机目录/docker/volume/nginx下的文件也会同步修改容器内的目录/etc/nginx文件,可以理解为容器内目录/etc/nginx引用了宿主机目录/docker/volume/nginx(类似C#/Java中的对象引用)
- my-vue-app:latest 运行容器所使用的镜像
如上图所示,容器创建成功,使用docker ps --all查看容器列表:
我们发现容器的状态并不是Running状态,这时我们可以通过docker logs命令来查看容器运行日志:
从错误日志,基本可以定位错误了,nginx在/etc/nginx目录中没有找到nginx.conf文件,这是因为在2.1中制作镜像时在Dockerfile中执行了RUN rm -rf /etc/nginx,导致该目录下的文件都被删除了,目的是让镜像体积更小。怎么解决这个问题呢?这时候挂卷的作用就来了,还记得docker run中的-v /docker/volume/nginx:/etc/nginx选项吗,冒号(:)前面的路径/docker/volume/nginx就是挂载在宿主机的路径,我们只需要将配置文件拷贝到这个目录就行了。
从nginx官方文档下载nginx,下载地址:nginx download
下载在本地后解压:
将conf文件夹中的文件拷贝到linux服务器中的/docker/volume/nginx目录中
使用vim修改一下nginx.conf中的location配置,将访问目录设置到/app
为什么是/app? 还记得步骤2.1的Dockerfile中的WORKDIR /app和COPY ./dist ./指令吗,是因为我们将vue打包的静态文件都放在/app目录下的,所以将nginx.conf的root指向/app。
保存,重启容器:
docker restart 8f5ff03f6777
- docker restart 8f5ff03f6777 8f5ff03f6777为容器的ID,容器ID是随机生成的,这以你自己容器ID为准。
因为是80端口,直接用服务器的IP即可访问:
访问成功!