Pixelfedインストール手順

# おことわり

* Pixelfedは現在ベータ版であり、使用には十分な注意が必要です。
* この手順は、あくまでもローカルでの動作確認を目的としたものであり、Web公開に耐えられるか分かりません。



# Pixelfedとは？

https://pixelfed.org/

PHP Laravelベースの写真シェアWebアプリ。インスタグラムみたいな感じ？

ActivityPubに対応しており、他の実装（Mastodon、Pleroma等）と連合を組める。


# 環境

```text:uname
Linux pixelfed.local 5.6.14-300.fc32.x86_64 #1 SMP Wed May 20 20:47:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```

* Pixelfed 0.10.9
* PostgreSQL 12.2
* PHP 7.4.6
* Laravel 6.18.8

にて、画像が投稿できるところまで確認済み。
（連合を組むところまではテストしていない）


# 既知の問題点

* Horizon Dashboard上で`status`が`inactive`のままになってしまう



# 下準備

* SELinuxを無効化
* `yum update`
* ファイアウォールで`HTTP`と`HTTPS`を許可 → [このあたり参考](https://qiita.com/kumasun/items/543c62eedeb0f00e5afd#%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB%E3%81%AE%E9%96%8B%E6%94%BE)
* Webサーバ用の証明書を用意 → [このあたり参考、取得の部分だけ](https://qiita.com/kumasun/items/543c62eedeb0f00e5afd#lets-encrypt%E3%81%AB%E3%82%88%E3%82%8Bssl%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E7%99%BA%E8%A1%8C%E3%81%A8%E7%99%BB%E9%8C%B2)


# 依存性パッケージをインストール

Git、PostgreSQL、Redis、Nginx、PHP-FPM、Composer、PHP、ImageMagick

```bash
$ sudo yum install git postgresql-server redis nginx php-fpm composer php ImageMagick
```


PHPのモジュールなど

```bash
$ sudo yum install php php-redis php-bcmath php-ctype php-curl php-exif php-iconv php-intl php-json php-mbstring php-openssl php-tokenizer php-xml php-zip php-pdo php-pgsql
```

## PHPのTimezone設定、PHPのバージョン情報非通知

デフォルトでは`UTC`になっているため、`Asia/Tokyo`に変更
バージョン情報非通知はやらなくても動きますが、無駄な情報を表示したくないので消しておきます

```bash
$ vim /etc/php.ini
```

```conf:/etc/php.ini
date.timezone = Asia/Tokyo
expose_php = Off
```

## Redisの自動起動設定と起動

```bash
$ sudo systemctl enable redis
$ sudo systemctl start redis
```


# データベースを用意する（PostgreSQL）

## データベースの初期化と自動起動設定

```bash
$ sudo postgresql-setup --initdb
$ sudo systemctl enable postgresql
```


## ローカルの認証方式を`md5`(パスワード認証)に変更

ident認証は使えない

```bash
$ sudo vim /var/lib/pgsql/data/pg_hba.conf
```

```conf:pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
#host    all             all             ::1/128                 ident
host    all             all             ::1/128                 md5
```

## データベースの起動

```bash
$ sudo systemctl start postgresql
```

## データベースに `pixelfed` ユーザとデータベースを作る

```bash
$ sudo su - postgres
$ createuser pixelfed -P
新しいロールのためのパスワード:
もう一度入力してください:
$ createdb pixelfed -O pixelfed
$ exit
```

パスワードは後で使うので控えておく


# Pixelfed 本体のインストール

## Linuxに `Pixelfed` 専用ユーザをつくる

```bash
$ sudo useradd pixelfed
```

## 専用ユーザでPixelfedをインストールする

```bash
$ sudo su - pixelfed
$ cd ~ && git clone https://github.com/pixelfed/pixelfed live && cd live/
$ composer install
```	

## 設定ファイルの編集

```bash
$ cp .env.example .env
$ php artisan key:generate
$ vim .env
```

`.env`の必要な部分を編集する（とりあえず今は必要最低限のみ）

```ini:.env
APP_URL=http://(ドメイン)
APP_DOMAIN="(ドメイン)"
ADMIN_DOMAIN="(ドメイン)"
SESSION_DOMAIN="(ドメイン)"

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=pixelfed
DB_USERNAME=pixelfed
DB_PASSWORD=(PgSQLのパスワード)

OPEN_REGISTRATION=false
```


## データベースマイグレーション

実行すると、本当によいか聞いてくるので `yes` と答える。

```bash
$ php artisan migrate
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.01 seconds)

(後略)

$ 
```

全て問題なく流れればOK

なにかしらのエラーが出た場合は、読み解いて解決する。

```
Illuminate\Database\QueryException  : SQLSTATE[08006] [7] FATAL:  Ident authentication failed for user "pixelfed" (SQL: select * from information_schema.tables where table_schema = public and table_name = migrations and table_type = 'BASE TABLE')
```

たとえば上記エラーの場合は、「"pixelfed"ユーザーのIdent認証に失敗した」ということなので、PostgreSQL側の認証方式が正しいか（md5か）を確認する。
設定ファイルを触った後は、postgresサービスの再起動を忘れずに！


## キャッシュの生成

本番環境として使用する場合は、パフォーマンス向上のためキャッシュを生成しておくとよいとのこと。

```bash
$ php artisan config:cache
$ php artisan route:cache
$ php artisan view:cache
``` 


## Laravel Horizon（バックグラウンド処理用スーパバイザ）のインストール

```bash
$ php artisan horizon:install
```

### Horizon のサービス化

公式にはないが、systemd経由で動かしてみる

```bash
$ sudo vim /etc/systemd/system/horizon.service
```

```conf:/etc/systemd/system/horizon.service
[Unit]
Description=Laravel Horizon Queue Manager
After=network.target auditd.service

[Service]
User=pixelfed
WorkingDirectory=/home/pixelfed/live
ExecStart=/usr/bin/php /home/pixelfed/live/artisan horizon
Restart=always

[Install]
WantedBy=multi-user.target
```

WorkingDirectoryを合わせてあげないと、Webの管理画面から状況が確認できない。
（でも一応動きはする）

```bash
$ sudo systemctl daemon-reload
$ sudo systemctl start horizon
$ sudo systemctl status horizon
● horizon.service - Laravel Horizon Queue Manager
     Loaded: loaded (/etc/systemd/system/horizon.service; disabled; vendor preset: disabled)
     Active: active (running) since Thu 2020-05-28 09:37:50 JST; 1s ago
```

動かしてみて `Active: active (running)` となっていれば正常に動作している。
問題なさそうなら自動起動を有効にしておく。

```bash
$ sudo systemctl enable horizon
```

## スケジューラタスクのインストール

```bash
$ crontab -e
```

```text:crontab
* * * * * cd /home/pixelfed/live && /usr/bin/php artisan schedule:run >> /dev/null 2>&1
```

定期的に画像の最適化やガーベジコレクションを行う。

## 後処理

最新の都市情報を取り込み、ストレージ領域をリンクする

```bash
$ php artisan import:cities
$ php artisan storage:link
```

# PHP-FPMの設定

## Pixelfed用のUNIX Socketを準備する

```bash
# vim /etc/php-fpm.d/pixelfed.conf
```

```text:/etc/php-fpm.d/pixelfed.conf
[pixelfed]
user = pixelfed
group = pixelfed

listen = /run/php-fpm/pixelfed.sock
;　　　　　　　　　　↑ このPathは後で使うので控えておく！！
listen.owner = pixelfed
listen.group = pixelfed
listen.mode = 0660

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 50
access.log = /var/log/php-fpm/$pool.access.log
slowlog    = /var/log/php-fpm/$pool.slow.log
php_admin_value[error_log] = /var/log/php-fpm/$pool.error.log
php_admin_flag[log_errors] = on

php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache
```

## サービスファイルを調整する

```bash
$ sudo vim /usr/lib/systemd/system/php-fpm.service
```

`PrivateTmp=true` という文言があれば、コメントアウトし無効にする

```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart php-fpm

$ sudo ls -l /run/php-fpm/
total 4
-rw-r--r-- 1 root     root     5 May 28 16:21 php-fpm.pid
srw-rw---- 1 pixelfed pixelfed 0 May 28 16:21 pixelfed.sock
```

`pixelfed.sock` が存在していればOK



# Nginxの設定

## 初期設定



## Pixelfedの設定

```bash
$ sudo vim /etc/nginx/conf.d/pixelfed.conf
```

```nginx:pixelfed.conf
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name photos.example.jp;                 # change this to your fqdn
    root /home/pixelfed/live/public;               # path to repo/public

    ssl_certificate /etc/letsencrypt/live/photos.example.jp/cert.pem;          # generate your own
    ssl_certificate_key /etc/letsencrypt/live/photos.example.jp/privkey.pem;   # or use letsencrypt

    ssl_protocols TLSv1.2;
    ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20:EECDH+AES;
    ssl_prefer_server_ciphers on;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    client_max_body_size 100m;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php-fpm/pixelfed.sock;
#                                 ↑ 控えたUNIXソケットのパスを記入する
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # or $request_filename
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

server {                                           # Redirect http to https
    server_name photos.example.jp;                 # change this to your fqdn
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
}
~                                                                                          
```




# ユーザの作成

対話型プロンプトで作成ができる

```bash
$ php artisan user:create
```



# こんなときは

## Horizonがエラーになって開けない

`php artisan horizon:assets` を実行してみてください


## `.env`ファイルを書き換えたのに設定が変わらない

`php artisan config:clear`


## アバターや画像のアップロードができない

* Nginx設定で、ファイルのアップロード容量を大きくしてみてください
* [ストレージのリンクを行ってみてください](https://qiita.com/kumasun/items/acdab6211fe9e24308f1#%E5%BE%8C%E5%87%A6%E7%90%86)





# TODO

* 公開に耐えうる設定を見つける
* 管理コマンド一覧を用意する