sroxck

sroxck

Record the process of building and deploying Mx-space + shiro from scratch.

mx space
is a simple yet powerful personal blog system that is fast and modern. You can use it to build your own personal space, record life, and share knowledge. mx Space core service; based on nestjs (nodejs), requires mongoDB and Redis to run completely.

shiro
is a theme system developed using React based on mx space.

Both systems have thousands of stars on GitHub, are relatively mature, and have many interesting features, so this blog reconstruction directly uses this system.

Preparation#

  1. One server, non-Windows is fine.
  2. One domain name, must have HTTPS.

First, we go to purchase a server, any configuration will do. You can look for some new customer discounts, something like a few dozen dollars a year is fine. Here I chose to buy a Tencent Cloud server, new customer 79 a year with a configuration of 2h2g and Baota Linux panel.

After purchasing the server, we reinstall the system in the Baota Linux panel. The default system for the server is Tencent Cloud OS. Here we install dockerCE from the panel, which will automatically configure the Tencent Cloud image.

You can also manually install docker and set the image to Alibaba Cloud.

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

After execution, check if it was successful.

docker -v
 
docker compose version

At this point, the server preparation work is complete.

Backend mx space Deployment#

Pull Configuration File#

Pull the configuration file in the server root directory.

cd && mkdir -p mx-space/core && cd $_
 
# Pull docker-compose.yml file
wget https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml

Configure Core Startup Configuration File#

Modify the values in the configuration file below to your own defined values.

- JWT_SECRET = your jwt
- ALLOWED_ORIGINS = your domain
- ENCRYPT_ENABLE = false
  • JWT Secret: A string of at least 16 characters and no more than 32 characters is required for encrypting the user's JWT. Be sure to keep your secret safe and do not disclose it to others.
  • Allowed Domains: Fill in the allowed domains, usually the front-end domain. If multiple domains are allowed to access, separate them with commas.
  • Enable Encryption: If you are sure you want to enable encryption, change false to true.

Start Core#

If your server is in China and cannot pull images or the pulling speed is too slow, you can use a proxy or add the image domain name before the image in docker-compose.yml, such as docker.1panel.top/innei/mx-server.

docker compose up -d

Nginx Reverse Proxy Configuration#

Install Nginx#

You can install it using docker; I am using system installation here.

sudo yum install nginx
# Check status
sudo systemctl status nginx
# Start service
sudo systemctl start nginx

By default, a single domain is used, meaning the backend management system and the blog display system use the same domain.

Additionally, whether for the front-end or back-end domain, you need to configure the HTTPS certificate to ensure the website can be accessed normally.

Replace the following SSL certificate with your own.

server {
    listen 80;
    listen 443 ssl http2 ; 
    ## Bind domain 
    server_name www.example.com; 
    index index.html; 
    proxy_set_header Host $host; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header X-Forwarded-Host $server_name; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    error_log /www/sites/www.example.com/log/error.log;
    access_log /www/sites/www.example.com/log/access.log; 
    location /socket.io {
        proxy_set_header Upgrade $http_upgrade; 
        proxy_set_header Connection "Upgrade"; 
        proxy_set_header Host $host; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto $scheme; 
        proxy_pass http://127.0.0.1:2333/socket.io; 
    }
    location /api/v2 {
        proxy_pass http://127.0.0.1:2333/api/v2; 
    }
    location /render {
        proxy_pass http://127.0.0.1:2333/render; 
    }
    location / {
        proxy_pass http://127.0.0.1:2323; 
    }
    location /qaqdmin {
        proxy_pass http://127.0.0.1:2333/proxy/qaqdmin;
    }
    location /proxy {
        proxy_pass http://127.0.0.1:2333/proxy;
    }
 
    location ~* \/(feed|sitemap|atom.xml) {
        proxy_pass http://127.0.0.1:2333/$1; 
    }
    ssl_certificate /www/sites/www.example.com/ssl/fullchain.pem; 
    ssl_certificate_key /www/sites/www.example.com/ssl/privkey.pem; 
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; 
    ssl_ciphers 'your code'; 
    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m; 
    ssl_session_timeout 10m; 
    error_page 497 https://$host$request_uri; 
    limit_conn perserver 300; 
    limit_conn perip 25; 
    limit_rate 512k; 
}

After successfully setting up the reverse proxy, log in to the backend through the bound domain to initialize.

Frontend shiro Deployment#

Ensure that the mx Space backend is installed and started.

Configure Cloud Functions#

Enter the mx Space backend, go to the "Configuration and Cloud Functions" page, click the new button in the upper right corner, and fill in the following settings in the edit page:

  • Name: shiro
  • Reference: theme
  • Data Type: JSON

