Docker Nginx 与 React 和 Laravel

Docker Nginx with React and Laravel

所以我想要一个 Nginx 网络服务器同时服务于 Docker 的前端和后端。 这是我的 docker-compose:

version: "3.8"

services:
  db: #mysqldb
    image: mysql:5.7
    container_name: ${DB_SERVICE_NAME}
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:
      - ./docker-compose/mysql:/docker-entrypoint-initdb.d
    networks:
      - backend

  mrmfrontend:
    build:
      context: ./mrmfrontend
      args:
        - REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
        - REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
        - REACT_APP_FRONTEND_ENDPOINT=$REACT_APP_FRONTEND_ENDPOINT
        - REACT_APP_FRONTEND_ENDPOINT_ERROR=$REACT_APP_FRONTEND_ENDPOINT_ERROR
        - REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
        - REACT_APP_NAME=$REACT_APP_NAME
        - REACT_APP_OWNER=""
    ports:
      - $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
    networks:
      - frontend

  nginx:
    image: nginx:alpine
    container_name: backend-nginx
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./MRMBackend:/var/www
      - ./docker-compose/nginx/backend:/etc/nginx/conf.d/
    networks:
      - backend
      - frontend

  app:
    build:
      args:
        user: admin
        uid: 1000
      context: ./MRMBackend
      dockerfile: Dockerfile
    image: backend
    container_name: backend-app
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./MRMBackend:/var/www
    networks:
      - backend

volumes:
  db:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

这是前端的 Docker 文件:

FROM node:16.13.0 as build-stage

WORKDIR /app

COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i

ARG REACT_APP_API_BASE_URL
ARG REACT_APP_BACKEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT_ERROR
ARG REACT_APP_CUSTOMER
ARG REACT_APP_NAME

ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
ENV REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT = $REACT_APP_FRONTEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT_ERROR = $REACT_APP_FRONTEND_ENDPOINT_ERROR
ENV REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
ENV REACT_APP_NAME=$REACT_APP_NAME

ENV GENERATE_SOURCEMAP=false

RUN npm run build

问题是前端容器似乎无法启动。它总是在启动时退出。

根据我的理解,我应该将 build-stage 的构建内容复制到 nginx 文件夹“/usr/share/nginx/html”,但是如何从 docker-compose 文件中复制它?

仅使用卷是行不通的。我在 docker-compose 中需要 nginx,因为它也在为后端服务。

请注意后端工作正常。

更新

我的第一个方法是在前端使用 Docker 文件,我将构建的内容直接复制到 Nginx 映像中

# Stage 1
FROM node:16.13.0 as build-stage

WORKDIR /app

COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i

ARG REACT_APP_API_BASE_URL
ARG REACT_APP_BACKEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT_ERROR
ARG REACT_APP_CUSTOMER
ARG REACT_APP_NAME

ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
ENV REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT = $REACT_APP_FRONTEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT_ERROR = $REACT_APP_FRONTEND_ENDPOINT_ERROR
ENV REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
ENV REACT_APP_NAME=$REACT_APP_NAME

#avoid javascript out of memory
ENV GENERATE_SOURCEMAP=false

RUN npm run build

# Stage 2
FROM nginx:1.17.0-alpine

COPY --from=build-stage /app/build /usr/share/nginx/html
EXPOSE $REACT_DOCKER_PORT

CMD nginx -g 'daemon off;'

但是这样我想我部署了两个Nginx。一份在 Docker 文件中,一份在 Docker-compose 中。我说得对吗?

我主要使用 Docker multi-build 来配置我的 FE 应用程序。希望这对您有所帮助!

FROM node:16.13.0 as build-stage

WORKDIR /app

COPY package.json ./
COPY package-lock.json ./
COPY ./ ./

RUN npm install
RUN npm run dev



#Build Files
FROM nginx:1.19.10-alpine
COPY nginx-conf /etc/nginx/conf.d/default.conf
COPY --from=build /app /home/ubuntu/app/dist

您可以使用默认的 nginx 配置。

@federico-arona

如我的评论所述:如果您想拥有 1 个 nginx,则需要从构建应用程序的容器中共享或复制文件。

根据您的要求和您想要完成的目标。最好的解决方案是命名卷,因为它们可以跨容器共享。

它们是保存 Docker 容器生成和使用的数据的首选机制。另外,您可以使用 Docker CLI 命令和 Docker API 管理卷。 The Official docs 显示其他优势以及有关如何使用它们的附加信息。