如何使用docker + nginx来部署前端项目
大致流程如下:如果你是在云服务器上,比如阿里云、腾讯云之类,要注意打开安全组和防火墙的端口号,不然无法访问原文链接:https://juejin.cn/post/7441584637142499362。
本文不教如何安装docker,默认已安装好docker。这是我的docker版本,在我本地安装的。
docker 基本操作
docker的命令远远不止这些,本文只讲需要用到的。
docker pull 拉取nginx镜像
如果你之前用nginx部署过前端项目的话,用docker部署你就会发现更简单。
bash
代码解读
复制代码
docker pull nginx
等待pull
完成,pull
成功之后,可以用docker images
查看一下
可以看到nginx已经成功下载了。
docker run 启动nginx镜像
bash
代码解读
复制代码
docker run -d -p 80:80 --name nginx nginx
-d
: 让容器后台运行(detached mode)-p 80:80
: 前面80是宿主机的端口号,后面80是容器的端口号,意思是将宿主机的80端口映射到容器的80端口。当访问宿主机的80端口时,请求会被映射到容器内的Nginx服务的80端口,从而能够访问到Nginx服务。--name nginx
: 设置容器的名称,方便后续对该容器进行管理操作,例如停止、启动或删除容器时,可以通过这个名称来指定操作的容器对象,名字随便取,叫什么都可以。nginx
: 镜像名称
启动之后,终端会输出对应的容器id,说明已经启动成功。也可以用docker ps
查看一下
docker ps 查看运行中的容器
可以看到,有一条nginx
的容器正在运行,这个容器的id
是84
开头,正是我们刚刚执行docker run
返回的那个容器id
。
打开浏览器,输入localhost
,可以看到下面的默认页面,恭喜你,已经成功用docker启动nginx了。
http端口号默认80,所以可以省略端口号,如果你映射的是其他端口号,记得带上端口号
如果你是在本地电脑上安装的docker
,搭配docker
官方提供的Docker Desktop
桌面端,使用起来更方便。上面所有的命令,在Docker Desktop
里面都有对应的可视化操作。
docker stop
bash
代码解读
复制代码
docker stop <容器名/容器ID>
这里要注意是容器名称,不是镜像名称,就是前面我们执行docker run
命令后面带的参数--name nginx
的nginx
。
执行docker stop nginx
,可以看到返回了容器的名称。然后docker ps
再查看一下运行的容器,发现并没有nginx
容器里。
再刷新一下浏览器看看
部署
创建项目
bash
代码解读
复制代码
npm create vite@latest
依次执行
bash
代码解读
复制代码
cd docker-fe-demo npm install run run dev
在App.tsx里面随便写一点代码,保持。
tsx
代码解读
复制代码
function App() { return <>hello sens</>; } export default App;
页面正常渲染了
编写Dockerfile--多阶段构建
在项目根目录新建一个Dockerfile和docker.nginx.conf文件。
Dockerfile是固定名字,类似于webpack.config.js,docker.nginx.conf自己随便取,但是要保证.conf结尾
我的做法是把nginx的conf配置文件暴露出来,放到前端,方便修改,最后copy进去,丢到nginx对应配置文件的地方。当然,你也可以不放到前端,写死在nginx里面也行。
Dockerfile
代码解读
复制代码
# build 阶段 FROM node:18-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm config set registry https://registry.npmmirror.com/ RUN npm install COPY . . RUN npm run build # production 阶段 FROM nginx:stable as production-stage COPY --from=build-stage /app/dist /usr/share/nginx/html COPY --from=build-stage /app/docker.nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
解释一下这份配置文件,把镜像分成了两个阶段(FROM了两次),build阶段和production阶段。最终镜像产物就是最后一个FROM的镜像,这里最后FROM了nginx,相当于生成了一份nginx的镜像。
build阶段
WORKDIR /app
: 设置容器内的工作目录为/app
,后续的操作(如复制文件、运行命令等)都将在这个目录下进行。COPY package*.json ./
: 将主机上与package
相关的json
文件(通常是package.json
和package-lock.json
)复制到容器内的/app
目录下。这一步是为了先安装项目依赖RUN npm config set registry https://registry.npmmirror.com/
: 设置npm淘宝源RUN npm install
: 执行npm installCOPY . .
:将(主机)当前目录下的所有文件复制到容器内的/app
目录下。RUN npm run build
:在容器内运行npm run build
命令,构建项目(通常是将源代码编译、打包等操作)。
build阶段完成之后,我们可以得到打包之后的dist文件了,后面只要把这份文件,丢给nginx
即可。
production阶段
COPY --from=build-stage /app/dist /usr/share/nginx/html
: 将build-stage
阶段构建的/app/dist
复制到/usr/share/nginx/html
目录(为什么是/usr/share/nginx/html目录呢?后面说)COPY --from=build-stage /app/docker.nginx.conf /etc/nginx/conf.d/default.conf
: 同理,将build-stage
阶段构建的/app/docker.nginx.conf
复制到/etc/nginx/conf.d/default.conf
。EXPOSE 80
:容器暴露80端口。CMD ["nginx", "-g", "daemon off;"]
:启动nginx
服务器,并关闭守护进程模式,以便容器可以持续运行并提供服务。
上面多了两个很陌生的文件目录地址,/usr/share/nginx/html
和/etc/nginx/conf.d/default.conf
。了解nginx的朋友应该知道这是什么意思。 一开始我们已经pull nginx镜像,并且将nginx运行起来,现在让我们进入到nginx容器里面。
bash
代码解读
复制代码
docker exec -it nginx /bin/bash
这里也可以看到,是我们之前84
开头的nginx容器。 然后执行:
bash
代码解读
复制代码
cat /etc/nginx/nginx.conf
打印一下nginx的配置信息。
可以看到,有这样的一项配置,include /etc/nginx/conf.d/*.conf;
它的意思是/etc/nginx/conf.d/
目录下所有以.conf
为后缀的配置文件都会引入到主配置文件中使其生效。 那让我们去/etc/nginx/conf.d/
目录看看。
bash
代码解读
复制代码
cd /etc/nginx/conf.d/ ls cat default.conf
圈中的意思是指定root(根)目录是/usr/share/nginx/html
,当收到一个请求的时候,就会去指定的root目录里面找对应的index文件。
再进入到/usr/share/nginx/html
里面看看:
bash
代码解读
复制代码
cd /usr/share/nginx/html ls cat index.html
这不正是我们开头运行nginx镜像,访问localhost
显示出来的页面内容吗?
所以,我们只要把打包之后的dist文件丢到/usr/share/nginx/html
里面就行。
你也可以修改
conf
配置文件,指定root
的值是任何目录,这里我选择的是不指定,而是把我的dist
文件copy
丢进去。
编写nginx配置文件
docker.nginx.conf
conf
代码解读
复制代码
server { listen 80; listen [::]:80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
特别注意的是 try_files $uri $uri/ /index.html;
这是实现前端路由的关键。我们都知道,history路由,页面刷新的时候,是会请求服务器地址的。这句话的意思是,请求过来,会尝试在root目录下面寻找当前的uri,如果没有找到就找uri/,如果还没有找到,就返回index.html。只有返回了index.html,才能走到前端路由逻辑。
docker build 构建镜像
bash
代码解读
复制代码
docker build -t docker-fe-demo .
-t
:指定构建出来的镜像的名称和标签。我这里没有指定,tag默认就是latest
,你也可以-t docker-fe-demo:sens
,这个镜像的标签就是sens
。.
:Docker将会在当前目录下寻找Dockerfile文件并执行构建,就是前面设置的WORKDIR
docker run 启动镜像
arduino
代码解读
复制代码
docker run -d -p 80:80 --name docker-fe-demo docker-fe-demo
注意端口不要被其他程序占用,再次访问localhost,可以看到,成功部署了。
总结
大致流程如下:
如果你是在云服务器上,比如阿里云、腾讯云之类,要注意打开安全组和防火墙的端口号,不然无法访问
原文链接:https://juejin.cn/post/7441584637142499362
更多推荐
所有评论(0)