DockerでGnuCash用のPostgreSQL DBとgnucash-webをセルフホストしてTailscaleでアクセスする

どもども、情報学系会計職です。

会計職になってから久しく自分の家計簿なんてつけてなかったんですが、ふと医療費とか生命保険料とか社会保険料とか原神の廃課金とかを帳簿で管理したくなったので、GnuCashのセットアップを考えてみました。

# Dockerでどっか〜ん

結論から行きましょう。`docker-compose.yml` をご覧ください。

```
services:
  db:
    image: postgres:15-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: 'gnucash'
      POSTGRES_DB: 'gnucash'
      POSTGRES_PASSWORD: '*******' 
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    depends_on:
      - tailscale
    network_mode: "service:tailscale"
  app:
    image: ghcr.io/joshuabach/gnucash-web:main
    restart: unless-stopped
    environment:
      SECRET_KEY: '00000000000000000000000000000000'
      LOG_LEVEL: 'WARN'
      DB_DRIVER: 'postgresql'
      DB_NAME: 'gnucash'
      DB_HOST: 'localhost'
      AUTH_MECHANISM: 'passthrough'
      TRANSACTION_PAGE_LENGTH: 25
      PRESELECTED_CONTRA_ACCOUNT:
    depends_on:
      - db
      - tailscale
    network_mode: "service:tailscale"
  tailscale:
    image: tailscale/tailscale:latest
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_RAW
    environment:
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_EXTRA_ARGS=--advertise-exit-node=false
    volumes:
      - ./tailscale_state:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
```
基本的には[gnucash-web](https://github.com/joshuabach/gnucash-web.git)にある`docker-compose-postgres.yml`にTailscaleをがっちゃんこしただけですが、それ以外に特筆すべき点として、
* `DB_DRIVER`は`postgres`ではなく`postgresql`と書いてください。最新の`sqlalchemy`ではエラーします。
* `depends_on`と`network_mode`をTailscaleありきに設定します。Tailscaleは`localhost`のポートでないと`tailscale serve --bg`が通らないので、tailnetから使いたいポートはTailscaleコンテナに同居させる必要があります。

# composeを上げる

`docker-compose up -d`が上がったら、`docker-compose exec tailscale sh`して`tailscale up`と`tailscale serve --bg 8000`しましょう。
あと、必要があればTailscale管理コンソールでマシン名の設定とキー失効の無効化をしておきましょう。

さて、gnucash-webはDBの初期化をしてくれません。デスクトップ版GnuCashで作成した会計データを保存する必要があります。

![スクリーンショット 2025-03-30 10.04.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/34b3aecb-f6e2-4272-b0e9-9a1009c21512.png)
ファイルから「別名で保存」

![スクリーンショット 2025-03-30 10.06.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/565cf0c2-5882-4bae-83d5-1cf526cd227f.png)
データ形式は`postgres`

![スクリーンショット 2025-03-30 10.07.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/9647a408-c0ee-4a93-9f52-be569fe9c298.png)
Dockerコンテナに振られたTailscaleのホスト名と、composeで指定したDB名、ユーザー名、パスワード

あとは「別名で保存」を押せばDBに会計データが作成されます。

![スクリーンショット 2025-03-30 10.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/b9434026-44b5-42df-8b3a-4c78d8371306.png)
gnucash-webの使い方ですが、ここにはDBのユーザー名とパスワードを入れれば良いことになっています。

おわかりいただけるかと思いますが、こんなガバガバセキュリティなので、到底公開でホストするわけにはいきません。もともとGnuCashは1人で1箇所でしか開けないモデルなので、する意味もありません。そこでTailscaleで自分専用にホストする必要があるというわけです。

# 会計科目ってどうする?

ここからはシステム構築の話ではなくて、会計科目ってどうするっていう話ですね。

参考までに私の設定を…。

![スクリーンショット 2025-03-30 10.11.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4005442/96ddaa6d-a011-415f-8618-1426a5c8943c.png)

私はしがない会計事務所の雇われなので、実のところ自分の確定申告が必要になる見込みは今のところないです。ので、ほぼ家計簿ですね。
家計簿も複式簿記の方がつけやすいという気持ちの問題です。

「医療費」はつけておくと便利だと思います。給与所得者でも、これだけのために確定申告をする方も多いと思います。その段になって医療費レシートかき集めるのは大変です。電車で行った交通費も入れたいとかなるととにかくあとから思い出すのは大変です。記憶に新しいうちに記帳しましょう。

交通費ですが、ICカードの残高まで管理しているといよいよ会計事務じみてくるので、チャージはとりあえず「食費」と推定して仕訳して、医療費などの分は食費から振り替えるという仕訳をするのがよいでしょう。これは私の場合ですが、実際、iPhoneのモバイルPASMOにチャージしたほとんどの金額は駅の自販機で使っているからです。

社会保険料は、給与所得者であれば給与から天引きされているはずなので、給与明細を見ながら入れましょう。所得税も同様です。
通勤定期券の手当ですが、これは定期を買ったときに未収入金勘定を立てて、給与をもらったときに取り崩すという形式でもよいですし、私は面倒なので定期を買ったときにマイナスの非課税収入を上げて、給与の通勤手当を非課税収入に上げるのでよいかと考えています。
住民税は年末調整や確定申告に影響しないので、適当に入れておけばよいです。

不動産収入がある方は、「不動産収入」「不動産用租税公課」などの科目を設定しておくといいのではないでしょうか。
あと、流石に事業収入があって、インボイスを登録している方は、消費税の経理が必要なので、消費税法に適合した日本の会計ソフトを使ったほうが良いと思います。

以上、参考にしてみてください。