Cloudflare Tunnel + apisix + halo + docker折腾小记
目的
目标是将家中小型主机上运行的服务容器化,并通过内网穿透使其可以从公网访问。
技术选型
- halo
Halo [ˈheɪloʊ],强大易用的开源建站工具。是时候给hexo加个后台了。 - apisix
Apache APISIX 是一个高性能、可扩展的开源 API 网关。这里用来管理和控制容器化后的服务。 - cloudflare tunnel
cloudflare的内网穿透工具,免费! 
目录结构
.
├── apisix-docker
│   ├── apisix_conf
│   ├── dashboard_conf
│   ├── docker-compose.yml
│   ├── etcd_conf
│   ├── grafana_conf
│   ├── mkcert
│   ├── .env
│   ├── prometheus_conf
│   └── upstream
├── blog
│   ├── docker-compose.yml
│   ├── halo2
│   ├── mysql
│   └── mysqlBackup
└── container-cloudflare-tunnel
    ├── config
    └── docker-compose.yml
apisix
- 
这里去掉了grafana和普罗米修斯
 - 
将apisix的默认9080映射到宿主机的80端口,顺眼
 - 
给network改了个名字,方便其他的docker加入
 - 
增加.env,规范network的生成
COMPOSE_PROJECT_NAME=b1ank➜ app docker network ls NETWORK ID NAME DRIVER SCOPE 40fe9edd7249 b1ank_home bridge local - 
注意修改默认的admin_key和用户名密码
apisix-docker/apisix_conf/config.yaml
apisix-docker/dashboard_conf/conf.yaml 
version: "3"
services:
  apisix-dashboard:
    image: apache/apisix-dashboard:3.0.1-alpine
    restart: always
    volumes:
    - ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
    ports:
    - "9000:9000"
    networks:
      home:
  apisix:
    image: apache/apisix:${APISIX_IMAGE_TAG:-3.5.0-debian}
    restart: always
    volumes:
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
    depends_on:
      - etcd
    ports:
      - "9180:9180/tcp"
      - "80:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"
      - "9092:9092/tcp"
    networks:
      home:
  etcd:
    image: bitnami/etcd:3.4.15
    restart: always
    volumes:
      - etcd_data:/bitnami/etcd
    environment:
      ETCD_ENABLE_V2: "true"
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379"
      ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
    ports:
      - "2379:2379/tcp"
    networks:
      home:
networks:
  home:
    driver: bridge
    ipam:
      config:
        - subnet: 172.128.2.0/24        
volumes:
  etcd_data:
    driver: local
halo
参考官方文档
- 先改掉默认的数据库密码
 - 修改
halo.external-url - 注释掉mysql映射出来的3306,因为不需要外部连接,容器间互相本身是连通的
 
version: "3"
services:
  halo:
    image: halohub/halo:2.10
    container_name: halo
    restart: on-failure:3
    depends_on:
      halodb:
        condition: service_healthy
    networks:
      halo_network:
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8080:8090"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    command:
      - --spring.r2dbc.url=r2dbc:pool:mysql://halodb:3306/halo
      - --spring.r2dbc.username=root
      # MySQL 的密码,请保证与下方 MYSQL_ROOT_PASSWORD 的变量值一致。
      - --spring.r2dbc.password=changeme
      - --spring.sql.init.platform=mysql
      # 外部访问地址,请根据实际需要修改
      - --halo.external-url=http://192.168.0.114:8080/
  halodb:
    image: mysql:8.1.0
    container_name: halodb
    restart: on-failure:3
    networks:
      halo_network:
    command: 
      - --default-authentication-plugin=caching_sha2_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
      - --explicit_defaults_for_timestamp=true
    volumes:
      - ./mysql:/var/lib/mysql
      - ./mysqlBackup:/data/mysqlBackup
    #ports:
    #  - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
      interval: 3s
      retries: 5
      start_period: 30s
    environment:
      # 请修改此密码,并对应修改上方 Halo 服务的 SPRING_R2DBC_PASSWORD 变量值
      - MYSQL_ROOT_PASSWORD=changeme
      - MYSQL_DATABASE=halo
networks:
  halo_network:
Cloudflare Tunnel
创建tunnel参考CloudFlare Tunnel 免费内网穿透的简明教程
- 设置付款方式的时候直接关掉页面重新进似乎可以绕过
 - 将此处的token保存好,后面要用

 
容器化参考container-cloudflare-tunnel
- 改成从远程仓库拉,不自己build了
 - network连的apisix的,取消了原来的host,收敛暴露面
networks: b1ank_home: external: true - token在.env里面配置
 
version: '3'
# service description
services:
  # cloudflare tunnel
  cloudflare-tunnel:
    image: cloudflare/cloudflared
    #build:
    #  context: ./src
    #  dockerfile: ./Dockerfile
    container_name: cloudflare-tunnel
    hostname: cloudflare-tunnel
    restart: unless-stopped
    networks:
      b1ank_home:
    command: tunnel run
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config/hosts:/etc/hosts
    environment:
      - "TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}"
    labels:
      # enbale watchtower updates
      - "com.centurylinklabs.watchtower.enable=true"
networks:
  b1ank_home:
    external: true
服务配置
- 
配置上游

 - 
配置路由,并且启用插件配置如下,目的是限制外部访问管理后台
 
{
  "_meta": {
    "disable": false
  },
  "block_rules": [
    "/console"
  ],
  "rejected_code": 404,
  "rejected_msg": "404 page not found"
}


- cloudflare处配置服务,统一配apisix,由apisix来做反向代理
 
