Traefik2 和 GHOST4 升级

这是一篇用 GHOST 4 发布的博客。

Traefik 升级

这次重新部署个人博客,发现 Traefik 已经从 V1 升级到 V2 了,于是也顺手升了一波,不过过程也是挺坎坷的,遇到了不少问题,配置方面变化还是挺大的,最后花了不少时间研究才解决的。

相比 NGINX,我更喜欢 Traefik,主要原因是它的功能很丰富很强大,配置简单清晰,本身支持 LET'S ENCRYPT SSL 证书的自动续期。而 NGINX 要实现 SSL 证书自动续期还需要配合其他的东西。并且 Traefik 对 Docker Swarm 支持更好,当时因为在研究个人博客的集群部署方案,所以转向了 Traefik。

分享下自己的 DockerCompose 配置文件,上次部署的时候还是集群部署的方案,但这次因为服务器只有一台,集群就没必要了,我对配置也做了一些改造。Docker 的强大之处就在于这个配置文件带上几个持久化目录,压缩完成之后,换个服务器解压然后 docker-compose up 就可以重新运行起来了,非常方便。

version: '3.3'
services:
  traefik:
    image: traefik
    networks:
      - traefik-net
    volumes:
      - './config/traefik_dynamic.toml:/traefik_dynamic.toml'
      - './logs/traefik:/data/logs'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - './config/acme.json:/acme.json'
      - './config/certs:/certs'
    ports:
      - '80:80/tcp'
      - '443:443/tcp'
    labels:
      traefik.enable: "true"
      traefik.docker.network: "traefik-net"
      traefik.http.routers.traefik.rule: "Host(`dashboard.ruiming.me`)"
      traefik.http.routers.traefik.service: api@internal
      traefik.http.routers.traefik.tls: "true"
      traefik.http.routers.traefik.tls.certResolver: "default"
      traefik.http.routers.traefik.middlewares: "secure,auth"
      traefik.http.middlewares.auth.basicauth.users: "XXXXX:$$apr1$$9XXXXXXXXXXXqkE.b.."
      traefik.http.middlewares.secure.headers.stsincludesubdomains: "true"
      traefik.http.middlewares.secure.headers.stspreload: "true"
      traefik.http.middlewares.secure.headers.stsseconds: 31536000
      traefik.http.middlewares.secure.headers.forceSTSHeader: "true"
      traefik.http.middlewares.secure.headers.frameDeny: "true"
      traefik.http.middlewares.secure.headers.referrerPolicy: "same-origin"
      traefik.http.middlewares.secure.headers.browserXssFilter: "true"
      traefik.http.middlewares.secure.headers.contentTypeNosniff: "true"
      traefik.http.middlewares.secure.headers.isdevelopment: "false"
    environment:
      CF_API_EMAIL: test@gmail.com
      CF_API_KEY: test
    command:
      - "--log.level=WARN"
      - '--api.insecure=true'
      - '--providers.docker=true'
      - '--providers.docker.exposedbydefault=false'
      - '--providers.file.filename=/traefik_dynamic.toml'
      - '--providers.file.watch=true'
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--certificatesresolvers.default.acme.dnschallenge=true"
      - "--certificatesresolvers.default.acme.dnschallenge.provider=cloudflare"
      - "--certificatesresolvers.default.acme.email=test@gmail.com"
      - "--certificatesresolvers.default.acme.storage=/acme.json"

  mysql:
    image: 'mysql:5.7'
    networks:
      - traefik-net
    environment:
        MYSQL_ROOT_PASSWORD: test
    volumes:
      - './applications/mysql:/var/lib/mysql' # MySQL 数据
    ports:
      - '23412:3306'

  ghost:
    image: 'ghost:4-alpine'
    networks:
      - traefik-net
    labels:
      - traefik.enable=true
      - traefik.http.routers.ghost.tls=true
      - traefik.http.routers.ghost.tls.certResolver=default
      - traefik.http.routers.ghost.rule=Host(`ruiming.me`)
      - traefik.http.routers.ghost.middlewares=secure
    volumes:
      - './applications/ghost:/var/lib/ghost/content'
    depends_on:
      - mysql
    environment:
      url: https://ruiming.me
      database__connection__password: test
      database__connection__user: root
      GHOST_ROOT_URL: http://ruiming.me
      database__client: mysql
      database__connection__host: mysql
      database__connection__database: ghost

networks:
  traefik-net:
    external: true

上面我对 Traefik 做了不少的配置,包括 HTTP 自动跳转 HTTPS,HSTS,以及 SSL 安全性的配置(这部分在 traefik_dynamic.toml 文件中,内容如下)

[tls.options]
  [tls.options.default]
    minVersion = "VersionTLS12"
    sniStrict = true
    cipherSuites = [
      "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
      "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
    ]
    curvePreferences = [
      "secp521r1",
      "secp384r1"
    ]

这个配置可以在 SSL Qualify 拿到 A+ 的分数(图片好像渲染有点问题,可能是我的主题是 1.0 传承下来的原因。。。):

GHOST 升级

之前博客一直是用的 GHOST 1 的版本,运行了挺久的了,也一直没更新。直到最近 GHOST 提示我升级,我一看好家伙都从 1 跨度到 4 了,就想着升级看看有啥新功能。

总体而言这次升级还是比较让我失望升级花了不少时间,我一开始直接尝试升级到 4 版本,直接就报错跑不起来了。于是又参考网上教程,进到 Docker 容器内部准备手动先执行 GHOST UPDATE,但是搞了半天命令还是运行不起来,各种报错。最后解决方法是,把 GHOST 的镜像先升级到 1 最新版本,再升级到 2 最新版本,以此类推终于升级上去了。

升级了 GHOST 之后,我用的还是以前的主题。我打算再多体验一下 GHOST,如果新版本好用的话,后面也许我会自己开发一个主题。如果不好用,那我可能会迁出 GHOST 哈哈。