gitlistからgiteaへ

2021年6月16日

前回はdockerコンテナの起動・停止を独立してできるようにしたので、

今回は新しいコンテナでgitを動かしてみます。

VALUE SERVERはレンタル共有サーバーであり、まともに動くのはPHPだけでした。バージョンは多少古いもののgitコマンドも元から入っており、この組み合わせでgitリポジトリをセルフホストするなら、gitコマンドを必要とし、PHPで動作するgitlistは最適だったと思います。

しかしConoHa VPSに移行しPHP縛りという呪いから開放された現在、同じgitlistで満足してていいのか?と自問した結果、以下の3択ではないかとの結論に至りました。

  1. 見た目はショボいが最高に低コストで動作する、本家git付属のGitWebに移行
  2. 見た目もそこそこでコストがPHP分だけになる、gitlistの続投
  3. 見た目も機能も抜群に良く、同等な機能を持つ競合に比べてコストが低いgiteaに移行

VPSがメモリ1Gでなければ迷わず3なのですが、その気になればプルリクエストが出来たり認証手段も豊富な高機能gitリポジトリセルフホスティングアプリはメモリ消費量が格段に多いのです。giteaはgoで書かれ、Raspberry Piでも動く軽量アプリというのが売りなのですが、それでも何もしてなくてもRSSが150MBほどなわけです。PHPや他のプロセスが50MB程度で顔デカイと思われてる中、その3倍の幅で鎮座しちゃってるのです。しかも仮想メモリVSZを見るとこの人1GBほど使ってて、もう無理!とほぼ諦めてGitWebを調べ始めてたのですが、、、こないだpsコマンドやらtopコマンドやら/procやらで消費メモリをいろいろ見た結果、仮想メモリは障らなければ恐るるに足らずということが分かったため、

一度gitea試してみることになり、今回の設置と相成りました。

Giteaの設置

gitea自身はdockerイメージも公式に配布しているので、それをそのまま使用しますが、nginxでhttps→httpのリバースプロキシしつつVirtualHostで別ドメインとして動かします。

サブドメイン追加

ConoHaのDNSにgitという名前のCNAMEレコードを追加します。

関連記事

サブドメインのSSL証明書を取得

Let’s Encryptでgitサブドメイン(git.elephantcat.work)の証明書を取得します。certbotのあるディレクトリで以下のファイルを作成して…

DOMAIN="git.elephantcat.work"
EMAIL="更新通知を受け取りたいメールアドレス"

登録用のシェルスクリプトを実行します。

$ bash register.sh git

成功すると「Congratulations! Your certificate and chain have been saved at:」と表示されて、証明書の位置を教えてくれます。

関連記事

nginxでリバースプロキシ設定

gitea用設定のため、gitea.confを作成します。

server {
  listen 443 ssl; 
  server_name git.elephantcat.work; 
  ssl_certificate     /etc/letsencrypt/live/git.elephantcat.work/fullchain.pem;
  ssl_certificate_key   /etc/letsencrypt/live/git.elephantcat.work/privkey.pem;
  location / {
    resolver 127.0.0.11 valid=30s;
    set $variable gitea;
    proxy_pass http://$variable:3000;
  }
}

作成したファイルをnginxの設定として読み込まれるようにdocker-compose.ymlでマウントします。

version: "3"
services:
  nginx:
    image: nginx
    restart: always
    volumes:
      - ./../wordpress_fpm/wordpress:/var/www/html
      - ./wordpress-fpm.conf:/etc/nginx/conf.d/default.conf
      - ./gitea.conf:/etc/nginx/conf.d/gitea.conf
      - ./(certbotへの相対パス)/etc/letsencrypt:/etc/letsencrypt/
    ports:
      - 443:443
    networks:
      - frontend

networks:
  frontend:
    external: true

WordPress用設定のwordpress_fpm.conf中のlistenディレクティブにdefault_serverを追加し、万一迷子の443ポートで来たときはWordPress側に行くようにしておきます(一応こちらをデフォルトのファイル名にしてるので何となく)。

- listen 443 ssl;
---
+ listen 443 default_server ssl;

http://nginx.org/en/docs/http/ngx_http_core_module.html#listen

