Deploying ReactJS With Docker

自行选择测试项目,或新建项目

  • 创建

    1
    2
    npx create-react-app reactdocker;
    cd reactdocker;
  • 运行

    1
    npm start;
  • 关闭

    1
    ctrl + c

创建环境

1
2
3
4
5
6
7
8

# 在当前项目下执行
docker run -it -p 3001:3000 -p 80:80 -v $PWD:/var/www/localhost/htdocs --name reactdocker alpine /bin/sh

-p 3001:3000 # 虚拟机3000端口 映射 宿主机3001端口
-v $PWD 宿主机当前目录 映射到 /var/www/localhost/htdocs,也就是在虚拟机中自动创建/var/www/localhost/htdocs并映射
-—name reactdocker reactdocker为别名
alpine 虚拟机镜像

安装nodejs和npm

1
2
apk add nodejs;
apk add npm;

重新安装包

1
2
3
4
5
cd /var/www/localhost/htdocs;
# 原文中删除包再重新安装,可能是规避nodejs版本或者包存在差异
# 笔者建议可以先尝试 步骤5
rm -rf node_modules;
npm install;

启动

1
2
3
4
5
6
npm start;
# 访问 http://localhost:3001/
# press ctrl + c 关闭
npm run build; # 构建
cd build;
ls -al;

安装 nginx,nano

1
2
3
4
apk add nginx; # 代理服务器
apk add nano; # 字符终端的文本编辑器

nano /etc/nginx/conf.d/default.conf # 编辑代理服务器配置
  • default.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # This is a default site configuration which will simply return 404, preventing
    # chance access to any other virtualhost.
    server {
    listen 80 default_server;
    listen [::]:80 default_server;4
    location / {
    root /var/www/localhost/htdocs/build;
    # this will make so all routes will lead to
    # index.html so that react handles the routes
    try_files $uri $uri/ /index.html;
    }
    # You may need this to prevent return 404 recursion.
    location = /404.html {
    internal;
    }
    }

创建目录以允许nginx在进程ID上运行

1
2
3
4
mkdir /run/nginx;
nginx -t; # 测试配置
nginx;
# 访问 http://localhost/

创建 Dockerfile

1
2
3
4
5
6
7
8
9
10
退出容器  
ctrl + p
ctrl + q
# 创建config 文件夹
mkdir config;
# 拷贝 default.conf 到 config/default.conf
docker cp reactdocker:/etc/nginx/conf.d/default.conf config/default.conf;
# 销毁容器
docker rm -f reactdocker;
docker ps -a # 查看所有容器
  • 在项目根目录下创建基础 Dockerfile
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    FROM alpine
    EXPOSE 80
    ADD config/default.conf /etc/nginx/conf.d/default.conf
    COPY . /var/www/localhost/htdocs
    RUN apk add nginx && \
    mkdir /run/nginx && \
    apk add nodejs && \
    apk add npm && \
    cd /var/www/localhost/htdocs && \
    rm -rf node_modules && \
    npm install && \
    npm run build;
    CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;';"]
    WORKDIR /var/www/localhost/htdocs
1
2
3
4
5
6
# 构建
docker build . -t reactdocker
# 运行
docker run -it -d -p 80:80 --name rdocker reactdocker;
# 访问 http://localhost/
# 现在我们的容器已准备好推送到Docker Hub并准备好部署。

优化Docker镜像

  • 添加 .dockerignore 文件,来移除一下不再需要到依赖文件

    1
    node_modules
  • 接下来修改 Dockerfile来移除我们不需要的依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    FROM alpine
    EXPOSE 80
    ADD config/default.conf /etc/nginx/conf.d/default.conf
    COPY . /var/www/localhost/htdocs
    RUN apk add nginx && \
    mkdir /run/nginx && \
    apk add nodejs && \
    apk add npm && \
    cd /var/www/localhost/htdocs && \
    npm install && \
    npm run build && \
    apk del nodejs && \
    apk del npm && \
    mv /var/www/localhost/htdocs/build /var/www/localhost && \
    cd /var/www/localhost/htdocs && \
    rm -rf * && \
    mv /var/www/localhost/build /var/www/localhost/htdocs;
    CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;';"]
    WORKDIR /var/www/localhost/htdocs
  • 让我们看一下之前构建的容器大小

    1
    2
    $ docker images | grep "reactdocker";
    reactdocker latest d10ec33f5720 3 minutes ago 560MB
  • 现在我们重新构建

    1
    2
    3
    4
    docker build . -t reactdocker;
    # 查看容器大小
    docker images | grep "reactdocker";
    reactdocker latest f5b6a627f188 5 minutes ago 79.7MB
  • 再次运行容器

    1
    2
    docker run -it -d -p 80:80 --name rdocker reactdocker
    # 访问 http://localhost/

现在我们已经有了优化过的Docker镜像,让我们将它推送到Docker Hub。

1
2
docker tag reactdocker yuluhuang/reactdocker;
docker push yuluhuang/reactdocker;

下载

1
docker run -it -d -p 80:80 --name rdocker yuluhuang/reactdocker;

参考资料 https://medium.com/@mannycodes/deploying-reactjs-with-docker-ac16728c0896