博客自动化部署-2020

去年写的一个博客 Actions 配合 Docker 的部署方法以及速度优化

由于时间间隔较长,并且实际上使用这个方案部署了两天后我就放弃了,所以本人无法保证本文的代码可以正常使用

Preface

去年年底想着高考完了优化一下博客的访问速度,且由于 Cloudflare + Github Pages 的 Free Server 方案在国内的速度是有所谓极限的,故后来尝试在 Aliyun 国内机上部署,就出现了这套方案。

TL;DR

本方案使用两个 repo,一个是存放博客源代码的,建议设为私有库,主要做代码管理,这里命名为 source-repo;另一个存放生成的静态文件,也就是 gh-pages 库,这里命名为 public-repo。

第一个 Actions 主要的事务

  • 根据 source-repo 的源代码构建静态网页文件
  • 将 Dockerfile、cert(optional not recommended) 放到网站根目录
  • 将第二个 Actions 放到 .github/workflows

第二个 Actions 主要的事务

  • 根据根目录构建一个 Apache Docker
  • 将构建好的镜像推送到阿里镜像仓库
  • 连接待部署的服务器并拉取镜像运行

tips: 由于双 Actions 方案稍微复杂,并不适合初入 Actions 的人,所以此处不再复述 repo、aliyun server、docker account 的访问和配置。

Code

Actions 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
name: Push CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [10.x]

    steps:
      - uses: actions/checkout@master

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - name: Environment Setup
        env:
          id_rsa: ${{ secrets.BLOG_ACTIONS_PRI }}
        run: |
          mkdir -p ~/.ssh/
          echo "$id_rsa" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          git config --global user.name 'iyume'
          git config --global user.email '[email protected]'          

      - name: Install Dependencies
        run: |
          npm i -g hexo-cli
          npm i          

      - name: Generate Public
        run: |
          gulp default          

      - name: First-Step Deployer
        run: |
          cd public
          mkdir -p .github/workflows
          cp ../two_step_deploy/actions.yml .github/workflows/actions.yml
          cp ../two_step_deploy/Dockerfile Dockerfile
          cp ../two_step_deploy/.dockerignore .dockerignore
          cp ../two_step_deploy/httpd.conf httpd.conf
          cp ../two_step_deploy/httpd-vhosts.conf httpd-vhosts.conf
          # cp ../two_step_deploy/cert cert -r
          git init
          git remote add origin [email protected]:iyume/hexo-blog.git
          git commit --allow-empty -n -m "Initial commit"
          git add .
          git commit -m "[Force Updated] Actions ID $GITHUB_RUN_NUMBER"
          git push origin master -f
          git branch gh-pages
          git checkout gh-pages
          git merge master
          git reset HEAD^
          git add .
          git rm --cached -r .github
          git commit -m "[Site Updated] Force Actions ID $GITHUB_RUN_NUMBER"
          git push origin gh-pages -f          

      - name: Second-Step Deployer
        run: |
          echo "Second-Step is deployed by repo hexo-blog"          

Actions 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
name: Docker Build and Push

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@master

      - name: Build and Push
        env:
          registry: ${{ secrets.REGISTRY }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
        run: |
          docker login --username $username --password $password registry.cn-hongkong.aliyuncs.com
          docker build -t $registry:$GITHUB_RUN_NUMBER .
          docker push $registry:$GITHUB_RUN_NUMBER
          docker tag $registry:$GITHUB_RUN_NUMBER $registry:latest
          docker push $registry:latest          

      - name: Pull and Deploy
        uses: appleboy/ssh-action@master
        env:
          registry: ${{ secrets.REGISTRY }} # can not be used as no-string
          repo_username: ${{ secrets.USERNAME }}
          repo_password: ${{ secrets.PASSWORD }}
        with:
          host: ${{ secrets.HOST_IP }}
          username: ${{ secrets.HOST_USERNAME }}
          password: ${{ secrets.HOST_PASSWORD }}
          port: 22
          envs: registry, repo_username, repo_password
          script: |
            docker stop myblog || true
            docker rm myblog || true
            docker rmi ${{ secrets.REGISTRY }}:latest || true
            docker login --username "$repo_username" --password "$repo_password" registry.cn-hongkong.aliyuncs.com
            docker pull ${{ secrets.REGISTRY }}:latest
            docker run -d --name myblog -p 80:80 -p 443:443 ${{ secrets.REGISTRY }}:latest            

Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
FROM httpd

WORKDIR /usr/local/apache2

RUN rm -rf htdocs/*
COPY . htdocs/
RUN rm conf/extra/httpd-vhosts.conf && mv htdocs/httpd-vhosts.conf conf/extra/httpd-vhosts.conf
RUN rm conf/httpd.conf && mv htdocs/httpd.conf conf/httpd.conf

# RUN mkdir cert
# COPY cert/* cert/

EXPOSE 80
EXPOSE 443
CC BY-NC-SA 4.0 License