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 set of systems.

Preparation#

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

First, we need to purchase a server, any configuration will do. You can look for some new customer discounts, something around a few dozen dollars a year is sufficient. Here, I chose to purchase a Tencent Cloud server, new customer price is 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 executing, 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 root directory of the server.

cd && mkdir -p mx-space/core && cd $_
 
# Pull the 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: Must be a string of at least 16 characters and no more than 32 characters, used to encrypt the user's JWT. Be sure to keep your secret safe and do not disclose it to others.
  • Allowed Domains: Must fill in the allowed domain names, 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, for example, docker.1panel.top/innei/mx-server.

docker compose up -d

Nginx Reverse Proxy Configuration#

Install Nginx#

You can install it using docker; I will use the system installation here.

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

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

Additionally, whether for the front-end or back-end domain names, you need to configure HTTPS certificates 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 name 
    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 name to initialize.

Frontend shiro Deployment#

Ensure that the mx Space backend is installed and started.

Configure Cloud Function#

Enter the mx Space backend, go to the "Configuration and Cloud Functions" page, click the add button in the upper right corner, and fill in the following settings in the editing 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.