1
0
hugo/content/blog/2023-08-11-flyio.md
2024-04-23 22:21:26 +09:00

368 lines
8.5 KiB
Markdown

+++
date = "2023-08-11"
tags = ["flyio"]
title = "fly.ioから自鯖に移行した"
slug = "flyio"
+++
去年の8月までは`$0`で運用できてたんだけど、そこから約1年、月に`$30~40`くらいでした。`$30`は確実に超えてる感じなので、`$40`のほうが実態に近いかな。
つまり、この1年で`$360~480`くらいかかってる。
移行も面倒なのでしばらく放置してたんだけど、fly.ioでhostingしているmastodonが思うように動かなくなってきており、具体的には、激重になってた。
これはmastodonを動かすのに使っていた`redis`の裏技が封印された事によるものだと思う。
年に`$360~480`かけて激重のmastodonを運用するのは割に合わないと思ったので、移行を決意。fly.ioにhostしてたほぼすべてのサーバーを自前運用に切り替えました。
目標としては、また`$0`を目指す感じになりそう。
## postgres backup & restore
fly.ioのpostgresのbackupとdockerへのrestoreの手順です。
```sh:pg.dump
$ brew install libpq
$ echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ flyctl proxy 5432 -a $pg_app_name
# postgres://${username}:${password}@${host}:5432/${db_name}
$ pg_dump -h localhost -p 5432 -U $username $db_name >! pg.dump
```
```sh:pg.restore
$ sudo docker compose up db
$ su
$ cat pg.dump | docker compose exec -T db psql -U $username -p 5432
```
これは、docker-composeの構成によります。例えば、下記の場合は、こうなります。
```sh:pg.restore
$ sudo docker compose up mitra_postgres
$ su
$ cat pg.dump | docker compose exec -T mitra_postgres psql -U postgres -p 5433
```
```yml:compose.yml
version: '3.9'
services:
mitra:
container_name: mitra
build: .
network_mode: host
restart: unless-stopped
volumes:
- type: bind
source: ./files
target: /app/files
env_file:
- .env.local
mitra_postgres:
image: postgres:latest
container_name: mitra_postgres
ports:
- 5433:5433
volumes:
- mitra_db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=$password
volumes:
mitra_db:
```
## fly.io volume backup
```sh
$ fly ssh sftp shell r
$ get /path/to/dir ./
$ aunpack dir.zip
```
これを解凍してdockerのvolumeに設定するといいでしょう。
## docker compose volume
docker composeのvolumemについても解説します。
```yml:compose.yml
volumes:
- mitra_db:/var/lib/postgresql/data
volumes:
mitra_db:
```
これは、`/var/lib/docker/volumes`になります。
```sh
$ sudo ls /var/lib/docker/volumes
```
これをrepoに置きたい場合はこのようにします。
```yml:compose.yml
volumes:
- ./mitra_db:/var/lib/postgresql/data
```
これで`./mitra_db`に保存されます。
## docker volume owner
```yml:compose.yml
build:
context: .
args:
- UID
- GID
- USERNAME=user
- GROUPNAME=user
```
```sh:docker.file
ARG UID
ARG GID
ARG USERNAME
ARG GROUPNAME
RUN groupadd -g ${GID} ${GROUPNAME} -f && \
useradd -m -s /bin/bash -u ${UID} -g ${GID} ${USERNAME}
```
```sh
$ sudo docker compose build --build-arg UID="$(id -u)" --build-arg GID="$(id -g)"
```
## systemd
```sh:/etc/systemd/system/mitra.service
[Unit]
Description=mitra service
Documentation=https://codeberg.org/silverpill/mitra
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/syui/flyio/mitra
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
[Install]
WantedBy=default.target
```
```sh
$ sudo systemctl daemon-reload
$ sudo systemctl start mitra
$ sudo systemctl enable mitra
```
## mastodon
mastodonは`127.0.0.1`を`0.0.0.0`にしないとlocalhostにアクセスできなかった。また、`service_name`と`pg_port`は他のコンテナとかぶるので変更。
https://github.com/mastodon/mastodon/blob/main/docker-compose.yml
```sh
DB_HOST=ms_db
DB_PORT=5434
REDIS_HOST=ms_redis
```
```yml:compose.yml
version: '3'
services:
ms_db:
restart: always
image: postgres:14-alpine
shm_size: 256mb
ports:
- 5434:5434
networks:
- internal_network
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
volumes:
- ./postgres14:/var/lib/postgresql/data
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_PASSWORD=$password
- PGPORT=5434
ms_redis:
restart: always
image: redis:7-alpine
networks:
- internal_network
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
volumes:
- ./redis:/data
mastodon:
build: .
image: ghcr.io/mastodon/mastodon:edge
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_network
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
ports:
- '0.0.0.0:3000:3000'
depends_on:
- ms_db
- ms_redis
# - es
volumes:
- ./public/system:/mastodon/public/system
streaming:
build: .
image: ghcr.io/mastodon/mastodon:edge
restart: always
env_file: .env.production
command: node ./streaming
networks:
- external_network
- internal_network
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
ports:
- '0.0.0.0:4000:4000'
depends_on:
- ms_db
- ms_redis
sidekiq:
build: .
image: ghcr.io/mastodon/mastodon:edge
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- ms_db
- ms_redis
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
networks:
external_network:
internal_network:
internal: true
```
## matrix
install : https://matrix-org.github.io/dendrite/installation/docker/install
docker : https://github.com/matrix-org/dendrite/blob/main/build/docker/README.md
compose.yml : https://github.com/matrix-org/dendrite/blob/main/build/docker/docker-compose.yml
`./config`をdockerで作成し、dendrite.yml, keyをvolumeにすればいいです。
```sh
mkdir -p ./config
docker run --rm --entrypoint="/bin/sh" \
-v $(pwd)/config:/mnt \
matrixdotorg/dendrite-monolith:latest \
-c "/usr/bin/generate-config \
-dir /var/dendrite/ \
-db postgres://dendrite:itsasecret@postgres/dendrite?sslmode=disable \
-server YourDomainHere > ./config/dendrite.yaml"
```
```yml:compose.yml
version: "3.4"
services:
matrix_postgres:
hostname: matrix_postgres
image: postgres:latest
restart: always
volumes:
- dendrite_postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: itsasecret
POSTGRES_USER: dendrite
POSTGRES_DATABASE: dendrite
PGPORT: 5435
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dendrite"]
interval: 5s
timeout: 5s
retries: 5
networks:
- internal
ports:
- 5435:5435
matrix:
hostname: matrix
image: matrixdotorg/dendrite-monolith:latest
ports:
- 8008:8008
- 8448:8448
volumes:
- ./config:/etc/dendrite
- ./data:/data
depends_on:
matrix_postgres:
condition: service_healthy
networks:
- internal
restart: unless-stopped
networks:
internal:
attachable: true
volumes:
dendrite_postgres_data:
```
matrixは厄介で`8448:8448`の`.well-know/matrix/server`への対応がわからなかった。これはcloudflareの設定になるんだけど、いけると思った設定ではmatrixが動かない感じだった。これはおそらく、tunnelで作られるdnsがproxy onになるためだと思う。
```toml:fly.toml
[[services]]
internal_port = 8008
protocol = "tcp"
[[services.ports]]
handlers = ["tls", "http"]
port = "443"
[[services.ports]]
handlers = ["tls", "http"]
port = "8448"
```
https://matrix-org.github.io/synapse/v1.41/delegate.html
```json:.well-known/matrix/server
{
"m.server": "synapse.example.com:443"
}
```
```sh
$ sudo docker exec -it dendrite-matrix-1 /usr/bin/create-account -config /etc/dendrite/dendrite.yaml -username $USER -password $password -admin
```