一鍵式自動給個人雲服務搭建常用平臺

請叫我大蘇發表於2023-12-29

背景

有時興致來了就喜歡瞎鼓搗,幾年前還是學生時買過學生優惠的雲伺服器,但沒錢續費關停後就不了了之,近期看到有活動又重新入手了
但問題就來了,之前好不容易搭建上去的各種服務,現在又得重新來一遍
幾年前還是學生時可能對這類環境搭建還比較感興趣
現在人老了,精力不夠了,做啥都考慮效率問題
如果幾年後又重新買了,豈不是又得重新來一遍?

所以啊,還是得搞個一鍵式操作,來把這類基礎、重複且低效的準備工作改造成自動化

訴求

覆蓋我日常使用的服務有:

  • 個人部落格、筆記平臺
    • 方便維護、查閱我過往積累的部落格和筆記
  • NextCloud
    • 個人雲網盤,也支援線上文件編輯、查閱(如線上 office)
  • UI 元件使用說明平臺
    • 方便我查閱過往封裝的通用 UI 元件的使用文件
  • Jenkins
    • 方便我自動化管理各個雲服務

那麼,該怎麼做呢?

準備工作

如果是第一次搞,那麼還是有些準備工作,就緒後,隨便在一臺新的雲服務執行下自動化指令碼完事

1. 資料、程式碼都上 github

  • 把部落格筆記平臺的各個 md 文件、圖片資源等都存放到 github 管理
  • 把元件使用平臺的專案程式碼也 github 管理
  • 把建立 docker 的相關配置檔案也 github 管理

既然要方便一鍵式部署,就把各種資料都儲存到網上,免費且穩定的應該就是 github 了,這樣後續就可以寫個自動化指令碼去自動拉取各個資料了

2. 編寫 docker-compose.yml 和各服務的 Dockerfile

各個雲服務透過 docker 來部署,環境搭建就可以做到一份配置,到處部署的效果了。

目錄結構說明

├─ doc # 部落格、筆記平臺,用 nginx 做容器
│ ├─ Dockerfile
│ ├─ nginx.conf
├─ jenkins # jenkins 平臺,預置好 node, pnpm 等環境
│ ├─ Dockerfile
├─ nginx # 監聽預設埠(80,443),根據二級域名做反向代理
│ ├─ Dockerfile
│ ├─ nginx.conf
├─ uidoc # 元件庫使用說明平臺,用 nginx 做容器
│ ├─ Dockerfile
│ ├─ nginx.conf
├─ docker-compose.yml # 上述容器的統一管理、通訊配置

jenkins 容器的 Dokcerfile

# 使用基於 Debian 的 Jenkins 映象作為基礎
FROM jenkins/jenkins:lts

# 切換到 root 使用者
USER root

# 安裝 Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs

# 安裝 pnpm
RUN npm install -g pnpm

# 安裝 yarn
RUN npm install -g yarn

# 切換回 Jenkins 使用者
USER jenkins

EXPOSE 8080

nginx 容器的反向代理配置

server {
    listen  80;
    listen [::]:80;
    server_name *.dasu.fun;
    client_max_body_size 1024M;

    location / {
      # 正則匹配二級域名,並賦值給變數 $domain
      if ($http_host ~* "^(.*?)\.dasu\.fun$") {
        set $domain $1;
      }
      # 根據二級域名,做反向代理轉發
      if ($domain ~* "jenkins") {
        proxy_pass http://192.168.5.104:8080;
      }
      if ($domain ~* "blog") {
        proxy_pass http://192.168.5.105;
      }
      if ($domain ~* "uidoc") {
        proxy_pass http://192.168.5.106;
      }
      if ($domain ~* "nextcloud") {
        proxy_pass http://192.168.5.108;
      }
      if ($domain ~* "doc") {
        proxy_pass http://192.168.5.110;
      }
      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_pass http://192.168.5.110;
    }
}

docker-compose.yml 配置

version: "3"

