#self-hosted#server#tips

Giteaは最近Actionが使えるようになった。Dockerで別にランナーマシンを立ち上げる必要があるほか、GitHub Actionsと比べると、Concurrencyなどちゃんと効かなかったり色々まだ機能が足りてない所はある。

ただ、公開されてるGithubs Actionはそのままuseできるのが強い。actions/cache@v3の代わりにhttps://github.com/actions/cache@v3のようにURLで指定できる。よく使うアクションはgitea側にもミラーされていることもあるが、なんか放置されてるやつも多々あるので注意。

Pagesの機能がないため、別途サーバーを立ち上げてrsyncで同期するくらいしか方法がない。そこそこ設定は面倒くさいが、nginxよりさらに簡易的に動かせるgo製のWebサーバーCaddyを使ってなんとかすることにした。

下準備

鍵をssh-keygenで作っておく。(秘密鍵をGitea側のSecretsに置くので新しく生成しないとだめ)

ssh-keygen -t ed25519

ファイル名はrsync_webserverrsync_webserver.pubとかにしておく

Caddyサーバー側の構成

tomoyanonymous/Caddy_rsync_webserver - Caddy_rsync_webserver - Tomoya Matsuura Gitea

フォルダ構成

Dockerfile
docker-compose.yml
Caddyfile
docs/  #空フォルダ
rsync_webserver.pub #鍵をコピーしておく

rsyncでファイルを受け取る用のDockerイメージを作る

FROM ubuntu:latest
 
RUN apt-get update && apt-get install -y openssh-server rsync
RUN mkdir /var/run/sshd
 
RUN sed -i 's/#\?SyslogFacility AUTH/SyslogFacility AUTH/' /etc/ssh/sshd_config
RUN sed -i 's/#\?LogLevel INFO/LogLevel Info/' /etc/ssh/sshd_config
 
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
 
COPY rsync_webserver.pub /root/authorized_keys
 
RUN mkdir ~/.ssh && \
    mv ~/authorized_keys ~/.ssh/authorized_keys && \
    chmod 0600 ~/.ssh/authorized_keys && \
    chmod 0700 ~/.ssh
 
EXPOSE 22
 
CMD ["/usr/sbin/sshd", "-D"]

パーミッションは必ず~/.ssh/authorized_keysが600、~/.sshが700でないとssh接続できないので注意

docker-compose.ymlでCaddyとの連携設定。共通のボリュームでhtmlを管理するが、今回はそのフォルダをdocsという名前で作った。Caddyのイメージはそのまま使う。

version: '3'
 
services:
   ssh:
      build: .
      volumes:
        - ./docs:/var/www/html
      ports:
        - '25222:22'
   server:
     image: caddy:latest
     volumes:
       - ./Caddyfile:/etc/caddy/Caddyfile
       - ./docs:/www/html
     ports:
       - "8080:80"

Caddyファイルは最小限。

:80 {
  root * /www/html
  file_server
  try_files {path}.html {path}
  handle_errors {
    rewrite * /404.html
    file_server
  }
}

この辺参考。Serving static files using Caddy。Quartzでは/記事名.htmlexample.com/記事名でアクセスする必要があるのでtry_filesの行が必要。

docs内に適当なindex.htmlを置いてdocker-compose builddocker-compose up -dで立ち上げ、DockerホストのIP:8080で繋ぐとアクセスできる。

これをそのままCloudflare Tunnelで公開している。

Gitea側の設定

Action RunnerつきでGiteaを立ち上げるところまでは省略。

ほぼこのサイトの例を借りる。HugoじゃなくQuartzなので色々違うけど

CI/CD pipeline for a Hugo-built static page using Gitea Actions on a selfhosted Gitea instance · Julius Röttgermann | DevOps related Blog and Tutorials

リポジトリのSettings Actions SecretsにPRIVATE_KEYという名前でrsync_webserverの中身を貼り付ける。 同じくVariablesの方には以下を設定

  • WEBSERVER_HOST (Caddyが立ち上がっているサーバーのIP)
  • WEBSERVER_PORT (Caddyが立ち上がっているサーバーのSSH用ポート、上の例では25222)
  • WEBSERVER_USER :root(これあんまり良くないのかな)

で、リポジトリに/.gitea/workflows/ci.yamlを作る。Gitea Actionsのubuntu-latestラベルのランナーはデフォルトでDebianベースのnode:16-bullseyeのDockerイメージのエイリアスで(これまじでややこしい)、QuartzはNode18以降でないと動かない。またGoも入ってないので入れる。

name: Build
on:
  push:
    branches:
      - v4
jobs:
  build:
    env:
      RUNNER_TOOL_CACHE: /toolcache #これないとキャッシュが効かない
    runs-on: ubuntu-latest
    steps:
      - run: git config --global core.quotepath false
      - name: Install apt packages
        run: apt update && apt install -y rsync
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: https://github.com/actions/setup-node@v4
        with:
          node-version: 'latest'
      - uses: https://github.com/actions/setup-go@v4
        with:
          go-version: '^1.20'
      - uses: https://gitea.com/actions/[email protected]
        id: get-hash
        with: 
          patterns: |-
            **/package-lock.json      
      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ steps.get-hash.outputs.hash }}
          restore-keys: |
            ${{ runner.os }}-node-
      - run: npm i
      - run: npx quartz build
      - name: Create private key
        run: |
          echo "${{ secrets.PRIVATE_KEY }}" > /tmp/act_runner_key
          chmod 600 /tmp/act_runner_key
      - name: rsync public directory
        run: |
          rsync -avz --delete -e "ssh -i /tmp/act_runner_key -o StrictHostKeyChecking=no -p ${{ vars.WEBSERVER_PORT }}" ${{ gitea.workspace }}/public/* ${{ vars.WEBSERVER_USER }}@${{ vars.WEBSERVER_HOST }}:/var/www/html

できてますねえ!

Branch Previewが手軽にできればいいんだけどなあ