+++ 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 ```