使用Docker“创建React App”

时间:2016-08-04 04:11:50

标签: reactjs docker webpack docker-compose livereload

我想知道是否有人使用dock-react-app和docker有任何经验。我能够使用Dockerfile设置它:

from node
RUN mkdir /src
WORKDIR /src
ADD package.json /src/package.json
RUN npm install
EXPOSE  3000
CMD [ "npm", "start" ]

然后使用docker-compose文件,如:

app:
  volumes:
    - "./app:/src"
  ports:
    - "3000:3000"
    - "35729:35729"
  build: ./app

这允许我启动容器并查看应用程序。但是,当在已装入的卷中保存文件时,livereload不起作用,而webpack在src目录中创建了几个.json.gzip文件。

有关使其正常工作的任何建议吗?

4 个答案:

答案 0 :(得分:7)

是的,正如aholbreich所提到的,我会在我的机器上本地使用npm install / npm start进行开发,因为它非常简单。这可能与docker-compose,装载音量等有关,但我认为设置它可能有点繁琐。

对于部署,您可以非常轻松地使用Dockerfile。这是我正在使用的Dockerfile示例:

FROM node:6.9

# Create app directory
RUN mkdir -p /src/app
WORKDIR /src/app

# to make npm test run only once non-interactively
ENV CI=true

# Install app dependencies
COPY package.json /src/app/
RUN npm install && \
    npm install -g pushstate-server

# Bundle app source
COPY . /src/app

# Build and optimize react app
RUN npm run build

EXPOSE 9000

# defined in package.json
CMD [ "npm", "run", "start:prod" ]

您需要将start:prod选项添加到 package.json

"scripts": {
  "start": "react-scripts start",
  "start:prod": "pushstate-server build",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject"
},

您可以使用以下命令在CI服务上运行测试:

docker run <image> npm test

没有什么可以阻止你在本地运行这个docker容器,以确保按预期工作。

答案 1 :(得分:5)

我最近创建了一个名为hello-docker-react的小项目,他正在寻找op正在寻找的东西。

它是使用docker-compose,create-react-app,yarn,节点图像和小型入口点脚本制作的。

实时重装工作完美无缺,我还没有发现任何问题。

https://github.com/lopezator/hello-docker-react

答案 2 :(得分:1)

