Очень широкий вопрос.Возможно, лучше разбить его на более прямые вопросы.Во всяком случае, я не думаю, что запуск вашей установки dev в Docker идеален.Вместо этого соберите свое приложение обычно с CRA.Затем разверните в Docker.
В моих собственных проектах у меня есть докер-контейнер, на котором работает сервер узлов, который обслуживает приложение реагирования с использованием SSR.
Вот часть докера.Обратите внимание, что ваш package.json
должен иметь скрипт с именем start:prod
, чтобы это работало.Затем этот скрипт запускает ваше приложение в производство.
// --- Dockerfile
# Pulled from docker hub and has everything
# needed to run a node project
FROM node:alpine
ENV PORT 3000
# Navigate (cd) to the app folder in the docker container
WORKDIR /usr/src/app
# Copy all package.json / package-lock.json etc. to the root folder
# Executed on build: docker build .
COPY ./package*.json ./
RUN npm i
# copy entire project into docker container
COPY . .
# build front-end with react build scripts and store them in the build folder
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
Вот сервер экспресс, который запустит сервер.
// -- server.js
import express from "express";
import router from "./controller/index";
const app = express();
const port = 4000;
// Tell the app to use the routes above
app.use(router);
// start the app
app.listen(port, () => {
console.log(`express running on port ${port}`);
});
Вот файл controller/index.js
, который вам потребуется для запуска
// -- controller/index.js
import express from "express";
import path from "path";
import serverRenderer from '../middleware/renderer';
const router = express.Router();
// root (/) should always serve our server rendered page
router.use('^/$', serverRenderer());
// other static resources should just be served as they are
router.use(express.static(
path.resolve(__dirname, '..', '..', 'build'),
{ maxAge: '30d' },
));
export default router;
И, наконец, средство визуализации, которое отображает приложение на сервере.
// -- renderer.js
import React from "react";
import { renderToString } from "react-dom/server";
import App from "../../src/App";
const path = require("path");
const fs = require("fs");
export default () => (req, res) => {
// point to html file created by CRA's build tool
const filePath = path.resolve(__dirname, "..", "..", "build", "index.html");
fs.readFile(filePath, "utf8", (error, htmlData) => {
if (error) {
console.error("error", error);
return response.status(404).end();
}
// render the app as string
const html = renderToString(<App />);
// inject rendered app into final html and send
return res.send(
htmlData
.replace('<div id="root"></div>', `<div id="root">${html}</div>`)
);
})
}
Вам потребуется bootstrap.js
для внедрения поддержки определенных пакетов.
// -- bootstrap.js
require('ignore-styles');
require('url-loader');
require('file-loader');
require('babel-register')({
ignore: [/(node_modules)/],
presets: ['es2015', 'react-app'],
plugins: [
'syntax-dynamic-import',
'dynamic-import-node'
]
});
require("./index");
Подробности обо всем этом можно найти здесь: https://blog.mytoori.com/react-served-by-express-running-in-docker-container