在生产环境使用docker-compose和Dockerfiles部署Express/React应用

80次阅读
没有评论

问题描述

想要使用Docker在生产环境部署他的Express/React应用,但遇到了一些困难。他的项目结构如下:
– 一个server文件夹:运行Express应用,端口为4000
– 一个web文件夹:一个React应用,在本地运行时使用端口3000,在服务器上需要运行在端口80
– 在根目录下有一个docker-compose.prod.yml文件

他目前的尝试如下:
docker-compose.prod.yml文件中运行一个Postgres服务(端口5432),以及webserver各自的Dockerfile
– 在webserver文件夹中各有一个Dockerfile
– 他在本地使用yarn build构建了serverweb文件夹,然后将所有内容传输到服务器上
– 在服务器上,他运行以下命令构建了两个镜像:docker build -f web/Dockerfile.prod -t app_web ./webdocker build -f server/Dockerfile.prod -t app_server ./server
– 最后,他运行了docker-compose -f docker-compose.prod.yml up

他遇到的问题如下:
1. server容器抛出了Error: Cannot find module '...'错误,尽管他在Dockerfile中运行了yarn install --production(可能与卷有关)
2. 当他运行docker run -it -p 80:80 app_webdocker-compose up时,访问服务器IP地址时,web容器的行为不同:在第一种情况下,应用显示正常;在第二种情况下,一个页面列出了web文件夹中的内容(所有文件和文件夹)

他非常希望得到帮助,因为他对生产环境中的Docker使用还比较新(他是否应该使用docker machine?他的文件夹结构、docker-compose和Dockerfiles是否有问题?)

解决方案

首先,感谢您的详细描述,让我可以更好地理解您的问题。现在,让我们逐步解决您遇到的问题。

解决”Cannot find module”错误

这个问题可能是由于卷的使用方式导致的。您在server/Dockerfile.prod中使用了以下配置:

FROM mhart/alpine-node:11 AS builder
WORKDIR /app/server
COPY package.json ./
RUN yarn install --production
COPY . .

FROM mhart/alpine-node
WORKDIR /app/server
COPY --from=builder /app/server .
CMD ["node", "/app/server/dist"]

在这个Dockerfile中,您将node_modules目录包括在了镜像中,而且在第一个构建阶段中没有使用它。这可能导致构建的镜像中缺少一些依赖模块,从而在容器中运行时导致”Cannot find module”错误。

为了解决这个问题,您可以尝试在第一个构建阶段中使用yarn install,然后将node_modules目录复制到第二个构建阶段中。以下是修改后的server/Dockerfile.prod

FROM mhart/alpine-node:11 AS builder
WORKDIR /app/server
COPY package.json yarn.lock ./
RUN yarn install --production
COPY . .

FROM mhart/alpine-node
WORKDIR /app/server
COPY --from=builder /app/server .
CMD ["node", "/app/server/dist"]

解决Web容器行为差异问题

关于您在两种情况下web容器行为的差异,有可能是由于您在docker-compose.prod.yml文件中定义的端口映射导致的。

在第一种情况下,您运行了以下命令:

docker run -it -p 80:80 app_web

这里使用了端口映射,将容器的80端口映射到主机的80端口。因此,在访问服务器的IP地址时,应用能够通过主机的80端口进行访问。

在第二种情况下,您运行了以下命令:

docker-compose up

docker-compose.prod.yml中,您已经定义了端口映射:

ports:
  - 80:80

这导致在运行docker-compose up时,同样会将容器的80端口映射到主机的80端口。这可能导致与上述手动运行命令相同的行为。

关于使用docker-machine

根据您的描述,您的问题与docker-machine并无直接关系。docker-machine用于在远程服务器上创建和管理Docker主机,但在您的情况下,您似乎正在本地构建和运行镜像。

关于文件夹结构和Docker配置

根据您提供的信息,您的文件夹结构和Docker配置似乎是正确的。您在docker-compose.prod.yml中定义了三个服务:dbserverweb,并且您在webserver文件夹中都有对应的Dockerfile。然而,问题可能出在镜像构建和容器运行的具体细节上,比如卷的使用、依赖模块的安装等。

总结

在解决问题时,请确保您的容器配置和Dockerfile正确,并注意卷的使用以及端口映射的设置。关于”Cannot find module”错误,您可以尝试使用我提供的修改后的server/Dockerfile.prod。另外,确保您在构建镜像时包括了所有必要的依赖。

最后,关于不同行为的问题,检查您的`docker-compose.prod

正文完