使用 Docker 多阶段构建容器化 React 应用的另一种方法
TL;DR
准备
让我们开始吧
TL;DR
在云计算领域,容器化应用程序推崇解耦原则,提供了一种逻辑化的打包机制。它使基于容器的应用程序易于部署,并确保了一致性。作为一名 React 爱好者,我将与大家分享另一种 React 应用程序的打包方法。
准备
对于以下步骤,我假设您对Docker、React、基于 Linux 的文件夹结构有一些基本的了解……
让我们开始吧
初始化我们的 React 应用程序
为了方便起见,我使用 create-react-app 初始化一个空白的 React 应用程序。
phuong@Arch ~/kitchen/js$ npx create-react-app fooapp
使用 node:alpine 镜像构建我们的应用程序
我们将使用 NodeJS 镜像来构建应用程序,以确保完全隔离。将应用程序复制到应用程序文件夹后(在本例中为cd fooapp)。创建一个名为 Dockerfile 的文件,如下所示:
FROM node:alpine as builder
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
第 1 行:我们声明用于构建 React 应用的镜像,并为其附加构建器标签。
第 2 行:我们使用 WORKDIR 指令指示我们当前位于容器中的 /app 目录下。第
3 行:将应用程序复制到 Docker 容器中。
第 4 行:在容器中为 React 应用安装依赖项。第 5 行:执行命令构建应用程序,应用程序将被构建到块中并保存在名为build
的目录中。
使用 Nginx 为我们的应用程序提供服务
但是等等,我们构建的应用程序显然无法自行提供服务,我们需要一个服务器来将应用程序作为静态资源提供服务。我推荐使用nginx镜像作为我们的服务器,因为它以低资源消耗、配置简单和高性能而广受欢迎。
我们需要一个 nginx 服务器的配置文件,让我们在应用程序的根目录中创建 nginx.conf:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
为了避免将node_modules和不需要的文件夹复制到我们的容器中,我们只需将它们列在.dockerignore文件中即可。
.git
node_modules
build
因此我们的完整 Dockerfile 将是:
FROM node:alpine as builder
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
第 7 行:指令 FROM 指示我们使用 nginx:alpine 镜像(与 node:alpine 镜像配合使用)。
第 8 行:我们将 nginx 配置文件复制到容器中。
第 9 行:--from=builder指示 Docker 从第一阶段复制已构建的文件夹,就像我们上面标记的那样。第 10 行:将80 端口
暴露给容器外部。 第 11 行:指令指示 nginx 应保持在前台运行。对于容器而言,这很有用,因为最佳实践是“一个进程对应一个容器”。
总结一下
让我们检查我们的目录,我们应该有如下所示的确切应用程序目录。
让我们开始使用命令构建我们的容器:
docker build -t fooapp:v1 .
我们的构建过程
为了验证一切正常,我们使用命令运行我们新建的容器:
docker run --rm -d 8080:80 fooapp:v1
--rm标志告诉 docker 在运行我们的应用程序容器后删除容器,-d指示 docker 将主机上的端口 80 绑定到我们的应用程序容器的端口 8080。
瞧
现在我们应该能够从浏览器访问我们的应用程序。
最后,感谢您抽出时间阅读我的第一篇文章。以上步骤和论点仅代表我个人的想法,如有错误,请随时提出。欢迎在下方留言。谢谢。:)
附言:我还在以下位置发布了此文章的 git repo: