如何为ReactJS创建dockerized开发环境

时间:2019-05-07 16:26:14

标签: reactjs docker nginx

我已经通过includes live-server开发了一个react应用并部署了它。作为代理服务器,我使用的是nginx,它还为后端和前端提供一些静态和媒体文件。

尤其是为了测试静态文件和媒体文件的提供,我想拥有一个dockerized本地测试环境。

这是我的问题: 在测试环境中,我不想每次更改代码时都创建新的构建(npm run build-对于create-react-app)。理想情况下,我将能够通过绑定安装进行热重载。

这意味着我将不得不通过nginx服务开发服务器。那有可能吗?数天来,我一直在为这个问题咬指甲,寻找一种常规的解决方法。

3 个答案:

答案 0 :(得分:3)

实际上还不错,只需使用如下的nginx配置:

events {}

# assuming you want to serve your app on localhost:8080
# and assuming your webpack dev server runs on port 3000
http {
    include /etc/nginx/mime.types;
    server {
        # assuming you want to serve the app on localhost:8080
        listen 8080;
        client_max_body_size 50m;

        # webpack dev server
        location / {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            # use your port for your webpack dev server
            proxy_pass http://host.docker.internal:3000/;
        }

        # this is specifically needed for hot reload with webpack dev server
        location /sockjs-node {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;

            # 'host.docker.internal' is a docker dns record for your host machine's localhost,
            # and '3000' should be the port of your webpack dev server
            proxy_pass http://host.docker.internal:3000;

            proxy_redirect off;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
   }

    access_log /etc/nginx/access.log;
    error_log /etc/nginx/error.log debug;
}

并使用如下所示的./nginx.sh运行nginx:

#!/usr/bin/env bash

# path to your app's build directory
APP_BUILD_DIR=/path/to/my-app/build

# path of dir containing your nginx config
NGINX_CONF_DIR=$(pwd)

# name of your nginx conf file, relative to NGINX_CONF_DIR
NGINX_CONF_FILE=nginx.conf

# port at which nginx is serving your app
PORT=8080

# docker run docs: https://docs.docker.com/engine/reference/run/
# this will run an nginx container named 'nginx' as a daemon,
# and will mount NGINX_CONF_DIR in the container
docker run -d --name nginx \
  -v=$NGINX_CONF_DIR:/etc/nginx \
  -v=$APP_BUILD_DIR:/opt/base/my-app \
  -p=$PORT:$PORT nginx \
  nginx -c /etc/nginx/$NGINX_CONF_FILE -g "daemon off;"

该目录中还有一个this onemime.types文件。

因此您的目录结构应类似于:

dir/
-- nginx.sh
-- nginx.conf
-- mime.types
-- ...

我假设您正在计算机上而不是在Docker容器中运行webpack开发服务器?根据我的经验,我会诚实地建议您。 npm(或yarn)做得很好,即使我通过nginx容器提供服务,我也没有发现需要在本地容器中运行我的React应用程序。

奖金:如果您要运行相同的应用程序,则使用nginx配置,但要使用静态捆绑包而不是webpack开发服务器:

events {}

http {
    include /etc/nginx/mime.types;
    server {
        # assuming you want to serve the app on localhost:8080
        listen 8080;
        client_max_body_size 50m;

        location / {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            root /opt/base/my-app;
            try_files $uri /index.html;
        }

        # matches things like http://localhost:8080/build/static/js/2.d63c51de.chunk.js
        location /build/static/ {
            alias /opt/base/my-app/static/;
            try_files $uri $uri/;
        }
   }

    access_log /etc/nginx/access.log;
    error_log /etc/nginx/error.log debug;
}

参考:this SO post

答案 1 :(得分:1)

使用HMR对开发服务器进行Docker的移植并非易事。

即使没有进行任何调整,即使是预先配置的项目(具有HMR和docker-ready的)也可能无法在一开始就工作。 F.e.当您可以让应用程序在另一个IP /端口上工作时,HMR需要localhost路径(CORS问题)。在构建过程中,某些调整可能很困难-即时修补软件包。

在尝试设置您的理想配置之前,请尝试运行准备就绪的项目。您始终可以为不同的部分(在不同的端口上)运行不同的服务器。

我将从apollo-universal-starter-kit开始-它包含node.js api /后端部分,但可以与外部组件(可配置)一起使用。

您可以在Docker Hub上搜索其他支持React HMR的解决方案。尝试,获取灵感和知识...玩得开心。

答案 2 :(得分:0)

对于从本地文件系统热部署到 docker,请指定以下选项。以下是使用 powershell 在 Windows 10 上运行的 docker:

Set the environment variable
-e CHOKIDAR_USEPOLLING=true

Mount the volume of local machine into work directory in the container
-v ${pwd}:/<workdir in container>
 
E.g. : docker run -it --rm -p 5000:3000 -v /app/node_modules -v ${pwd}:/app -e CHOKIDAR_USEPOLLING=true <image id>