简单搭建qiankun的主应用和子应用并且用Docker进行服务器部署

发布于:2024-12-08 ⋅ 阅读:(144) ⋅ 点赞:(0)

在node18环境下,用react18创建qiankun主应用和两个子应用,react路由用V6版本,都在/main路由下访问子应用,用Dockerfile部署到腾讯云CentOS7.6服务器的8000端口进行访问,且在部署过程中进行nginx配置以进行合理的路由访问

要在 Node.js 18 环境下,用 React 18 创建一个基于 qiankun 的主应用和两个子应用,并使用 React Router v6 进行路由管理,所有子应用都在 /main 路由下访问,并使用 Docker 和 Nginx 部署到腾讯云 CentOS 7.6 服务器的 8000 端口,可以按照以下步骤进行:

1. 创建主应用和子应用

主应用

  1. 创建主应用:
npx create-react-app main-app --template typescript
cd main-app
  1. 安装 qiankun 和 react-router-dom:
npm install qiankun react-router-dom@6
  1. 配置主应用:
    在 index.tsx 中配置 qiankun:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { registerMicroApps, start } from 'qiankun';
import App from './App';

registerMicroApps([
  {
    name: 'sub-app-1',
    entry: '//localhost:7100',
    container: '#subapp-viewport',
    activeRule: '/main/sub-app-1',
  },
  {
    name: 'sub-app-2',
    entry: '//localhost:7200',
    container: '#subapp-viewport',
    activeRule: '/main/sub-app-2',
  },
]);

start();

ReactDOM.render(
  <React.StrictMode>
    <Router>
      <Routes>
        <Route path="/*" element={<App />} />
      </Routes>
    </Router>
  </React.StrictMode>,
  document.getElementById('root')
);
  1. 修改 App.tsx:
import React from 'react';
import { Link } from 'react-router-dom';

const App = () => (
  <div>
    <nav>
      <ul>
        <li>
          <Link to="/main/sub-app-1">Sub App 1</Link>
        </li>
        <li>
          <Link to="/main/sub-app-2">Sub App 2</Link>
        </li>
      </ul>
    </nav>
    <div id="subapp-viewport"></div>
  </div>
);

export default App;

子应用 1

  1. 创建子应用 1:
npx create-react-app sub-app-1 --template typescript
cd sub-app-1
  1. 安装 qiankun 和 react-router-dom:
npm install qiankun react-router-dom@6
  1. 配置子应用 1:
    在 index.tsx 中添加 qiankun 的生命周期函数:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import App from './App';

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

