您当前的位置:首页 > 电脑百科 > 程序开发 > 前端

使用 Docker + Nginx 部署前端项目

时间:2023-09-18 14:05:16  来源:  作者:前端24

前端项目除了目前的纯单页应用,还有SSR的应用,例如 nuxt 和 nextjs,其区别在于前者是单独的前端页面部署,而后者使用了一个内部的 node 小型服务器来做到服务器页面直出的效果。

下面我们就针对这两种常见的前端项目,讲讲他们上线部署的流程。

部署单页应用

单页应用,一般使用一种或多种前端框架,在发布上线时,一般会打包(webpack + babel)为最优化的静态资源,然后使用单独的服务器(Nginx)来挂载该资源。

  • 首先我们来打包资源

假设我们的项目叫 ops,其中 package.json 是这么写的:

"build": "react-scripts build",

在项目根目录中写一个脚本用于打包文件:build.sh:

## 打包的脚本(只展示必要步骤)
#!/usr/bin/env bash

## 接受 ENV
env=$1

## 这里可以区分开发和线上的不同env配置文件,一般是请求的资源和API的url不同
if [ $env = "pre" ];then
    cp .env_pre .env
elif [ $env = "prod" ];then
    cp .env_prod .env
else
    exit 1
fi

# yarn打包
yarn build

# 打包Docker镜像
# 默认推送到 hub.xxx.com/ops

time=$(date "+%Y%m%d%H%M%S")
tag="$time"

App_name=ops"_""$env"
default_registry=hub.xxx.com
default_project=ops
default_user=admin
default_pwd=xxxxxxxx
dockerfile=Dockerfile
nginx_conf="./scripts/nginx_""$env"".conf"

echo $(date "+%Y-%m-%d %H:%M:%S")-开始制作镜像
docker build --platform linux/amd64 --rm --build-arg NGINX_CONF=$nginx_conf -t $app_name:latest . 
echo $(date "+%Y-%m-%d %H:%M:%S")-镜像制作完成

echo $(date "+%Y-%m-%d %H:%M:%S")-开始打tag
docker tag $app_name:latest $default_registry/$default_project/$app_name:$tag
echo $(date "+%Y-%m-%d %H:%M:%S")-打tag完成

echo $(date "+%Y-%m-%d %H:%M:%S")-开始push镜像
docker login -u $default_user -p $default_pwd $default_registry
docker push $default_registry/$default_project/$app_name:$tag
echo $(date "+%Y-%m-%d %H:%M:%S")-push镜像完成

echo $(date "+%Y-%m-%d %H:%M:%S")-删除本地镜像
docker rmi $app_name:latest
docker rmi $default_registry/$default_project/$app_name:$tag

echo "执行发布脚本请输入tag:"
echo $tag

其中 docker 的登录用户名密码需要自己配置即可。Dockerfile如下:

FROM nginx:1.19.1
ARG NGINX_CONF=""

# 服务器上资源的地址
WORKDIR /data/ops

# 往目录里拷贝打包的文件夹 build,这是最关键的一步
ADD build build

# 这里在docker里执行了nginx配置,这里不使用默认配置
COPY ./scripts/run.sh ./
COPY "${NGINX_CONF}" /etc/nginx/conf.d/default.conf

EXPOSE 80
ENTRYPOINT ["sh", "./run.sh"]  

上边执行的 run.sh 脚本我这里是从客户端拷贝到了服务器上,当然也可以直接写在服务器中,其作用是启动docker镜像上的 nginx(安装目录 /etc/init.d/nginx,nginx配置这里省略)。run.sh 如下:

#!/usr/bin/env bash

#start udnr web...
/etc/init.d/nginx start

其中本地的 nginx配置文件 nginx_conf="./scripts/nginx_""$env"".conf" 是用于 docker 容器内部的 nginx,覆盖默认配置。这里我配置了服务的请求路径以及开发环境和生产环境的请求API地址的反向代理,这里不过多展开:

## ./scripts/nginx_prod.conf 为例
upstream dashboard {
    server 10.69.164.xxx:21001;
}

...

location / {
    try_files   /index.html =404;
    root        /data/ops/build;
}

location ~ .*.(js|gif|png|map|jpg|css|ico|html|less)$ {
    root            /data/ops/build;
    proxy_redirect  off;
    expires         30d;
    error_page 405  =200 http://$host$request_uri;
}

location /dashboard {
    proxy_pass         http://dashboard/;
    proxy_set_header   Host $Host;
}

build.sh 脚本执行完毕后,会生成一个挂载了项目build资源的Docker镜像,并输出了其 Tag。

  • 接下来我们来部署这个 docker 镜像

刚刚的操作都是在客户端操作的(可以手动执行脚本,也可以写在CI里)。现在我们登录服务器:

ssh root@172.xx.xxx.72

cd /data/ops/

其中 deploy.sh:

#!/bin/bash
if [ ! -n "$1" ]
then
echo "You should give me a image tag."
else
echo "The image tag is $1"

oldtag=`cat .env`