Modify as needed for your configuration.

{
  "footer": {
    "otherInfo": {
      "date": "2020-{{now}}",
      "icp": {
        "text": "萌 ICP 备 20236136 号",
        "link": "https://icp.gov.moe/?keyword=20236136"
      }
    },
    "linkSections": [
      {
        "name": "About",
        "links": [
          {
            "name": "About this site",
            "href": "/about-site"
          },
          {
            "name": "About me",
            "href": "/about"
          },
          {
            "name": "About this project",
            "href": "https://github.com/innei/Shiro",
            "external": true
          }
        ]
      },
      {
        "name": "More",
        "links": [
          {
            "name": "Timeline",
            "href": "/timeline"
          },
          {
            "name": "Friend Links",
            "href": "/friends"
          },
          {
            "name": "Monitoring",
            "href": "https://status.innei.in/status/main",
            "external": true
          }
        ]
      },
      {
        "name": "Contact",
        "links": [
          {
            "name": "Leave a message",
            "href": "/message"
          },
          {
            "name": "Send an email",
            "href": "mailto:[email protected]",
            "external": true
          },
          {
            "name": "GitHub",
            "href": "https://github.com/innei",
            "external": true
          }
        ]
      }
    ]
  },
  "config": {
    "color": {
      "light": [
        "#33A6B8",
        "#FF6666",
        "#26A69A",
        "#fb7287",
        "#69a6cc",
        "#F11A7B",
        "#78C1F3",
        "#FF6666",
        "#7ACDF6"
      ],
      "dark": [
        "#F596AA",
        "#A0A7D4",
        "#ff7b7b",
        "#99D8CF",
        "#838BC6",
        "#FFE5AD",
        "#9BE8D8",
        "#A1CCD1",
        "#EAAEBA"
      ]
    },
 
    "bg": [
      "https://github.com/Innei/static/blob/master/images/F0q8mwwaIAEtird.jpeg?raw=true",
      "https://github.com/Innei/static/blob/master/images/IMG_2111.jpeg.webp.jpg?raw=true"
    ],
    "custom": {
      "css": [],
      "styles": [],
      "js": [],
      "scripts": []
    },
    "site": {
      "favicon": "/innei.svg",
      "faviconDark": "/innei-dark.svg"
    },
    "hero": {
      "title": {
        "template": [
          {
            "type": "h1",
            "text": "Hi, I'm ",
            "class": "font-light text-4xl"
          },
          {
            "type": "h1",
            "text": "Innei",
            "class": "font-medium mx-2 text-4xl"
          },
          {
            "type": "h1",
            "text": "👋。",
            "class": "font-light text-4xl"
          },
          {
            "type": "br"
          },
          {
            "type": "h1",
            "text": "A NodeJS Full Stack ",
            "class": "font-light text-4xl"
          },
          {
            "type": "code",
            "text": "<Developer />",
            "class": "font-medium mx-2 text-3xl rounded p-1 bg-gray-200 dark:bg-gray-800/0 hover:dark:bg-gray-800/100 bg-opacity-0 hover:bg-opacity-100 transition-background duration-200"
          },
          {
            "type": "span",
            "class": "inline-block w-[1px] h-8 -bottom-2 relative bg-gray-800/80 dark:bg-gray-200/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 group-hover:animation-blink"
          }
        ]
      },
      "description": "An independent developer coding with love."
    },
    "module": {
      "activity": {
        "enable": true,
        "endpoint": "/fn/ps/update"
      },
      "donate": {
        "enable": true,
        "link": "https://afdian.net/@Innei",
        "qrcode": [
          "https://cdn.jsdelivr.net/gh/Innei/img-bed@master/20191211132347.png",
          "https://cdn.innei.ren/bed/2023/0424213144.png"
        ]
      },
      "bilibili": {
        "liveId": 1434499
      }
    }
  }
}

Pre-Build Run#

Deploy using docker on the server.

mkdir shiro
cd shiro
wget https://raw.githubusercontent.com/Innei/Shiro/main/docker-compose.yml
wget https://raw.githubusercontent.com/Innei/Shiro/main/.env.template .env

vim .env # Modify your ENV variables
docker compose up -d

docker compose pull # Update images later

Modify ENV variables.

# Backend API address
NEXT_PUBLIC_API_URL=your api
# Backend gateway
NEXT_PUBLIC_GATEWAY_URL=your gateway

At this point, the deployment of the mx space + shiro blog site is complete. After logging into your domain for configuration, you can start writing!

This article is synchronized and updated to xLog by Mix Space.
The original link is http://www.sroxck.top/posts/note/record


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.