function render(props) {
  const { container } = props;
  ReactDOM.render(
    <React.StrictMode>
      <Router basename={window.__POWERED_BY_QIANKUN__ ? '/main/sub-app-1' : '/'}>
        <Routes>
          <Route path="/*" element={<App />} />
        </Routes>
      </Router>
    </React.StrictMode>,
    container ? container.querySelector('#root') : document.getElementById('root')
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('sub-app-1 bootstraped');
}

export async function mount(props) {
  console.log('sub-app-1 mounted');
  render(props);
}

export async function unmount(props) {
  console.log('sub-app-1 unmounted');
  const { container } = props;
  ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.getElementById('root'));
}
  1. 配置 package.json:
{
  "name": "sub-app-1",
  "version": "0.1.0",
  "private": true,
  "homepage": "/main/sub-app-1",
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-scripts": "5.0.0",
    "qiankun": "^2.4.0",
    "react-router-dom": "^6.0.0"
  },
  "scripts": {
    "start": "PORT=7100 react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

子应用 2

子应用 2 的步骤和 子应用 1 基本一致,项目名不一样和Router的 basename 不一样即可;端口为 7200,或者自行定义,和主应用和子应用1端口不一样即可

2. 创建 Dockerfile

为每个应用创建 Dockerfile,并使用 Nginx 作为静态文件服务器。

主应用 Dockerfile

在 main-app 目录下创建 Dockerfile:

# Build stage
FROM node:18 AS build

# Set the working directory
WORKDIR /app

# Copy the package.json and package-lock.json files
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy the built files from the build stage
COPY --from=build /app/build /usr/share/nginx/html

# Copy the Nginx configuration file
COPY nginx.conf /etc/nginx/nginx.conf

# Expose port 80
EXPOSE 80

# Start Nginx
CMD ["nginx", "-g", "daemon off;"]

子应用的 Dockerfile

在 sub-app-1 目录下创建 Dockerfile:

# Build stage
FROM node:18 AS build

# Set the working directory
WORKDIR /app

# Copy the package.json and package-lock.json files
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy the built files from the build stage
COPY --from=build /app/build /usr/share/nginx/html

# Copy the Nginx configuration file
COPY nginx.conf /etc/nginx/nginx.conf

# Expose port 80
EXPOSE 80

# Start Nginx
CMD ["nginx", "-g", "daemon off;"]

3. 创建 Nginx 配置文件

为每个应用创建一个 Nginx 配置文件 nginx.conf。

主应用 Nginx 配置文件

在 main-app 目录下创建 nginx.conf:

server {
    listen 80;

    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    location /main/sub-app-1/ {
        proxy_pass http://localhost:7100/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /main/sub-app-2/ {
        proxy_pass http://localhost:7200/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

完整的主应用 nginx.conf

worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user - $http_xlog_purpose - $time_local - $request - $status - $body_bytes_sent - $http_referer - $http_user_agent - $http_x_forwarded_for';
    access_log  /var/log/nginx/access.log main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;
    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        location /main/kirin-react-app/ {
            proxy_pass http://localhost:8001/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        location /main/dragon-react-app/ {
            proxy_pass http://localhost:8002/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

子应用 1 和子应用 2 Nginx 配置文件

在 sub-app-1 和 sub-app-2 目录下分别创建 nginx.conf:

server {
    listen 80;

    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;

        # 添加 CORS 头
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept';
    }
}

完整的子应用 nginx.conf

worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user - $http_xlog_purpose - $time_local - $request - $status - $body_bytes_sent - $http_referer - $http_user_agent - $http_x_forwarded_for';
    access_log  /var/log/nginx/access.log main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;
    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;

            # 添加 CORS 头
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept';
        }
    }
}

4. 构建和运行 Docker 容器

在每个应用的目录下,运行以下命令构建 Docker 镜像:

docker build -t main-app .
docker build -t sub-app-1 .
docker build -t sub-app-2 .

然后运行 Docker 容器:

docker run -d -p 8000:80 main-app
docker run -d -p 7100:80 sub-app-1
docker run -d -p 7200:80 sub-app-2

5. 部署到腾讯云 CentOS 7.6 服务器

  1. 连接到腾讯云服务器:
    使用 SSH 连接到你的腾讯云 CentOS 7.6 服务器。
ssh your-username@your-server-ip
  1. 安装 Docker:
    如果你的服务器上还没有安装 Docker,可以使用以下命令安装:
sudo yum update -y
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
  1. 将 Docker 镜像推送到 Docker Hub:
    在本地机器上,将构建的 Docker 镜像推送到 Docker Hub:
docker tag main-app your-dockerhub-username/main-app
docker tag sub-app-1 your-dockerhub-username/sub-app-1
docker tag sub-app-2 your-dockerhub-username/sub-app-2

docker push your-dockerhub-username/main-app
docker push your-dockerhub-username/sub-app-1
docker push your-dockerhub-username/sub-app-2
  1. 在服务器上拉取并运行 Docker 镜像:
    在服务器上,拉取并运行 Docker 镜像:
docker pull your-dockerhub-username/main-app
docker pull your-dockerhub-username/sub-app-1
docker pull your-dockerhub-username/sub-app-2

docker run -d -p 8000:80 your-dockerhub-username/main-app
docker run -d -p 7100:80 your-dockerhub-username/sub-app-1
docker run -d -p 7200:80 your-dockerhub-username/sub-app-2

通过这些步骤,你可以在 Node.js 18 环境下,用 React 18 创建一个基于 qiankun 的主应用和两个子应用,并使用 Nginx 作为静态文件服务器,部署到腾讯云 CentOS 7.6 服务器的 8000 端口进行访问。这样可以确保各个应用的隔离性和独立性,同时通过 /main 路由访问子应用。


网站公告

今日签到

点亮在社区的每一天
去签到