## 获取上一次成功的tag,便于在打包失败时及时回退
echo "The old image tag is $oldtag"

path=$(pwd)

# 记录新的tag到容器的.env中
sed -i "s/$oldtag/TAG=$1/g" $path/.env

# docker-compose config
docker login -u ops -p 你的密码 hub.xxx.com
# 重新启动容器,因为 build 文件夹替换了,所以是最新的打包信息
docker-compose up -d

fi

现在在服务器上执行:

sh deploy.sh tag名称

此时在服务器上就启动起来了一个前端单页应用了,可以通过ip+端口号来访问了。

部署SSR应用

SSR前端框架我们以 nextjs 为例来讲一下如何与 docker 结合部署。

  • 首先来部署打包应用

假设项目的 package.json是这么写的:

"scripts": {
    "build": "next build --profile",
    "start": "next start",
}

nextjs部署到服务器时,需要先 yarn build,然后在打好包的 .next 同目录上执行 yarn start 以此来启动一个小型的SSR直出服务器。

明白了这个后,我们首先来打包。打包的操作除了写在shell里,也可以直接写在 Dockerfile 里:

# 安装一些linux系统必须的依赖和配置环境,并为下一步build安装node_modules
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# 拷贝打包需要的资源,执行build。默认的,build完后,当前目录下会有一个.next目录生成
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn build && yarn install --production --ignore-scripts --prefer-offline

# 添加用户组
FROM node:alpine AS runner
WORKDIR /app

ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# 打包以后,一些配置文件在打包的目录下没有,需要手动copy
COPY --from=builder /app/next.config.js ./                      # next的配置文件
COPY --from=builder /app/next-i18next.config.js ./              # 如果需要next-i18next支持,这里也需要拷贝自己在根目录放置的配置文件

COPY --from=builder --chown=nextjs:nodejs /app/public ./public  # 公共资源
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next    # 打包后的源代码
COPY --from=builder /app/node_modules ./node_modules            # 安装好的依赖
COPY --from=builder /app/package.json ./package.json            # 包信息

可以看到 docker 是很强大的,一个文件就把依赖安装、build和资源拷贝完成了。

  • 接下来是启动打包的项目

由于nextjs内置的node服务,直接可以 next start 启动,故不需要额外配置 nginx。可以在上边的Dockerfile 里追加启动的指令:

# 使用刚刚添加的用户
USER nextjs

# 暴露docker端口3000
EXPOSE 3000

ENV PORT 3000

# 执行 yarn start
CMD ["yarn", "start"]

到此,一个 nextjs 应用就在服务器的 3000 端口启动起来了。

流程总结如下:

  1. 使用docker或者shell进行打包,获取打包的资源文件目录
  2. 将资源文件、配置项、依赖等拷贝到docker容器中自定义的工作目录下
  3. 在docker该工作目录下执行指令启动docker中的nginx或者其他的服务器

文章出自:https://juejin.cn/post/7204646143543033916

作者:小肚肚肚肚肚哦



