如何在一台服务器上部署多个站点?

12 阅读

概览

你可以在同一台服务器上运行多个完全独立的 Halo 站点,每个站点拥有独立的数据目录、数据库和端口,通过反向代理绑定各自的域名。

本文提供两种方案:

  • 使用 1Panel:在应用商店中重复安装多个 Halo 应用即可,1Panel 会自动处理数据库创建、端口分配和域名绑定;

  • 使用 Docker Compose:手动编写编排文件,支持独立数据库和共享数据库两种部署结构。

方案一:使用 1Panel

1Panel 支持在同一台服务器上安装多个 Halo 应用,操作流程与安装第一个站点完全相同,重复执行即可。

操作步骤

  1. 进入 应用商店,找到 Halo 应用,点击安装;

  2. 为新站点填写不同的 名称 端口,避免与已有站点冲突,并按需配置数据库名、数据库用户等参数;

  3. 等待应用启动完成后,前往 网站 页面,点击 创建网站,在已装应用中选择刚刚新建的 Halo 应用,绑定对应的域名;

  4. 访问新域名完成 Halo 初始化

完整的安装参数说明可参考使用 1Panel 部署

方案二:使用 Docker Compose

独立数据库

每个站点携带自己的 PostgreSQL 容器,编排文件完全独立,互不干扰。

目录结构

~/
├── halo-site1/
│   ├── docker-compose.yaml
│   ├── halo2/
│   └── db/
└── halo-site2/
    ├── docker-compose.yaml
    ├── halo2/
    └── db/
mkdir ~/halo-site1 ~/halo-site2

站点一

version: "3"

services:
  halo:
    image: registry.fit2cloud.com/halo/halo-pro:2.23
    restart: on-failure:3
    depends_on:
      halodb:
        condition: service_healthy
    networks:
      halo_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8090:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=site1_db_password
      - --spring.sql.init.platform=postgresql
      - --halo.external-url=https://site1.yourdomain.com/

  halodb:
    image: postgres:15.4
    restart: on-failure:3
    networks:
      halo_network:
    volumes:
      - ./db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_PASSWORD=site1_db_password
      - POSTGRES_USER=halo
      - POSTGRES_DB=halo
      - PGUSER=halo

networks:
  halo_network:

站点二

将端口改为 8091,避免与站点一冲突:

version: "3"

services:
  halo:
    image: registry.fit2cloud.com/halo/halo-pro:2.23
    restart: on-failure:3
    depends_on:
      halodb:
        condition: service_healthy
    networks:
      halo_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8091:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8091/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=site2_db_password
      - --spring.sql.init.platform=postgresql
      - --halo.external-url=https://site2.yourdomain.com/

  halodb:
    image: postgres:15.4
    restart: on-failure:3
    networks:
      halo_network:
    volumes:
      - ./db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_PASSWORD=site2_db_password
      - POSTGRES_USER=halo
      - POSTGRES_DB=halo
      - PGUSER=halo

networks:
  halo_network:

启动服务

cd ~/halo-site1 && docker compose up -d
cd ~/halo-site2 && docker compose up -d

共享数据库

所有站点共用一个 PostgreSQL 实例,每个站点使用独立的数据库,可节省一个数据库容器的内存占用。

目录结构

~/
├── halo-db/
│   ├── docker-compose.yaml
│   └── data/
├── halo-site1/
│   ├── docker-compose.yaml
│   └── halo2/
└── halo-site2/
    ├── docker-compose.yaml
    └── halo2/

第一步:部署共享数据库

mkdir ~/halo-db

声明一个命名网络,供各站点共享访问:

version: "3"

services:
  halodb:
    image: postgres:15.4
    restart: on-failure:3
    networks:
      halo_db_network:
    volumes:
      - ./data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_PASSWORD=shared_db_password
      - POSTGRES_USER=halo
      - POSTGRES_DB=halo
      - PGUSER=halo

networks:
  halo_db_network:
    name: halo_db_network
cd ~/halo-db && docker compose up -d

第二步:为各站点创建数据库

docker exec -it halo-db-halodb-1 psql -U halo -c "CREATE DATABASE halo_site1;"
docker exec -it halo-db-halodb-1 psql -U halo -c "CREATE DATABASE halo_site2;"

容器名称默认由 Docker Compose 根据目录名和服务名生成,格式为 <目录名>-<服务名>-1。如果不确定容器名,可以运行 docker ps 查看。

第三步:部署各站点

各站点的编排文件不包含数据库服务,通过 external: true 接入共享网络,r2dbc.url 中的数据库名与上一步创建的对应:

version: "3"

services:
  halo:
    image: registry.fit2cloud.com/halo/halo-pro:2.23
    restart: on-failure:3
    networks:
      halo_db_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8090:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo_site1
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=shared_db_password
      - --spring.sql.init.platform=postgresql
      - --halo.external-url=https://site1.yourdomain.com/

networks:
  halo_db_network:
    external: true
version: "3"

services:
  halo:
    image: registry.fit2cloud.com/halo/halo-pro:2.23
    restart: on-failure:3
    networks:
      halo_db_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8091:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8091/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    environment:
      - JVM_OPTS=-Xmx256m -Xms256m
    command:
      - --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo_site2
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=shared_db_password
      - --spring.sql.init.platform=postgresql
      - --halo.external-url=https://site2.yourdomain.com/

networks:
  halo_db_network:
    external: true
cd ~/halo-site1 && docker compose up -d
cd ~/halo-site2 && docker compose up -d

配置反向代理(Docker Compose 方案)

通过 Nginx 将不同域名代理到对应端口:

upstream halo-site1 {
  server 127.0.0.1:8090;
}
server {
  listen 80;
  server_name site1.yourdomain.com;
  client_max_body_size 1024m;
  location / {
    proxy_pass http://halo-site1;
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

upstream halo-site2 {
  server 127.0.0.1:8091;
}
server {
  listen 80;
  server_name site2.yourdomain.com;
  client_max_body_size 1024m;
  location / {
    proxy_pass http://halo-site2;
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

注意事项

  • 每个站点的端口号必须唯一,不能与服务器上已占用的端口冲突;

  • 服务器的内存和 CPU 资源由所有站点共享,每个 Halo 实例默认占用约 256 MB 内存,请根据实际资源情况决定部署的站点数量;

  • 使用共享数据库时,需确保数据库容器先于所有 Halo 站点启动;若共享数据库容器重启,所有站点将同时不可访问。


评论