Teruhiro Komaki

日々の暮らし、技術的な学び、そして仕事の記録

自分だけのメモ環境を構築するため、軽量SNSの「GoToSocial」をセルフホストで構築した記録

GoToSocialサーバーを構築しました

先日よりGoToSocialをセルフホスト(Cloudflare Tunnel + Proxmox + Debian 12)して、使い始めました。

GoToSocial - Fast, fun, ActivityPub server, powered by Go.

事務所での停電や、地域での停電がない限り安定して運用できるはずです。

運用を始めて、数日たちましたが、すごく快適です。一番気になる検索周りを確認しましたが、想定した通りの検索結果が取得できましたので、今のところ不満はありません。安心して投稿しています。

私のアカウントのURLは、以下になります。当然サインアップも拒否していますし、サーバーに存在するアカウントは私一人のみです。

個人的なメモや記録目的で投稿している程度ですので、役に立つ情報は少ないかもしれません。

Teruhiro Komaki, @teruhirokomaki@social.teruhirokomaki.com

きっかけ

以前は、Twitterを使っていましたが、いつからか使わなくなりました。現在では、特定の技術の収集のために不定期で閲覧する程度です。

振り返ると、自分のツイートの内容は、技術関連の記事や、興味を持っている内容の情報共有がほとんどでした。

そのため、リンクを共有する程度や短文で誰にも気兼ねなく投稿できる環境はないかな…と探していました。

有力な候補としてMastodonのセルフホストを検討しましたが、インストールは大丈夫でも「長期的な運用が大変そうだな」と思い、なかなか進みませんでした。

そんななか、ふとGeminiに「MastodonのようなSNSで、軽量な代替ツールは?」と聞いたらGoToSocialと回答されたことがきっかけで存在を知りました。

GoToSocial is an ActivityPub social network server, written in Golang.

GoToSocial provides a lightweight, customizable, and safety-focused entryway into the Fediverse.

With GoToSocial, you can keep in touch with your friends, post, read, and share images and articles.

All without being tracked or advertised to!

GoToSocialは、Golangで書かれたActivityPubのソーシャルネットワークサーバーです。

GoToSocialは、軽量でカスタマイズ可能、そして安全性を重視したFediverseへの入り口を提供します。

GoToSocialを使えば、追跡されたり広告を表示されたりすることなく、友人と連絡を取り合ったり、投稿したり、画像や記事を読んだり、共有したりすることができます。

GoToSocial - Fast, fun, ActivityPub server, powered by Go.

教えてもらって、確認したらGolangで書かれたサーバーという点、軽量でスペックの低いマシンでも運用できる点、データベースをSQLiteで運用できる点、など大変興味深く使ってみたいと思いました。

上記の構成から、長期的にも安心して運用できると考えました。また、バージョンアップ時には、画像などのバイナリファイルやデータベースの移行もあると思うと、できる限り軽量で概要を理解できる程度のツールが良いと思いました。

インストール関連

求めていたツールにぴったりでした。Geminiでドキュメントを確認してもらい、概要、手順、インストール時のコマンドやシェルスクリプトを組み立ててもらいました。

そのコマンドやシェルスクリプトの内容をもとにして、AnsibleのPlaybookを作成してもらいました。

最近では、ProxmoxでDebianを起動したあとに、Ansibleを実行して環境を整えております。まだ、Ansibleを使ったことがなく、SSHして手動で構築されているようであれば、Ansibleを調べてもらうと良いと思います。

各種サンプルファイル

以下に概要として、各ファイルを記載しておきますので、参考にしてもらえればと思います。

ディレクトリ構成

.
├── install_gotosocial.yml      # (1) Playbook本体
└── roles/
    └── gotosocial/
        ├── tasks/
        │   └── main.yml        # (2) 実行するタスク一覧
        └── templates/
            ├── config.yaml.j2        # (3) GoToSocial設定ファイルのテンプレート
            └── gotosocial.service.j2   # (4) systemdサービスファイルのテンプレート
ディレクトリ構成

Playbook本体

# install_gotosocial.yml
- hosts: all
  become: yes
  vars:
    # --- ユーザーが設定する変数 ---
    # インストールしたいGoToSocialのバージョン
    gotosocial_version: "0.19.0"
    # あなたのサーバーのドメイン名
    gotosocial_host: "social.example.com"

    # --- システム内部で使う変数 (基本的に変更不要) ---
    gotosocial_user: "gotosocial"
    gotosocial_group: "gotosocial"
    gotosocial_base_dir: "/var/lib/gotosocial"
    gotosocial_config_dir: "/etc/gotosocial"
    gotosocial_log_dir: "/var/log/gotosocial"
    gotosocial_bin_path: "/usr/local/bin/gotosocial"

  roles:
    - gotosocial
install_gotosocial.yml

実行タスク一覧

# roles/gotosocial/tasks/main.yml
- name: GoToSocial | 専用のグループを作成
  ansible.builtin.group:
    name: "{{ gotosocial_group }}"
    state: present
    system: yes