ここまででプロキシの転送先は実在していませんがnginxは起動可能で、とりあえずgiteaを呼び出すまでの枠組みは出来ました。

関連記事

giteaコンテナとアプリの設定

まずはコンテナの設定(参考)。

version: "3"
  
networks:
  frontend:
    external: false

services:
  gitea:
    image: gitea/gitea:1.14.2
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - frontend
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

ここでネットワークはわざとexternal: falseにしてnginxから転送されないようにしておきます。初回起動時に設定ファイルを./giteaに書き出してもらって、必要な設定をした後に繋がるようにするためです。まずはdocker-compose up -dで起動して、ユーザーだけ作ります。

$ docker-compose up -d
$ docker-compose exec gitea bash
# su git
$ gitea migrate
$ gitea admin user create --username (ユーザー名) --admin --email (メールアドレス) --password (パスワード)
$ exit
# exit
$ docker-compose down

停止後に、作成された./gitea/gitea/conf/app.iniを編集し、ほとんどの有用な機能を停止します(メモリとセキュリティから)。

...
#ROOT_URL         = 
ROOT_URL         = https://git.elephantcat.work/
#DISABLE_SSH      = false
DISABLE_SSH      = true
...
#INSTALL_LOCK                  = false
INSTALL_LOCK                  = true
...
#DISABLE_REGISTRATION = false
DISABLE_REGISTRATION = true
...
[oauth2]
# add
ENABLE = false
...
# add
[api]
# add
ENABLE_SWAGGER = false

一旦起動させてログを確認し、うまく動きそうなら、再度停止し、YAMLのexternalをtrueに変更して外から繋がるようにして起動します。

$ docker-compose up -d
$ docker-compose logs -f
...
...s/graceful/server.go:55:NewServer() [I] Starting new Web server: tcp:0.0.0.0:3000 on PID: 16
^C
$ docker-compose down
$ vi docker-compose.yml # externalをtrueに
$ docker-compose up -d

起動したら(このサーバーだと)以下のURLでアクセスです。

https://git.elephantcat.work/

成功すると、こんな画面が出てきます。

リポジトリの復旧

作成したユーザーでVALUE SERVERで公開してたリポジトリを復元しました。

過去記事内のリンクの張り直し

過去記事内で参照されていたgitlist用のリンクをgitea用のリンクに変更しました。

メモリ確認

topです。

Tasks: 136 total,   1 running, 135 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.7 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.2 st
MiB Mem :    981.0 total,    218.3 free,    413.4 used,    349.3 buff/cache
MiB Swap:   2048.0 total,   1666.0 free,    382.0 used.    393.1 avail Mem 

    PID USER      PR  NI    VIRT    RES   SWAP   USED    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                 
  56946 systemd+  20   0 1731064  62992 287488 350480   3260 S   0.0   6.3   4:18.37 mysqld                                                                                                  
  94613 user      20   0  931480 176396    204 176600  58456 S   2.3  17.6   1:28.69 gitea                                                                                                   
  52685 root      20   0 1356924  32824  21664  54488  10292 S   0.0   3.3   1:22.31 dockerd                                                                                                 
  95972 www-data  20   0  316972  43100   3260  46360  30296 S   0.0   4.3   0:02.54 php-fpm                                                                                                 
  57128 www-data  20   0  317948  40464   3764  44228  27160 S   0.0   4.0   0:28.16 php-fpm                                                                                                 
  92256 www-data  20   0  317672  40280   3232  43512  26812 S   0.0   4.0   0:16.48 php-fpm                                                                                                 
    797 root      20   0 1046560  10712  13224  23936   1952 S   0.3   1.1  17:26.45 containerd 

コンテナのプロセスはホストから普通に見えるから便利!

USEDでは普通にMySQLが一番使ってますが、RESは献身的なほど小さいですね。
その点giteaはUSED分ほぼ全て(180MB)RESを使ってます。

まとめ

giteaは180MBも使ってるし、php-fpmも何も制御がないので、このサイト同時にいろいろアクセスされたら簡単に落ちるでしょうね。まあいろいろ問題もありますが、どうせBOTと悪戯キッズ以外来訪者のいないこのサイトなら、きっとひっそり動いてると信じて今回は終わります。

次回も移行出来てない部分の事後処理かなぁ…