日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上

文章目录

  • 需求描述
  • 开始操作
    • 准备阶段:准备 server.js 文件并安装依赖,将 vue 项目包装成单独的服务器
      • 制作 server.js
      • 安装 server.js 需要的依赖
    • 构建 Dockerfile
    • heroku container 链接和部署
    • 其他细节

需求描述

  • 你想用 vue 构建前端,用 django 构建后端,并且你不想用一个服务器来运行整个项目,而是想分开两个服务器部署
  • 通过 heroku 来部署有三种方式
    • 本地项目文件夹直接关联 heroku 远程仓库,push 上去自动开展部署
    • 本地项目文件夹关联 github 远程仓库,github 远程仓库关联 heroku,每次 github push 自动部署
    • 本地项目文件夹直接构建 dockerfile,然后关联 heroku container,通过 heroku container 进行部署
  • 只有前端页面的话是无法部署的,所以准备阶段我们需要再 vue 中加一个 server.js 来将前端项目打包成一个服务器,然后整体部署

开始操作

准备阶段:准备 server.js 文件并安装依赖,将 vue 项目包装成单独的服务器

制作 server.js

.
├── README.md
├── babel.config.js
├── img.png
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
├── server.js
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   ├── http.js
│   ├── main.js
│   ├── pages
│   └── router
├── todo.md
├── vue.config.js

  • 路径方面需要注意,server.js 是直接放在你的 vue 的根目录底下,也就是最外层
const express = require('express');
const serveStatic = require('serve-static');
const path = require('path');

const app = express();

app.use('/', serveStatic(path.join(__dirname, '/dist')));
// 处理 SPA 的路由回退,确保重定向到 index.html
app.get('*', function (req, res) {
    res.sendFile(path.join(__dirname, '/dist', 'index.html'));
});
const port = process.env.PORT || 16000;
app.listen(port);

console.log('Listening on port: ' + port);

安装 server.js 需要的依赖

  • 这一步是为了将这两个构建服务器需要的 package 写入 package.json,部署的时候方便
npm install express --save
npm install serve-static

构建 Dockerfile

  • 也是在 vue 项目目录的最外层(与 server.js同级),写入如下 Dockerfile
# 第一阶段:构建 =========================================
# 1. 指定平台,因为我本机是 mac 芯片的,而 docker 默认环境是 linux 所以我转换一下平台
# 2. 使用 Node.js 官方镜像作为构建环境, node:14 表示 node 的版本是 14
FROM --platform=linux/amd64 node:14 as build-stage

# 设置工作目录,设置了之后就可以直接使用 . 来表示 docker 中的 /app
WORKDIR /app

# 拷贝 package.json 和 package-lock.json (如果存在)
# COPY A B 是将 A文件夹或者文件拷贝到 B 文件夹或文件,下面命令中第二个位置是 ./ 代表将当前本地目录下 package.json 拷贝到 docker 的工作目录下,相当于 COPY package*.json /app
COPY package*.json ./

# 安装项目依赖
RUN npm install

# 拷贝项目文件和文件夹到工作目录
COPY . .

# 构建应用
RUN npm run build
# ======================================================

# 第二阶段:运行
# 再次使用 Node.js 镜像
FROM --platform=linux/amd64 node:14

# 设置工作目录
WORKDIR /app

# 将构建产物从构建阶段拷贝过来,因为docker 构建是层级结构, 所以相当于从上一层的缓存中 copy 过来
COPY --from=build-stage /app/dist /app/dist
COPY --from=build-stage /app/node_modules /app/node_modules
# 拷贝 server.js 
COPY server.js ./

# 暴露 80 端口
EXPOSE 80

# 启动应用
CMD ["node", "server.js"]

问题:这个项目里面为什么先 COPY package*.json ./ 再 COPY . ., 这两部分似乎可以合并

在 Dockerfile 中,将 COPY package*.json ./COPY . . 分开的原因是为了更有效地利用 Docker 的层级缓存机制。这种做法可以在某些情况下显著提高构建速度,尤其是在进行频繁的构建时。下面是详细解释:

层级缓存机制:

  • 当 Docker 构建镜像时,它会按照 Dockerfile 中的指令逐层构建,并为每一层生成一个缓存。
    如果某一层没有发生变化,Docker 就会重用这一层的缓存,而不是重新构建它。

优化依赖项安装:

  • 通过首先只复制 package.jsonpackage-lock.json 文件,然后运行 npm install,可以确保只有当这些文件发生变化时(即依赖项发生变化),Docker 才会重新安装依赖项。
  • 如果直接复制整个项目目录,那么任何文件的变化都会导致 Docker 无法使用缓存的依赖项层,因此即使只是源代码的一个小改动,也会导致 Docker 需要重新运行 npm install

提高构建效率:
在开发过程中,源代码的变化比依赖项的变化要频繁得多。因此,分开复制可以在大多数构建中避免不必要地重新安装依赖项,从而加快构建速度。
综上所述,尽管从技术上讲,将 COPY package*.json ./COPY . . 合并为一个步骤是可行的,但分开这两个步骤可以更好地利用 Docker 的层级缓存,从而提高构建效率,特别是在频繁的开发和构建过程中。

heroku container 链接和部署

  • 打开 heroku 并登录,create 一个 new app,这一步可以在 heroku 网站或者通过命令行完成
    日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上_第1张图片

  • 找到 deploy,并选择 container registry
    日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上_第2张图片

  • 接下来就是按照步骤执行,需要注意的是,你在 terminal 进行倒数两条命令的时候,一般需要再后面指定你的具体的 heroku app 名称,比如我在 heroku 上创建的 app 叫 alpha 那么我的命令就需要对应的改成

    heroku container:push web -a alpha
    heroku container:release web -a alpha
    

其他细节

  • 如果你需要和后端部署的服务器进行关联,那么请注意你的 vue 项目中链接后端项目的地址一定要对应的改好,注意点包括但不限于下面几点:
    • http -> https 如果后端部署到了服务器上,访问后端 api 的时候,就要使用 https 前缀
    • ws -> wss 对应的,如果建立 websocket 链接,就使用 wss 前缀
      在这里插入图片描述
      日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上_第3张图片
      日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上_第4张图片

你可能感兴趣的:(前端,学习,vue.js)