在通过create-react-app开发中使用docker时,我发现可以通过将<div id="right"> <div class="profile-info"> <p class="l" id="sedcard-views" style="position: relative;">Visite Totali: 180 </p> <p class="r">Ultima modifica: <span class="bold">06 Nov 2019</span></p> <div class="clear"></div> </div> <div class="clear"></div> <div class="diamond_vip"></div> <div class="profile-tabs"> <a href="javascript:void(0);" id="show_tabs" style="display:none">+</a> <a href="javascript:void(0);" id="hide_tabs" style="">x</a> <ul id="profile-tabs"> <li class="active" style="z-index: 5;"> <div class="l"></div> <div class="m"><a href="#info">Bio</a></div> <div class="r"></div> </li> <li class="" style="z-index: 4;"> <div class="l"></div> <div class="m"><a href="#services">Servizi</a></div> <div class="r"></div> </li> <li class="" style="z-index: 3;"> <div class="l"></div> <div class="m"><a href="#price">Tariffe</a></div> <div class="r"></div> </li> <li class="" style="z-index: 2;"> <div class="l"></div> <div class="m"><a href="#contact">Contatti</a></div> <div class="r"></div> </li> <li class="" style="z-index: 1;"> <div class="l"></div> <div class="m"><a href="#comments">Rec. &amp; Commenti</a></div> <div class="r"></div> </li> </ul> </div> <div class="clear"></div> <div id="profile-container" rel="6705" style="height: 3718px;"> <a rel="info"></a> <div class="head info"> <span>NAME HERE</span> <div class="clear"></div> </div> <div style="position: relative; min-height: 20px;"> <div class="absolute-right-box"> </div> <table> <tbody> <tr> <th>....</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>....:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> <tr> <th>...:</th> <td>...</td> </tr> </tbody> </table> </div> <div class="clear"></div> <table> <tbody> <tr> <th>Lingue: </th> <td> <span class="strong">Inglese</span> <span class="star-y"></span> <span class="star-y"></span> <span class="star-y"></span> <span class="star-n"></span> <div class="clear"></div> <span class="strong">Russo</span> <span class="star-y"></span> <span class="star-y"></span> <span class="star-y"></span> <span class="star-y"></span> <div class="clear"></div> </td> </tr> <tr> <th>....:</th> <td> <span class="incall"> ..... </span> <span class="outcall"> ..... </span> </td> </tr> <tr> <th>....:</th> <td> .... <img src="https://.....gif" width="12" height="12" alt="..."> </td> </tr> <tr> <th>...:</th> <td> .... </td> </tr> </tbody> </table> <div class="clear"></div> <div class="about-block"> <a rel="about"></a> <div class="head">...:</div> <div class="about-text"> <p>...i</p> </div> </div> <a rel="services"></a> <div class="block services"> <div class="head"><span>...</span></div> <ul> <li> ... </li> <li> ... <span class="pink">....</span> </li> <li> ... <span class="pink">...</span> </li> <li> ... <span class="pink">...</span> </li> <li> ... </li> <li> .... </li> </ul> <ul> <li> ... </li> <li> ... </li> <li> ... </li> <li> ... </li> <li> ... </li> <li> ... </li> </ul> <div class="clear"></div> </div> <div class="clear"></div> <a rel="price"></a> <div class="block rates"> <div class="head"><span>...</span></div> <table class="incall"> <tbody> <tr> <td colspan="2"><span class="icon">...</span></td> </tr> <tr> <th> ...:</th> <td>...</td> </tr> <tr> <th> ...:</th> <td>...</td> </tr> <tr> <th> ...:</th> <td>...</td> </tr> </tbody> </table> <table class="outcall"> <tbody> <tr> <td colspan="2"><span class="icon">...</span></td> </tr> <tr> <th> ...:</th> <td>...</td> </tr> <tr> <th> ...:</th> <td>...</td> </tr> </tbody> </table> <div class="clear"></div> </div> <div class="clear"></div> <div class="clear"></div> <a rel="tours"></a> <a rel="contact"></a> <div class="new_contacts"> <ul id="contactTabs"> <li class="active"> <div class="l"></div> <div class="m"><a id="contactTab" class="active contact" href="javascript:void(0);"><span>Contatti</span></a></div> <div class="r"></div> </li> </ul> <div class="n_cont"> <div class="contactTab block contact"> <div class="contact_info"> <table class="contact_info_table"> <tbody> <tr> <th>Città base:</th> <td> 00192 <a href="..." class="bold" title="..."> ... </a> </td> </tr> <tr> <th>Zone città:</th> <td> <a href="....">...</a> </td> </tr> <tr> <th>Telefono:</th> <td><img style="vertical-align:middle; display: inline-block; margin-right: 10px;" src="../img/flags/pt.png" title="...">+1234567</td> </tr> <tr> <th>Apps Available: </th> <td> <div class="whatsapp">WhatsApp</div> <div class="clear"></div> </td> </tr> <tr> <th>....: </th> <td class="bold">...</td> </tr> <tr> <th>...:</th> <td class="bold"> <div style="display: block; float: left"> <a style="display: block; width: 90px; height: 18px; outline: none; margin-top: 2px;" href="" onclick="return Cubix.PrivateMessaging.Show($(this).getParent(), '...')"> <img src="https://.....png" alt="Contattami"> </a> </div> </td> </tr> </tbody> </table> <div class="ext-site "> <table> <tbody> <tr> <th> <span><img src="...png"></span> </th> <td> <a href="http:/..." target="_blank">....!</a> </td> </tr> </tbody> </table> </div> <div class="clear"></div> <div class="borderElm"></div> <table class="working-times"> <thead> <tr> <td colspan="2">...</td> </tr> </thead> <tbody> <tr> <td align="center"> <p class="available_24_7">....</p> </td> </tr> </tbody> </table> <div class="borderElm"></div> <div class="clear"></div> </div> </div> <div class="mapTab none"> <div id="map_canvas" style="width:100%; height:370px"></div> </div> <div class="clear"></div> </div> </div> <a rel="comments"></a> <div class="reviews_comments"> <ul id="rcTabs"> <li class="active"> <div class="l"></div> <div class="m"><a id="cTab" class="comments active" href="javascript:void(0);"><span>Commenti<i> (0)</i></span></a></div> <div class="r"></div> </li> <li class=""> <div class="l"></div> <div class="m"><a id="rTab" class="reviews " href="javascript:void(0);"><span>Recensioni (0)</span></a></div> <div class="r"></div> </li> </ul> <div class="r_c"> <div class="cTab block" style=""> <div class="head comments p0"><span><span class="title"></span> <span class="btn-blue-slim add-comment">Scrivi commenti</span></span> </div> <div id="commentsBody" class="ajax"> <div id="add-comment-form"></div> <p class="comment_added" id="comment_added">Comment is awaiting moderation</p> <div id="comments_container" style="position: relative; opacity: 1;"> <p class="no_comment">Non esiste alcun commento</p> <input type="hidden" id="commentCount" value="0"> </div> </div> <div class="clear"></div> </div> <div class="rTab reviews none"> <div class="reviews-body"> <a class="btn-blue-slim" href="...">Aggiungi/Vedi recensioni</a> <div class="clear"></div> </div> </div> <div class="clear"></div> </div> </div> <div class="margin1000">&nbsp;</div> <div class="clear"></div> </div> <div class="clear"></div> </div> 添加到您的.env文件中来覆盖webpackDevServer配置。这将使文件监视再次起作用。它甚至刷新主机上的浏览器页面!我发现的唯一一件事是它不会自动打开网页。

我还建议您将CHOKIDAR_USEPOLLING=1添加到您的服务中,以将原始控制台输出返回到您的终端。要在日志中删除容器名称前缀,可以在运行tty: true之后运行类似的内容:

docker-compose up -d

答案 3 :(得分:1)

在CRA 4.0和许多依赖项下运行

.dockerignore

.git
.gitignore
node_modules
build

Dockerfile.dev

FROM node:alpine

WORKDIR /app

COPY package.json /app

RUN yarn install

COPY . .

CMD ["yarn", "start"]

docker-compose.dev.yml

version: "3.8"
services:
  print:
    stdin_open: true
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - ".:/app"
      - "/app/node_modules"

Dockerfile.prod

FROM node:alpine as build

WORKDIR /app

COPY package.json /app

RUN yarn install

COPY . /app

RUN yarn run build

FROM nginx:stable-alpine
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html

docker-compose.prod.yml

version: "3.8"
services:
  print:
    stdin_open: true
    build:
      context: .
      dockerfile: Dockerfile.prod
    ports:
      - "80:80"

nginx.conf

server {  
  listen 80;
  server_name frontend;
  location / {
    root /usr/share/nginx/html;
    index index.html;
    try_files $uri /index.html;
  }
}

要运行

docker-compose.exe -f .\docker-compose.yml up --build

docker-compose.exe -f .\docker-compose.dev.yml up --build