Tags:前端   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
20k级别前端是怎么使用LocalStorage的,想知道吗?
当咱们把咱们想缓存的东西,存在localStorage、sessionStorage中,在开发过程中,确实有利于咱们的开发,咱们想看的时候也是一目了然,点击Application就可以看到。前言大家好,我是林...【详细内容】
2024-03-26  Search: 前端  点击:(11)  评论:(0)  加入收藏
前端不存在了?盲测64%的人更喜欢GPT-4V的设计,杨笛一等团队新作
3 月 9 日央视的一档节目上,百度创始人、董事长兼 CEO 李彦宏指出,以后不会存在「程序员」这种职业了,因为只要会说话,人人都会具备程序员的能力。「未来的编程语言只会剩下两种...【详细内容】
2024-03-11  Search: 前端  点击:(9)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown —— 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  Search: 前端  点击:(11)  评论:(0)  加入收藏
两年前端经验还不会手写Promise?
什么是promise?当我们处理异步操作时,我们经常需要进行一系列的操作,如请求数据、处理数据、渲染UI等。在过去,这些操作通常通过回调函数来处理,但是回调函数嵌套过多会导致代码...【详细内容】
2024-03-07  Search: 前端  点击:(23)  评论:(0)  加入收藏
十个前端冷门但好用的前端工具函数库
本文推荐十个冷门但好用的前端工具函数仓库,它们可能没有很高的知名度,但却能为你解决实际问题,提高开发效率。在前端开发中,有时候我们会遇到一些常见的功能需求,但却不知道从哪...【详细内容】
2024-02-27  Search: 前端  点击:(21)  评论:(0)  加入收藏
前端开发:Visual Studio Code和Visual studio如何选?
Visual Studio Code和Visual studio都是微软的集成开发环境(IDE),那么在实际工作中该如何选择呢。贝格前端工场对二者做一番对比,帮助您决策一下。一、Visual Studio Code的介绍...【详细内容】
2024-02-27  Search: 前端  点击:(46)  评论:(0)  加入收藏
网站开发中的前端和后端开发有什么区别
前端开发和后端开发都是干什么的?有哪些区别?通俗地讲,前端干的工作是用户可以直接看得见的,而后端开发的工作主要在服务端,用户不太能直接看到。虽然前端开发和后端开发的工作有...【详细内容】
2024-02-21  Search: 前端  点击:(31)  评论:(0)  加入收藏
一段微信小程序前端与后端连接的代码,带注解
微信小程序的前端和后端连接通常涉及到使用微信小程序提供的网络请求API与后端服务器进行通信。以下是一个简单的示例,展示如何使用微信小程序的前端代码向后端发送请求并处...【详细内容】
2024-01-24  Search: 前端  点击:(55)  评论:(0)  加入收藏
如何优雅的实现前端国际化?
JavaScript 中每个常见问题都有许多成熟的解决方案。当然,国际化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 库可供选择,下面就来分享一些热门的前端国际化库!i18nexti18ne...【详细内容】
2024-01-17  Search: 前端  点击:(68)  评论:(0)  加入收藏
JavaScript前端框架2024年展望
Angular、Next.js、React和Solid的维护者和创作者们展望2024年,分享了他们计划中的改进。译自2024 Predictions by JavaScript Frontend Framework Maintainers,作者 Loraine...【详细内容】
2024-01-05  Search: 前端  点击:(89)  评论:(0)  加入收藏
▌简易百科推荐
20k级别前端是怎么使用LocalStorage的,想知道吗?
当咱们把咱们想缓存的东西,存在localStorage、sessionStorage中,在开发过程中,确实有利于咱们的开发,咱们想看的时候也是一目了然,点击Application就可以看到。前言大家好,我是林...【详细内容】
2024-03-26  前端之神  微信公众号  Tags:前端   点击:(11)  评论:(0)  加入收藏
前端不存在了?盲测64%的人更喜欢GPT-4V的设计,杨笛一等团队新作
3 月 9 日央视的一档节目上,百度创始人、董事长兼 CEO 李彦宏指出,以后不会存在「程序员」这种职业了,因为只要会说话,人人都会具备程序员的能力。「未来的编程语言只会剩下两种...【详细内容】
2024-03-11  机器之心Pro    Tags:前端   点击:(9)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown —— 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  OSC开源社区    Tags:Vue   点击:(11)  评论:(0)  加入收藏
两年前端经验还不会手写Promise?
什么是promise?当我们处理异步操作时,我们经常需要进行一系列的操作,如请求数据、处理数据、渲染UI等。在过去,这些操作通常通过回调函数来处理,但是回调函数嵌套过多会导致代码...【详细内容】
2024-03-07  海燕技术栈  微信公众号  Tags:Promise   点击:(23)  评论:(0)  加入收藏
网站开发中的前端和后端开发有什么区别
前端开发和后端开发都是干什么的?有哪些区别?通俗地讲,前端干的工作是用户可以直接看得见的,而后端开发的工作主要在服务端,用户不太能直接看到。虽然前端开发和后端开发的工作有...【详细内容】
2024-02-21  CarryData    Tags:前端   点击:(31)  评论:(0)  加入收藏
网站程序开发中的前后端分离技术
随着互联网的快速发展和技术的不断创新,传统的网站开发模式已经难以满足日益增长的业务需求。为了提高开发效率、增强系统的可维护性和可扩展性,前后端分离技术逐渐成为了网站...【详细内容】
2024-01-31  网站建设派迪星航    Tags:前后端分离   点击:(23)  评论:(0)  加入收藏
如何优雅的实现前端国际化?
JavaScript 中每个常见问题都有许多成熟的解决方案。当然,国际化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 库可供选择,下面就来分享一些热门的前端国际化库!i18nexti18ne...【详细内容】
2024-01-17  前端充电宝  微信公众号  Tags:前端   点击:(68)  评论:(0)  加入收藏
Vue中Scope是怎么做样式隔离的?
scope样式隔离在 Vue 中,样式隔离是通过 scoped 特性实现的。当在一个组件的 <style> 标签上添加 scoped 特性时,Vue 会自动为这个样式块中的所有选择器添加一个唯一的属性,以...【详细内容】
2024-01-04  海燕技术栈  微信公众号  Tags:Vue   点击:(80)  评论:(0)  加入收藏
vue3中 ref和 reactive的区别 ?
最近有朋友在面试过程中经常被问到这么一个问题,vue3 中的ref 和 reactive的区别在哪里,为什么 要定义两个API 一个 api不能实现 响应式更新吗??带着这个疑问 ,我们 接下来进行逐...【详细内容】
2024-01-03  互联网高级架构师  今日头条  Tags:vue3   点击:(37)  评论:(0)  加入收藏
React18 与 Vue3 全方面对比
1. 编程风格 & 视图风格1.1 编程风格 React 语法少、难度大;Vue 语法多,难度小例如指令:Vue<input v-model="username"/><ul> <li v-for="(item,index) in list" :key="inde...【详细内容】
2024-01-03  爱做梦的程序员  今日头条  Tags:Vue3   点击:(72)  评论:(0)  加入收藏
站内最新
站内热门
站内头条