1/17

第六章:构建自定义镜像+(Nginx + React)

接下来两章讲解 Docker 开发的工作流,了解 Docker 在开发、测试、部署、开发循环流程中扮演的角色:

开发:介绍了如何使用 Github 管理代码

测试:使用 Travis CI 进行持续集成

部署:在亚马逊 AWS 上部署

  • 初始化

使用 npx create-react-app docker-react-frontend 初始化前端项目。(过程可能有点长,可增加选项跳过安装步骤)

添加 .npmrc 文件。

添加 Dockerfile.dev 文件,开发环境的构建镜像配置:

FROM node:14-alpine

WORKDIR '/usr/app'

COPY .npmrc .
COPY package.json .
RUN npm install
COPY . .

CMD ["npm", "run", "start"]

这一章区分开发环境和生产环境,项目中 Dockerfile 是区分的,使用 Dockerfile.dev 配置开发环境,构建时添加 -f 选项指明配置文件:docker build -f Dockerfile.dev .

  • Volumes

视频中在前端项目时,如果我们改动代码,不会影响容器中的代码,容器内使用还是构建时的代码,而应用又是在容器内启动的,所以也不会有热更新。

而我们不可能改一次代码就构建一次镜像,那样的话太麻烦了,还有没有其他什么方法?

答案就是要用 Docker 中 Volumes 这个机制。

Volumes 可能理解起来比较抽象,可以先简单的等同端口映射,我们将本地的文件“映射”到容器内部。

实际做法是 docker run 命令增加 -v 选项:

wuxianmimi docker-react-frontend % docker run -p 3000:3000 -v /usr/app/node_modules -v $(pwd):/usr/app 72f579b2bf49e403

> docker-react-frontend@0.1.0 start /usr/app
> react-scripts start

(node:25) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:25) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
Starting the development server...

Compiled successfully!

You can now view docker-react-frontend in the browser.

Local:           http://localhost:3000
On Your Network: http://172.17.0.2:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
Compiling...
Compiled successfully!
webpack compiled successfully

第一个 -v /usr/app/node_modules,没有冒号, 表示容器内这个文件夹不需要映射,使用容器本身的文件。

第二个 -v $(pwd):/usr/app,在有冒号的情况下,左边的映射到右边。冒号左边表示本地目录,冒号右边表示容器内目录。

以上操作也可以使用 docker-compose 来简化,添加 docker-compose.yml 文件:

version: '3'
services:
web:
   # 这里同之前写法不一样,因为默认是找 Dockerfile 文件的
   # 由于我们的文件名不一样,所以要手动配置
  build:
    context: .
    dockerfile: Dockerfile.dev
  ports:
    - "3000:3000"
  volumes:
    - /usr/app/node_modules
    - .:/usr/app

运行 docker-compose up 命令,顺利启动。

  • 测试

docker-compose.yml 增加第二个服务,用来测试应用:

version: '3'
services:
web:
   # 这里同之前写法不一样,因为默认是找 Dockerfile 文件的
   # 由于我们的文件名不一样,所以要手动配置
  build:
    context: .
    dockerfile: Dockerfile.dev
  ports:
    - "3000:3000"
  volumes:
    - /usr/app/node_modules
    - .:/usr/app
tests:
  build:
    context: .
    dockerfile: Dockerfile.dev
  volumes:
    - /usr/app/node_modules
    - .:/usr/app
   # 覆盖默认命令
  command: ["npm", "run", "test"]

运行 docker-compose up 命令时,会自动运行测试服务。

  • 使用 Nginx 来做 web 服务器

前端应用使用 npm run build 打包成静态文件后放在服务器上,然后请求通过 Nginx 访问这些文件。

这一步的难点有两个,第一,打包需要安装依赖,而依赖又很大占空间怎么办?第二,打包的文件和 Ngnix 如何结合?

创建 Dockerfile 文件:

# 给第一步构建阶段取别名 builder
FROM node:14-alpine as builder
WORKDIR '/usr/app'
COPY .npmrc .
COPY package.json .
RUN npm install
COPY . .
RUN ["npm", "run", "build"]

# FROM 指令划分构建阶段,下面是第二步
FROM nginx
# 指明文件从 builder 阶段产生的镜像中来
COPY --from=builder /usr/app/build /usr/share/nginx/html
# nginx 镜像有默认启动命令,不需要我们设置

命令行输入 docker build . 构建,构建成功后输入 docker run 命令启动容器:

wuxianmimi docker-react-frontend % docker run -p 80:80 2d16f24ae5fbeefe00
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/01/10 07:03:18 [notice] 1#1: using the "epoll" event method
2023/01/10 07:03:18 [notice] 1#1: nginx/1.23.3
2023/01/10 07:03:18 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/01/10 07:03:18 [notice] 1#1: OS: Linux 5.15.49-linuxkit
2023/01/10 07:03:18 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/01/10 07:03:18 [notice] 1#1: start worker processes
2023/01/10 07:03:18 [notice] 1#1: start worker process 29
2023/01/10 07:03:18 [notice] 1#1: start worker process 30
2023/01/10 07:03:18 [notice] 1#1: start worker process 31
2023/01/10 07:03:18 [notice] 1#1: start worker process 32

浏览器访问 http://localhost/

imgReact项目

posted @ 2025-01-17 19:20  Hbro  阅读(11)  评论(0)    收藏  举报