本文不教如何安装docker,默认已安装好docker。这是我的docker版本,在我本地安装的。

image.png

docker 基本操作

docker的命令远远不止这些,本文只讲需要用到的。

docker pull 拉取nginx镜像

如果你之前用nginx部署过前端项目的话,用docker部署你就会发现更简单。


bash

代码解读

复制代码

docker pull nginx

等待pull完成,pull成功之后,可以用docker images查看一下

image.png

可以看到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: 镜像名称

image.png

启动之后,终端会输出对应的容器id,说明已经启动成功。也可以用docker ps查看一下

docker ps 查看运行中的容器

image.png

可以看到,有一条nginx的容器正在运行,这个容器的id84开头,正是我们刚刚执行docker run返回的那个容器id

打开浏览器,输入localhost,可以看到下面的默认页面,恭喜你,已经成功用docker启动nginx了。

http端口号默认80,所以可以省略端口号,如果你映射的是其他端口号,记得带上端口号

image.png

如果你是在本地电脑上安装的docker,搭配docker官方提供的Docker Desktop桌面端,使用起来更方便。上面所有的命令,在Docker Desktop里面都有对应的可视化操作。

docker stop


bash

代码解读

复制代码

docker stop <容器名/容器ID>

这里要注意是容器名称,不是镜像名称,就是前面我们执行docker run命令后面带的参数--name nginxnginx

执行docker stop nginx,可以看到返回了容器的名称。然后docker ps再查看一下运行的容器,发现并没有nginx容器里。

image.png

再刷新一下浏览器看看

image.png

部署

创建项目


bash

代码解读

复制代码

npm create vite@latest

image.png

依次执行


bash

代码解读

复制代码

cd docker-fe-demo npm install run run dev

在App.tsx里面随便写一点代码,保持。


tsx

代码解读

复制代码

function App() { return <>hello sens</>; } export default App;

页面正常渲染了

image.png

编写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.jsonpackage-lock.json)复制到容器内的/app目录下。这一步是为了先安装项目依赖
  • RUN npm config set registry https://registry.npmmirror.com/: 设置npm淘宝源
  • RUN npm install: 执行npm install
  • COPY . .:将(主机)当前目录下的所有文件复制到容器内的/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

image.png

这里也可以看到,是我们之前84开头的nginx容器。 然后执行:


bash

代码解读

复制代码

cat /etc/nginx/nginx.conf

打印一下nginx的配置信息。

image.png

可以看到,有这样的一项配置,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

image.png

圈中的意思是指定root(根)目录是/usr/share/nginx/html,当收到一个请求的时候,就会去指定的root目录里面找对应的index文件。

再进入到/usr/share/nginx/html里面看看:


bash

代码解读

复制代码

cd /usr/share/nginx/html ls cat index.html

image.png

这不正是我们开头运行nginx镜像,访问localhost显示出来的页面内容吗?

image.png

所以,我们只要把打包之后的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,可以看到,成功部署了。

image.png

总结

大致流程如下:

image.png

如果你是在云服务器上,比如阿里云、腾讯云之类,要注意打开安全组和防火墙的端口号,不然无法访问

原文链接:https://juejin.cn/post/7441584637142499362

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