- name: GoToSocial | 専用のユーザーを作成
  ansible.builtin.user:
    name: "{{ gotosocial_user }}"
    group: "{{ gotosocial_group }}"
    state: present
    create_home: no
    shell: "/bin/false"
    system: yes

- name: GoToSocial | 必要なディレクトリを作成
  ansible.builtin.file:
    path: "{{ item }}"
    state: directory
    owner: "{{ gotosocial_user }}"
    group: "{{ gotosocial_group }}"
    mode: "0755"
  loop:
    - "{{ gotosocial_config_dir }}"
    - "{{ gotosocial_base_dir }}"
    - "{{ gotosocial_base_dir }}/web"
    - "{{ gotosocial_base_dir }}/storage"
    - "{{ gotosocial_log_dir }}"

- name: GoToSocial | バイナリをダウンロードして展開
  ansible.builtin.unarchive:
    src: "https://github.com/superseriousbusiness/gotosocial/releases/download/v{{ gotosocial_version }}/gotosocial_{{ gotosocial_version }}_linux_amd64.tar.gz"
    dest: "/tmp/"
    remote_src: yes
    creates: "/tmp/gotosocial"

- name: GoToSocial | バイナリを/usr/local/binに配置
  ansible.builtin.copy:
    src: "/tmp/gotosocial"
    dest: "{{ gotosocial_bin_path }}"
    remote_src: yes
    mode: "0755"
    owner: "root"
    group: "root"

- name: GoToSocial | Webリソースを配置
  ansible.builtin.copy:
    src: "/tmp/web/"
    dest: "{{ gotosocial_base_dir }}/web/"
    remote_src: yes
    owner: "{{ gotosocial_user }}"
    group: "{{ gotosocial_group }}"

- name: GoToSocial | 設定ファイル(config.yaml)を生成
  ansible.builtin.template:
    src: "config.yaml.j2"
    dest: "{{ gotosocial_config_dir }}/config.yaml"
    owner: "{{ gotosocial_user }}"
    group: "{{ gotosocial_group }}"
    mode: "0640"

- name: GoToSocial | systemdサービスファイルを生成
  ansible.builtin.template:
    src: "gotosocial.service.j2"
    dest: "/etc/systemd/system/gotosocial.service"
    owner: "root"
    group: "root"
    mode: "0644"

- name: GoToSocial | サービスを起動・有効化
  ansible.builtin.systemd:
    name: "gotosocial"
    daemon_reload: yes
    state: restarted
    enabled: yes
roles/gotosocial/tasks/main.yml

GoToSocial設定ファイルのテンプレート

# roles/gotosocial/templates/config.yaml.j2
# -- GENERAL CONFIG --
# ドメイン名
host: "{{ gotosocial_host }}"
# リバースプロキシ経由でアクセスするためlocalhostにバインド
bind-address: "localhost"
port: 8080
log-level: "info"

# -- ACCOUNTS CONFIG --
# 新規ユーザー登録を無効化 (手動でアカウント作成)
accounts-registration-open: false

# -- DATABASE CONFIG --
# データベースにはSQLiteを使用
db-type: "sqlite"
db-address: "{{ gotosocial_base_dir }}/sqlite.db"

# -- STORAGE CONFIG --
# 画像などのメディアはローカルストレージに保存
storage-backend: "local"
storage-local-base-path: "{{ gotosocial_base_dir }}/storage"

# -- WEB CONFIG --
# Webリソースのパス
web-template-base-dir: "{{ gotosocial_base_dir }}/web/template/"
web-asset-base-dir: "{{ gotosocial_base_dir }}/web/assets/"
roles/gotosocial/templates/config.yaml.j2

systemdサービスファイルのテンプレート

# roles/gotosocial/templates/gotosocial.service.j2
[Unit]
Description=GoToSocial - A federated social media server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User={{ gotosocial_user }}
Group={{ gotosocial_group }}
WorkingDirectory={{ gotosocial_base_dir }}
ExecStart={{ gotosocial_bin_path }} --config-path {{ gotosocial_config_dir }}/config.yaml server start

Restart=always
RestartSec=5s

StandardOutput=append:{{ gotosocial_log_dir }}/output.log
StandardError=append:{{ gotosocial_log_dir }}/error.log

# Security Hardening
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
ProtectHome=true
ReadWritePaths={{ gotosocial_base_dir }} {{ gotosocial_config_dir }} {{ gotosocial_log_dir }}

[Install]
WantedBy=multi-user.target
roles/gotosocial/templates/gotosocial.service.j2

Playbookの実行

# -i オプションで対象サーバーのIPアドレスやホスト名を指定
ansible-playbook -i "your_server_ip," install_gotosocial.yml
Playbookの実行

クライアントについて

GoToSocialは軽量なActivityPubサーバーなので、投稿や閲覧をするには、クライアントアプリが別途必要になります。Mastodonと互換性のある多くのクライアントが使えます。

私は、色々と試しまして、最終的にElkを使うことにしました。

Mastodonウェブクライアント Elk

私のことは、フォローして頂かなくても大丈夫です。