services:
  nginx:
    build: ./nginx/ # 使用位於 ./nginx/ 目錄中的 Dockerfile 來構建容器映象
    ports:
      - "80:80" # 將容器的 80 埠對映到主機的 80 埠
    restart: always # 容器停止後自動重啟
    networks:
      n_nginx:
        ipv4_address: 192.168.5.103 # 為容器分配指定的 IPv4 地址

  jenkins:
    build: ./jenkins/ # 使用位於 ./jenkins/ 目錄中的 Dockerfile 來構建容器映象
    ports:
      - "9001:8080" # 將容器的 8080 埠對映到主機的 9001 埠
      - "50000:50000" # 將容器的 50000 埠對映到主機的 50000 埠
    user: root # 在容器中以 root 使用者身份執行
    restart: always # 容器停止後自動重啟
    volumes:
      - /root/Doc/:/var/jenkins_home/doc/codes/ # 將主機的 /root/Doc/ 目錄掛載到容器的 /var/jenkins_home/doc/codes/ 目錄
      - /root/uidoc/:/var/jenkins_home/uidoc/codes/
      - /root/.ssh/:/root/.ssh/:ro # 將主機的 /root/.ssh/ 目錄掛載到容器的 /root/.ssh/ 目錄,並設定為只讀
      - /etc/localtime:/etc/localtime:ro # 將主機的 /etc/localtime 檔案掛載到容器的 /etc/localtime 檔案,並設定為只讀
    networks:
      n_nginx:
        ipv4_address: 192.168.5.104 # 為容器分配指定的 IPv4 地址

  uidoc:
    build: ./uidoc/ # 使用位於 ./uidoc/ 目錄中的 Dockerfile 來構建容器映象
    ports:
      - "9002:80" # 將容器的 80 埠對映到主機的 9002 埠
    restart: always # 容器停止後自動重啟
    volumes:
      - /root/uidoc/dist/:/usr/share/nginx/html/
    networks:
      n_nginx:
        ipv4_address: 192.168.5.106 # 為容器分配指定的 IPv4 地址

  db:
    image: postgres # 使用 PostgreSQL 映象
    restart: always # 容器停止後自動重啟
    environment:
      - POSTGRES_PASSWORD=222zaqXSW! # 設定 PostgreSQL 資料庫的密碼
      - POSTGRES_USER=postgres # 設定 PostgreSQL 資料庫的使用者名稱
    volumes:
      - /root/postgres/data:/var/lib/postgresql/data # 將主機的 /root/postgres/data 目錄掛載到容器的 /var/lib/postgresql/data 目錄
    expose:
      - "5432" # 暴露容器的 5432 埠給其他容器使用
    networks:
      n_nginx:
        ipv4_address: 192.168.5.107 # 為容器分配指定的 IPv4 地址

  nextcloud:
    image: nextcloud # 使用 Nextcloud 映象
    restart: always # 容器停止後自動重啟
    ports:
      - 9003:80 # 將容器的 80 埠對映到主機的 9003 埠
    depends_on:
      - db # 依賴於 db 服務,確保資料庫服務在 Nextcloud 服務啟動之前已經啟動
    environment:
      - POSTGRES_HOST=db # 設定 Nextcloud 使用的 PostgreSQL 資料庫的主機為 db
      - POSTGRES_DB=postgres # 設定 Nextcloud 使用的資料庫名稱
      - POSTGRES_USER=postgres # 設定 Nextcloud 使用的資料庫使用者名稱
      - POSTGRES_PASSWORD=222zaqXSW! # 設定 Nextcloud 使用的資料庫密碼
    volumes:
      - nextcloud:/var/www/html # 將名為 "nextcloud" 的卷掛載到容器的 /var/www/html 目錄
    networks:
      n_nginx:
        ipv4_address: 192.168.5.108 # 為容器分配指定的 IPv4 地址

  doc:
    build: ./doc/
    ports:
      - "9005:80"
    restart: always
    volumes:
      - /root/Doc/dist/:/usr/share/nginx/html/
    networks:
      n_nginx:
        ipv4_address: 192.168.5.110 # 為容器分配指定的 IPv4 地址

networks:
  n_nginx:
    driver: bridge # 使用橋接網路模式
    ipam:
      config:
        - subnet: 192.168.5.0/24 # 定義網路的子網地址範圍為 192.168.5.0/24,宿主機一般會是該網段的 .1,所以不要將網段設定為 1

# 命名卷是多容器共享卷,具有持久化能力
volumes:
  nextcloud:

3. 購買域名、備案和配置 DNS 解析

購買和備案自行參考域名購買的平臺指引
由於我使用到多個雲服務,而且是透過二級域名來區分,因此需要配置下各個二級域名的解析,如:

主機記錄(二級域名) 記錄值(雲伺服器 IP)
uidoc 59.110.12.xx
doc 59.110.12.xx
netcloud 59.110.12.xx
jenkins 59.110.12.xx
blog 59.110.12.xx
www 59.110.12.xx

4. 雲伺服器放開入埠

如果沒有購買域名,或者需要直接用 ip+port 訪問不同服務,那麼需要放開對應的埠,以阿里云為例,在域名控制檯-安全組-訪問規則-入方向裡配置:

自動化指令碼一鍵式部署

1. 雲服務生成 ssh

由於所有的資料都傳到 github 上了,因此需要先把雲伺服器的 ssh 配置到 github 上,以便伺服器有許可權拉取 github 專案

  • ssh-keygen -t rsa -b 4096 -C "xxx@qq.com"
  • cat .ssh/id_rsa.pub
  • 將第二步輸出的公鑰複製到 github 的 ssh 配置

2. 在伺服器上執行指令碼

cat << 'EOF' > setup.sh

#!/bin/bash

# 函式:列印日誌
log() {
  echo '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
  echo "$1"
}

# 更新軟體庫
sudo yum update -y
# 安裝 Docker 環境
log "開始安裝 Docker 環境..."
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
sudo systemctl start docker
sudo usermod -aG docker $USER
docker -v
log "Docker 環境安裝完成。"

# 安裝 Docker Compose 環境
log "開始安裝 Docker Compose 環境..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
log "Docker Compose 環境安裝完成。"
docker-compose --version

# 安裝 Git 環境
log "開始安裝 Git 環境..."
sudo yum install -y git
log "Git 環境安裝完成。"
git --version

# 安裝 nvm 和 Node.js 環境
log "開始安裝 nvm 和 Node.js 環境..."
curl -o- https://gitee.com/mirrors/nvm/raw/v0.39.0/install.sh | bash
source ~/.bashrc
nvm --version
nvm install --lts
npm config set registry https://registry.npm.taobao.org
log "nvm 和 Node.js 環境安裝完成。"
node -v

# 安裝 Whistle 環境
log "開始安裝 Whistle 環境..."
npm install whistle -g
log "Whistle 環境安裝完成。"
#w2 start

# 安裝 pnpm
log "開始 pnpm..."
npm install -g pnpm
pnpm -v

# 安裝 yarn
log "開始 yarn..."
npm install -g yarn
yarn -v


# 拉取 github 倉庫
log "拉取 github 倉庫..."

cd /root/
mkdir blog
mkdir github
mkdir postgres

echo -e "Host github.com\n  StrictHostKeyChecking no" >> ~/.ssh/config
git clone git@github.com:woshidasusu/dockers.git

cd /root/blog
git clone git@github.com:woshidasusu/woshidasusu.github.io.git

cd /root/
git clone git@github.com:woshidasusu/Doc.git
cd Doc
pnpm install
pnpm run build


cd /root/
git clone git@github.com:woshidasusu/uidoc.git
cd uidoc
npm install
npm run build


log "所有環境安裝完成。"
docker -v
docker-compose --version
node -v


EOF

  • 執行後,會在當前目錄下生成一份 setup.sh 檔案,繼續執行:
  • chmod +x setup.sh
    • 將檔案設定成可執行
  • bash setup.sh
    • 執行指令碼

指令碼會自動去安裝 docker, docker-compose, git, nvm, node, whistle 以及拉取 github 的專案
注:有些下載源是 github 的可能會失敗,如果失敗了需要手動執行,通常是 docker-compose 和 nvm 可能出現安裝失敗

docker-compose up -d

進入上述指令碼下載的 dockers 目錄,在該目錄執行:

  • docker-compose up -d

執行結束後,各服務容器就會建立並執行起來了,這時候瀏覽器訪問相關服務試試看就完事了


搞完這些後,我可以隨便格式化雲盤,每次重新搭時,先配置個 ssh,再執行下指令碼,服務就都自動搭建完畢,舒服~

相關文章