GNU socialをHerokuにたててみた

![](https://raw.githubusercontent.com/mba-hack/images/master/gnu-social-01.png)


## 追記:2019.03.25

前に立てたことあったけど、今度も例に漏れず、ハマりまくった。

Qiitaに書いた自分の記事を参考にしながら進めるものの、内容は正しかったけど、ハマりポイントを把握してなかった。

前提として、以下の順番じゃないと、正常に動かすことはできない。


```sh
$ git clone https://git.gnu.io/dansup/gnu-social
$ cd !$:t
$ git checkout composer-autoloading

$ php -v
7.3

$ vim composer.json
{
  "require": {
    "ext-pgsql": "*",
    "ext-gd": "*",
    "ext-intl": "*",
    "php": "^7.3.0",
    "illuminate/contracts": "*",
    "illuminate/support": "*",
    "ramsey/uuid": "^3.0",
    "ezyang/htmlpurifier": "^4.10",
    "psy/psysh": "^0.8.17"
  }

$ composer update

$ heroku create $APP_NAME
$ heroku buildpacks:add https://github.com/heroku/heroku-buildpack-php -a $APP_NAME
$ heroku addons:add cleardb:ignite -a $APP_NAME
$ heroku config -a $APP_NAME

$ vim Profile
web: vendor/bin/heroku-php-apache2

$ heroku git:remote -a $APP_NAME
$ git add .
$ git commit -m "first"
$ git push heroku master

# 次に、dockerを使って、DBにアクセスする。ついでに、そこで作成されたconfig.phpを取得する、config.phpの位置情報を適切に保存するため、これはdockerから実行するのが望ましい
$ open -a Docker
$ sudo docker run -p 8000:80 rudism/gnu-social /root/start
$ open -a Google\ Chrome http://localhost:8000/install.php

# ブラウザでの/install.phpの設定は、以下の値を参考に設定する
# `/install.php`をhttpで実行する必要がある。
# DBなどの情報をheroku addonsのcleardbに入れる
# example : mysql://A:B@example.com/C
# optionである?,=,trueとかの末尾の部分はいらない
# 	host : example.com
# 	DB name : C
# 	user : A
# 	password : B
# $config['site']['path'] = false; 
# $config['site']['ssl'] = 'never'; 
# $config['site']['fancy'] = false;

# 初期設定が完了したらlocalhost:8000で一度、/index.php/well-known/host-metaを確認して、投稿し、/index.php/well-known/webfinger?resourece=acct:user@localhost:8000を確認しておくといいかも

# config.phpを取得する
$ sudo docker cp `sudo docker ps -q`:/var/www/gnu-social/config.php .

# config.phpを編集する
$ vim config.php
- $config['site']['server'] = 'localhost:8000';
+ $config['site']['server'] = 'APP_NAME.herokuapp.cf';
# ついでにこちらの設定を追加しても良い、好みによる
+ $config['site']['path'] = false; 
+ $config['site']['ssl'] = 'never'; 
+ $config['site']['fancy'] = false;

# config.phpをherokuにdeployする
# .gitignoreに注意してください
$ git add config.php
$ git commit -m "add config"
$ git push heroku master

# DBをdump、編集して、restoreする。なぜなら、このままではprofile domain(url)がlocalhostになっているため、本来のdomainにしたあと、restoreする必要があるから。webfingerで使われるaliasとかもDBに保存されたこの値から取得するため、localhostになってしまうおそれがある
# 一応、heroku-mysql dashboardでもbackupを作成してdlしておく
$ mysql --host=$HOST --user=$USER_NAME --password=$PASSWORD $DB_NAME
mysql > select * from user;
$ mysqldump --host=$HOST $DB_NAME --user=$USER_NAME --password=$PASSWORD >! dump.sql
$ vim dump.sql # localhost -> example.com
$ mysql --host=$HOST --user=$USER_NAME --password=$PASSWORD $DB_NAME < dump.sql

# apache_conf.appでも何でもいいので、それらを使って./well-knownあたりの設定を行う、heroku webでは権限上アクセスできなかったりした
# ./well-known/以下はwebfingerにとって重要で、これがインスタンス間のやり取りを行う上で必要な情報になる
$ vim .htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.php/$1 [L,QSA]
</IfModule>
<FilesMatch "\.(ini)">
        Require all denied
</FilesMatch>
<FilesMatch ".well-known/*">
    Require all granted
</FilesMatch>
```


では、なぜ、Dockerを使って/install.phpを実行したあと、config.phpを取得する必要があるのでしょう。

一つは、config.phpの内容です。これは、lib/installer.phpを見れば大体の推測が可能です。しかし、二つ目の理由が重要で、config.phpの保存場所の指定にあります。/install.phpを実行後、config.phpが書き込まれますが、保存場所はDBに送られます。これは、実行したサーバーの状況に応じてのことですが、herokuの場合は、/app以下でしょうか。しかし、herokuの場合、web serverに保存されたファイルはリセットされてしまいます。したがって、まずはconfig.phpの位置情報をDB内に指定させたあとに、その/config.phpをpushしなければなりません。

また、dockerからの/install.phpでないと、./well-known(webfinger)が動作しないことを確認しました。これが動作しないと、mastodonとのやり取りができません。

```sh
# URLはindex.phpが必要かも -> /index.php/.well-known/xxx
# curl https://gnu-social.herokuapp.com/index.php/.well-known/webfinger?resource=acct:syui@gnu-social.herokuapp.com"
$ curl https://gnu-social.herokuapp.com/.well-known/host-meta
$ curl "https://gnu-social.herokuapp.com/.well-known/webfinger?resource=acct:syui@gnu-social.herokuapp.com"
```

もし失敗した場合は、DBを消してから、再度、作り直します。

```sh
$ heroku addons:remove cleardb -a $APP_NAME --confirm $APP_NAME
$ heroku addons:add cleardb:ignite -a $APP_NAME
$ heroku config -a $APP_NAME
```


## その他の情報

### config.php

herokuのmysqlが調子が悪いので、よくアクセスできなくなる。DBの問題であって、gnu-socialの問題ではない。

/install.phpを実行したあとなら、以下の設定も有効にできます。

> config.php

```sh
//$config['site']['ssl'] = 'never'; 
$config['site']['ssl'] = 'always';
$config['site']['sslproxy'] = true; 
$config['site']['fancy'] = true;
```


### /.well-known = 403

使用したRepositoryには、`socialfy-another-domain`があり、設定ファイルがおいてあります。mastodonとかでもお馴染みのあれですが、gnu-socialにもおいておきましょう。

https://git.gnu.io/dansup/gnu-social/blob/composer-autoloading/socialfy-another-domain/README.txt

しかし、heroku + nginxでは、/.well-known以下が403になります。

これは、heroku nginx_app.confの設定でアクセスできます。

```php
location ^~ /.well-known/ {
    allow all;
}
```

https://github.com/heroku/heroku-buildpack-php/issues/218

自分の場合は、以下のような感じ。 (nginxでrewriteを設定してない場合)

```sh
$ curl -H "Accept: application/xrd+xml" "https://gnu-social.herokuapp.com/.well-known/webfinger/index.php?resource=acct:syui@gnu-social.herokuapp.com"

# この設定でindex.phpを除けます
$ vim nginx_app.conf
location ^~ /.well-known/webfinger {
    rewrite ^(.*)$ /.well-known/webfinger/index.php$1 last;
    try_files @heroku-fcgi @heroku-fcgi;
    allow all;
}

# host-meta : "https://gnu-social.herokuapp.com/.well-known/webfinger?resource={uri}"

$ curl -H "Accept: application/xrd+xml" "https://gnu-social.herokuapp.com/.well-known/webfinger?resource=acct:syui@gnu-social.herokuapp.com"
```

### pleroma-fe

Download : https://git.pleroma.social/pleroma/pleroma-fe/pipelines

Downloadして、dist/index.htmlをdist/pleroma.htmlにrenameしたあとにrootに置く。そして、/pleroma.htmlからアクセスする

### qvitter

```sh
$ cd plugin/
$ git clone https://git.gnu.io/h2p/Qvitter
$ cd !$:t
$ rm -rf .git
$ vim config.php
addPlugin('Qvitter');
$ php scripts/checkschema.php
```

### activtypub

```sh
$ cd plugin/
$ git clone https://git.gnu.io/dansup/ActivityPub
$ cd !$:t
$ git checkout dev
$ composer up
$ rm -rf .git
$ vim config.php
addPlugin('ActivityPub');
$ php scripts/checkschema.php
```

### plugin

> config.php 

おそらくデフォルトで有効になっているが、一応

```sh
addPlugin('OStatus');
addPlugin('WebFinger');
addPlugin('LRDD');

addPlugin('Activity');
addPlugin('ActivitySpam');
addPlugin('ActivityVerb');
addPlugin('ActivityVerbPost');
addPlugin('ActivityModeration');
```

### attachments

`admin -> paths -> attachments -> path,dir`を空にして保存すると、web UIがうまく動作しなくなる。

```sh
$ php scripts/checkschema.php
```

> PHP Warning:  mkdir(): Permission denied, Could not create directory for 'thumbnail': '/thumb'

`gnu-social/lib/gnusocial.php`の`/thumb`を`/app/static`とかにして、`php scripts/checkschema.php`を実行。


`config.php`に`$config['thumbnail']['dir'] = "/app/static";`を追加することで治った。

しかし、DBに保存された値によって、以降も`php scripts/checkschema.php`が失敗してしまう。

> lib/gnusocial.php

```sh
- if (!mkdir($dir)) {
-                throw new ConfigException('Could not create directory for '._ve($description).': '._ve($dir));
-            }
-            if (!chmod($dir, 0775)) {
-                common_log(LOG_WARNING, 'Could not chmod 0775 on directory for '._ve($description).': '._ve($dir));
-            }
```

herokuは、mkdirでディレクトリを作れない、作ったとしてもリセットされて消えてしまう。

https://github.com/foocorp/gnu-social/blob/master/INSTALL


### mysql

herokuのmysqlにアクセス。

```sh
$ mysql --host=$HOST --user=$USER_NAME --password=$PASSWORD --reconnect $DB_NAME
```


### webfinger:user.json

通常、webfingerが出力するのは、xmlじゃなくjsonっぽい気がしているので、jsonにしたあとに、webfinger/index.phpを編集する。

user fileをjsonにして使うと、mastodonではnokogiriがerrorを吐く。

> Nokogiri::XML::XPath::SyntaxError: ERROR: Undefined namespace prefix: //xmlns:Subject

```php
$f = $u . ".xml";
//$f = $u . ".json";

if (file_exists($f)) {
  header('Content-Disposition: attachment; filename="'.urlencode($f).'"');
  header('Content-type: application/xrd+xml');
  //header('Content-type: application/json');
  echo file_get_contents($f);
}
```

```json
{
  "subject": "acct:syui@gnu-social.herokuapp.com",
  "aliases": [
    "https://gnu-social.herokuapp.com/syui",
    "https://gnu-social.herokuapp.com/user/2",
    "https://gnu-social.herokuapp.com/index.php/user/2",
    "https://gnu-social.herokuapp.com/index.php/syui"
  ],
  "links": [
    {
      "rel": "http://webfinger.net/rel/profile-page",
      "type": "text/html",
      "href": "https://gnu-social.herokuapp.com/syui"
    },
    {
      "rel": "http://gmpg.org/xfn/11",
      "type": "text/html",
      "href": "https://gnu-social.herokuapp.com/syui"
    },
    {
      "rel": "describedby",
      "type": "application/rdf+xml",
      "href": "https://gnu-social.herokuapp.com/syui/foaf"
    },
    {
      "rel": "http://apinamespace.org/atom",
      "type": "application/atomsvc+xml",
      "href": "https://gnu-social.herokuapp.com/api/statusnet/app/service/syui.xml"
    },
    {
      "rel": "http://schemas.google.com/g/2010#updates-from",
      "type": "application/atom+xml",
      "href": "https://gnu-social.herokuapp.com/api/statuses/user_timeline/2.atom"
    },
    {
      "rel": "salmon",
      "href": "https://gnu-social.herokuapp.com/main/salmon/user/2"
    },
    {
      "rel": "http://salmon-protocol.org/ns/salmon-replies",
      "href": "https://gnu-social.herokuapp.com/main/salmon/user/2"
    },
    {
      "rel": "http://salmon-protocol.org/ns/salmon-mention",
      "href": "https://gnu-social.herokuapp.com/main/salmon/user/2"
    },
    {
      "rel": "http://ostatus.org/schema/1.0/subscribe",
      "template": "https://gnu-social.herokuapp.com/main/ostatussub?profile={uri}"
    },
    {
      "rel": "http://specs.openid.net/auth/2.0/provider",
      "href": "https://gnu-social.herokuapp.com/syui"
    }
  ]
}
```


### webfinger : acct:user@social.example.com

他のgnu-socialインスタンスを見ていると、どうやらwebfingerは、以下のような形でjsonを生成しているらしい。

> ./well-known/host-meta

```json
{
  "links": [
    {
      "rel": "lrdd",
      "type": "application/jrd+json",
      "template": "https://social.example.com/.well-known/webfinger?resource={uri}"
    },
    {
      "rel": "lrdd",
      "type": "application/json",
      "template": "https://social.example.com/.well-known/webfinger?resource={uri}"
    },
    {
      "rel": "lrdd",
      "type": "application/xrd+xml",
      "template": "https://social.example.com/.well-known/webfinger?resource={uri}"
    },
    {
      "rel": "http://apinamespace.org/oauth/access_token",
      "href": "https://social.example.com/api/oauth/access_token"
    },
    {
      "rel": "http://apinamespace.org/oauth/request_token",
      "href": "https://social.example.com/api/oauth/request_token"
    },
    {
      "rel": "http://apinamespace.org/oauth/authorize",
      "href": "https://social.example.com/api/oauth/authorize"
    }
  ]
}
```

> /.well-known/webfinger?resource={uri}

ここで気になるのが、public-keyで、おそらくDBにはsecret-keyが保存されていて、これが個人認証に使われているのだと思われる。heroku上で実行するwebfingerは動いていない気がするので、この処理を行うのは難しい。どうすればこの問題を回避できるのかわからない。dockerからwebfingerによって作成される`./well-known`を持ってくるといいかもしれない。

```json
    {
      "rel": "magic-public-key",
      "href": "data:application/magic-public-key,${magic-public-key}"
    },
    {
      "rel": "diaspora-public-key",
      "type": "RSA",
      "href": "${diaspora-public-key}"
    }
```

pleromaからメンションを送ってみたが、一応、gnu-socialのほうに通知が来た。しかし、gnu-social側から送っても、pleroma側には通知が来ず、メンションが飛ばされていないのかもしれない。

mastodonは、両方のやり取りが不可能だった。通知が来ない。しかも、インスタンスのリンクが作成されていないところを見ると、./well-knownでも他のところを見ているか、pleromaとは処理が違うんだろうと思われる。

### webfingerがうまく動作した手順

webfingerがうまく動作する手順が判明しました。

1 dockerから/install.phpを実行する、DBに送った情報をもとに、dockerにあるconfig.phpをherokuにpushする

2 config.phpを書き換え、pushする

3 うまく動作するのを確認したあと、DBをdumpする

```sh
$ mysqldump --host=$HOST $DB_NAME --user=$USER_NAME --password=$PASSWORD >! dump.sql
```



4 dockerのprofile domainがlocalhostになっているので、本来のdomainに修正したあと、mysqlのdumpを書き換え、restoreする

```sh
# tableを確認
$ mysql --host=$HOST --user=$USER_NAME --password=$PASSWORD $DB_NAME
mysql > select * from user;

$ vim dump.sql
# 修正
```

```sh
# restore
$ mysql --host=$HOST --user=$USER_NAME --password=$PASSWORD $DB_NAME < dump.sql
```

一応、heroku-mysql dashboardでもbackupを作成してdlしておく

5 apache2で以下の設定を行う

```sh
$ vim Profile
web: vendor/bin/heroku-php-apache2

$ vim .htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  #RewriteBase /mublog/
  #RewriteCond %{HTTP:Authorization} ^(.*)
  #RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  #RewriteRule (.*) index.php?p=$1 [L,QSA]
  RewriteRule (.*) index.php/$1 [L,QSA]

</IfModule>
<FilesMatch "\.(ini)">
    <IfVersion < 2.3>
        Order allow,deny
        Deny from all
    </IfVersion>
    <IfVersion >= 2.3>
        Require all denied
    </IfVersion>
</FilesMatch>
<FilesMatch ".well-known/*">
    Require all granted
</FilesMatch>
```

ここまででmastodon, pleroma, gnu-social間でやり取りできるようになった。

少しだけ心残りは、.htaccessでindex.php/.well-known/webfingerを短縮できなかったこと。apacheのrewireteの設定は難しい、特にリクエストがある場合は。

fancyをtrueにしてる関係で、host-metaはindex.phpは短縮されてるんだけど、実際のURLは`/.well-known/webfinger`じゃなく`index.php/.well-known/webfinger`

### ostatus

ostatusについて調べてみたら、かなりやばい。リンク切れ多数で更新されていない感じ。資料も探すのに苦労する感じでした。


`PubSubHubbub の機能不足を補うために、Atom の拡張（Activity Streams, Portable Contacts, Salmon）を使う`

> フィードが表す social activity を表現するために、Activity Streams を使う（例えば、フォローのときは "follow" verb を使う） プロフィール情報を提供するために Portable Contacts を使う リプライを送るために Salmon を使う


https://muziyoshiz.hatenablog.com/entry/2017/04/30/143632

### nginx

nginxで404が出る場合は、以下。

```sh
$ vim nginx_app.conf location / {
    try_files $uri @rewriteapp;
}
location @rewriteapp {
    rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/(app|app_dev|config)\.php(/|$) {
    try_files @heroku-fcgi @heroku-fcgi;
    internal;
} 

$ vim Procfile
web: vendor/bin/heroku-php-nginx -C nginx_app.conf
```

追記、終わり。

ここからは過去の投稿です。情報が古いですが、何かの参考になるかもしれないので、残しておきます。

## gnu-social for composer

composerが用意されているsrcを探しました。

よって、今回は、そちらのほうのsrcを使って、herokuにdeployしていくことにします。

```sh
$ git clone https://git.gnu.io/dansup/gnu-social
$ cd !$:t
$ git checkout composer-autoloading

# phpはlocalで7.2だったので、このversionでやってくことにします
$ php -v
7.2

$ composer update
error

# 追記 : "php": "~7.2.0",でないとダメなことを確認、Heroku Deployの際に、7.3が使用されてしまうため
$ vim composer.json
{
  "require": {
    "ext-pgsql": "*",
    "ext-gd": "*",
    "ext-intl": "*",
    "php": "~7.2.0",
    "illuminate/contracts": "*",
    "illuminate/support": "*",
    "ramsey/uuid": "^3.0",
    "ezyang/htmlpurifier": "^4.10",
    "psy/psysh": "^0.8.17"
  },
    "scripts": {
      "post-install-cmd": [
      	"chmod 644 config.php"
      ],
      "post-update-cmd": [
      	"chmod 644 config.php"
      ]
    }
}

# 最初にHeroku Deployする場合は、scriptsなしでいく。この場合、config.phpも除く。そして、/instapp.phpにブラウザでアクセスし、DBに値を書き込んだあとに、当該ファイルとcomposer.jsonをupして、pushする

$ composer update
ok
```

```json:composer.json
{
  "require": {
    "ext-pgsql": "*",
    "ext-gd": "*",
    "ext-intl": "*",
    "php": "^7.2.0",
    "illuminate/contracts": "*",
    "illuminate/support": "*",
    "ramsey/uuid": "^3.0",
    "ezyang/htmlpurifier": "^4.10",
    "psy/psysh": "^0.8.17"
  },
    "scripts": {
      "post-install-cmd": [
      	"chmod 644 config.php"
      ],
      "post-update-cmd": [
      	"chmod 644 config.php"
      ]
    }
}
```

> 追記 : composer.jsonは、"php": "~7.2.0",でないとダメなことを確認、Heroku Deployの際に、7.3が使用されてしまうため

## deploy gnu-social on heroku

`ｄｂ：mysql`を選択して、`config.php`を書いていきます。

`config.php`の内容はこんな感じです。

```sh:config.php
$config['site']['name'] = 'gnu-social';

$config['site']['server'] = '$APP_NAME.herokuapp.com';
$config['site']['domain'] = '$APP_NAME.herokuapp.com';

$config['site']['path'] = false; 

$config['site']['ssl'] = 'never'; 
//$config['site']['ssl'] = 'always'; 
//$config['site']['sslproxy'] = 'true'; 

$config['db']['database'] = 'mysql://${DB_USERNAME}:${DB_PASSWORD}@{DB_HOST}/${DB_DATABASE}';
$config['db']['type'] = 'mysql';
```

```sh
$ heroku create $APP_NAME

$ heroku buildpacks:add https://github.com/heroku/heroku-buildpack-php -a $APP_NAME
$ heroku addons:add cleardb:ignite -a  $APP_NAME

# databaseのoptionである?,=,trueとかの部分はいらない
$ heroku config -a $APP_NAME
mysql://username:password@hostname/database

# hostがgit.gnu.ioであることもあって、一応、削除した、(しなくていいかもしれない)
$ rm -rf .git
$ git init
$ heroku git:remote -a $APP_NAME 
$ git add .
$ git commit -m "first"
$ git push heroku master
deploy ok

$ heroku ps:scale web=1 -a $APP_NAME
$ open -a Google\ Chrome $APP_NAME.herokuapp.com/install.php
```

`/install.php`にアクセスしたら必要な情報を入力し、それがdbに記録されますので、管理者権限でloginできるようになります。

install.phpにアクセスする前は、composer.jsonとconfig.phpに注意してください、Heroku Deployするものが違います。具体的には、config.phpを除いたものでDeployしたあと、install.phpを実行し、ブラウザから入力後に、DBに保存されるので、その後、config.phpを含めた一式をHeroku Deployします。

```sh:example
$ vim composer.json
{
  "require": {
    "ext-pgsql": "*",
    "ext-gd": "*",
    "ext-intl": "*",
    "php": "^7.2.0",
    "illuminate/contracts": "*",
    "illuminate/support": "*",
    "ramsey/uuid": "^3.0",
    "ezyang/htmlpurifier": "^4.10",
    "psy/psysh": "^0.8.17"
  }
$ composer update
＃ config.phpを退避させる
$ mv config.php ../
$ git add .
$ git commit -m "first"
$ git push heroku master

$ open -a "Google Chrome" $APP_NAME.herokuapp.com/install.php
# config.phpと同じ情報を入力する

$ vim composer.json
{
  "require": {
    "ext-pgsql": "*",
    "ext-gd": "*",
    "ext-intl": "*",
    "php": "^7.2.0",
    "illuminate/contracts": "*",
    "illuminate/support": "*",
    "ramsey/uuid": "^3.0",
    "ezyang/htmlpurifier": "^4.10",
    "psy/psysh": "^0.8.17"
  },
    "scripts": {
      "post-install-cmd": [
      	"chmod 644 config.php"
      ],
      "post-update-cmd": [
      	"chmod 644 config.php"
      ]
    }
}
$ composer update
# 退避していたconfig.phpを戻す
$ cp -rf ../config.php .
$ vim .gitignore
- config.php
$ git add .
$ git commit -m "first"
$ git push heroku master
```

DB情報を入力する際は、`${DB_USERNAME}:${DB_PASSWORD}@{DB_HOST}/${DB_DATABASE}`を参考にしてください。

```
example : mysql://A:B@example.com/C

HOST : example.com
DB name : C
user : A
password : B
```

現時点での設定では、Heroku Free上、

```
$config['site']['fancy'] = false;
$config['site']['ssl'] = 'never'; 
```

しか通りませんでした。/install.phpでDBに設定する際、この設定に沿うようにしてください。正直、このあたりはよくわかりませんが、安定してやり取りするには上記の設定がベストと思われます。

一旦、この状態でやり取りができるか見てみてください。

heroku + cloudflare (cname)ではssl:trueとかqvitterとかを含めて、やり取りができない問題が発生するかもしれません。

#### 補足

ここからは別に読まなくていいんですが、heroku deployする際にちょっと難しかった部分の解説です。

gnu-socialの仕組みは単純で、基本的にinstall.phpがconfig.phpを書き込む処理を行います。ただし、deploy後は、heroku resetの関係でそこで作ったconfig.phpは、一時的にしか有効ではありません。もちろん、DBに保存されるユーザー情報は別ですが。

ということで、srcにconfig.phpを用意して、deployする必要があるわけなんですけど(.gitignoreに注意)、config.phpの内容がわからないんですよね。そもそもheroku run bash -a $APP_NAMEしてもconfig.phpが見つからないし、権限を考慮してもやっぱり見当たらないので、herokuの仕組み的なものなんだと思いますが、私の場合は、dockerでpreviewして、そのときに作成したconfig.phpをdocker cpして持ってくることを考えました。

install.phpのINSTALLDIRで設定されているはずなんですが、lib/installer.phpのchmod 644を書き直したり、INSTALLDIRを/appにしたりしたのですが、heroku runでは見つけられなかった。

ということで、dockerを使って簡潔に行きましょー。こんな感じで持ってきます。一応、CONFIGUREを読んでもいいんですけど、これ読んでやってるほうが時間かかると思う。

```sh
$ sudo docker run -p 8000:80 rudism/gnu-social /root/start
$ open -a Google\ Chrome http://localhost:8000/install.php

$ sudo docker ps -q

$ sudo docker cp xxx:/var/www/gnu-social/config.php .
or
$ sudo docker exec xxx /bin/bash
	cat /var/www/gnu-social/config.php
$ sudo docker cp xxx:/var/www/gnu-social/config.php .
or
$ sudo docker commit xxx rudism/gnu-social
$ sudo docker run -it rudism/gnu-social /bin/bash
	cat /var/www/gnu-social/config.php
$ sudo docker ps -q
$ sudo docker cp xxx:/var/www/gnu-social/config.php .
```

上記コマンドを見れば、やりたいことはだいたい分かると思います。いろいろな方法があります。この他にも色々ありますね。

しかし、要点は、heroku dbの情報を入力して作成されたconfig.phpを持ってくることが重要だと思います。下記はexampleです。

```php:config.php
<?php
if (!defined('GNUSOCIAL')) { exit(1); }
$config['site']['name'] = 'gnu-social';
$config['site']['server'] = '$APP_NAME.herokuapp.com';
$config['site']['path'] = false; 

$config['db']['database'] = 'mysql://${DB_USERNAME}:${DB_PASSWORD}@{DB_HOST}/${DB_DATABASE}';
$config['db']['type'] = 'mysql';
// Uncomment below for better performance. Just remember you must run
// php scripts/checkschema.php whenever your enabled plugins change!
//$config['db']['schemacheck'] = 'script';
```

gnu-socialをdocker等で試行錯誤した結果、sslとpgsqlはどうやっても機能しませんでした。特に、pgsqlはバグってると思います。lib/installer.phpみたいなファイルから書き直したんですが、docker上でもheroku上でもまともに動きませんでした。正直、よくわからない。

https://suriyadeepan.gitbooks.io/mesh-guide/content/gnu_social.html

あと、config.phpを置いたのはいいんですが、本来は、644でchmodされるファイルですから、そのパーミッションで行きたいんですけど、なぜか`$ heroku run bash, ls -l config.php`で確かめてみると、意図した権限じゃないんですよね。危険ですよ。composerでscript実行してるはずなんですけどね。(これはherokuの問題だと思う)



## gnu-social plugins : qvitter + pleroma-fe

gnu-socialのよいところは、拡張性があるところと、その拡張がわかりやすいところですね。これでこそ古き良きソフトウェアという感じです。

基本的には、`plugins/`に`git clone`して、`rm -rf 　plugins/$REPO/.git`して、config.phpで有効にするという感じで設定できます。

[qvitter](https://github.com/hannesmannerheim/qvitter)というのは、UIを変更するpluginです。導入してみました。また、[pleroma-fe](https://git.pleroma.social/pleroma/pleroma-fe)も同じようなものなので、導入。

参考 : https://git.pleroma.social/pleroma/pleroma-fe/wikis/dual-boot-with-qvitter

```php:config.php
$config['site']['ssl'] = 'always'; 
$config['site']['sslproxy'] = 'true'; 
$config['site']['fancy'] = true;

addPlugin('Qvitter');
$config['site']['qvitter']['enabledbydefault'] = true;
$config['site']['qvitter']['defaultbackgroundcolor'] = '#f4f4f4';
$config['site']['qvitter']['defaultlinkcolor'] = '#0084B4';
$config['site']['qvitter']['timebetweenpolling'] = 5000;
$config['site']['qvitter']['urlshortenersignature'] = 'b6afeec983';
$config['site']['qvitter']['sitebackground'] = 'img/vagnsmossen.jpg';
$config['site']['qvitter']['favicon_path'] = Plugin::staticPath('Qvitter', '').'img/gnusocial-favicons/';
$config['site']['qvitter']['sprite'] = Plugin::staticPath('Qvitter', '').'img/sprite.png?v=40';
$config['site']['qvitter']['enablewelcometext'] = true;
$config['site']['qvitter']['blocked_ips'] = array();
$config['thumbnail']['maxsize'] = 3000; // recommended setting to get more high-res image previews
$config['profile']['delete'] = true; // twitter users are used to being able to remove their accounts
$config['profile']['changenick'] = true; // twitter users are used to being able to change their nicknames
$config['public']['localonly'] = true; // only local users in the public timeline (qvitter always has a timeline for the whole known network)
```

ちょっとハマったところとかを解説。

qvitterは、urlに/index.phpを付けずにapiを呼び出すため、`fancy urls`をenableにしていない場合、url間違いでapiを呼び出せない。そのためエラーを出すのだけど、herokuなどのPaaSは、nginxなどを直接操作できないため、なかなか面倒でした。

具体的には、nginx_app.confを作って、Procfileのオプションで指定してやればOKでした。

```php:nginx_app.conf
location @rewriteapp {
    # rewrite all to index.php
    rewrite ^(.*)$ /index.php/$1 last;
}
```

```sh:Procfile
web: vendor/bin/heroku-php-nginx -C nginx_app.conf 
```

メモ

```
fancy urls = index.php 
ex : /index.php/api/user -> /api/user 
https://github.com/hannesmannerheim/qvitter/issues/256

> nginx_app.conf
location @rewriteapp {
# rewrite all to index.php
rewrite ^(.*)$ /index.php/$1 last;
} 

> Procfile 
-C nginx_app.conf 
```

https://devcenter.heroku.com/articles/custom-php-settings

あと、ちょっと変な現象に遭遇して、config.phpのsite nameにqvitterを入れてると、plugins/Qvitterを呼び出せなかった気がする。多分、plugins/Qvitterのcodeか何かバッティングしたのかも。なので、サイト名変えました。

#### その他の問題

cnameを設定したんですが、`nginx_app.conf`がうまく書けていないのか、user-profileのurlがherokuapp.comのものになってしまってます。

良い解決策あったらコメントにて是非教えてください!