Mastodon + Docker + Portainer + Nginx. Открываем двери федивёрса на VPS Ubuntu 22.04
Mastodon — социальная сеть микроблогов, использующая в своей основе модель децентрализации, называемую также федерацией, федиверсом или федеративной вселенной реализованную с помощью протокола ActivityPub. Он имеет открытый исходный код и может быть развернут любым пользователем на любом сервере, причем каждый сервер является полностью самостоятельным экземпляром Mastodon. Каждый экземпляр может иметь свои собственные политики, правила модерации и управляется только Вами. В федерации нет корпоративных модераторов от компаний-разработчиков, управление всем контентом осуществляется только Вами и никто извне не сможет вас ограничить в рамках вашего экземпляра. В федерации, состоящей из всех пользовательских серверов Mastodon (и других сервисов, например Pixelfed, PeerTube и т. д.), каждый экземпляр может быть осведомлен о других экземплярах по протоколу ActivityPub. Это позволяет взаимодействовать с другими пользователями как внутри одного сервера, так и между разными экземплярами Mastodon.
Это руководство - перенос моей существующей статьи из self-host инстанса Ghost. На сегодняшний день последняя актуальная версия Mastodon 4.2.5. Однако, там фундаментально ничего не изменилось с 4.2.1 и все будет работать так, как описано в этом руководстве. В ближайшее время я постараюсь обновить это руководство, т.к. если с актуальностью технической части все хорошо, то некоторые логические последовательности стоит переписать для простоты понимания.
В этом руководстве вы установите последнюю версию Mastodon, которая на момент написания статьи является 4.2.1. Настроите свой сервер Ubuntu 22.04, установите Docker для работы с контейнерами, а так же настроите Portainer для управление Вашими Docker-контейнерами через графический интерфейс, а не командную строку. Также установите proxy-сервер nginx и получите для всех своих сервисов SSL/TLS Let's Encrypt сертификаты для защищенного HTTPS соединения.
Данное руководство можно считать расширенной версией большинства руководств. Я не буду рассказывать «как запустить инстанс за 2 минуты», чтобы потом удалить его через 20 минут, т. к. он совершенно не подходит для дальнейшего развития. Я расскажу как сделать правильно и визуально приятно глазу, чтобы вы сами видели результат своих трудов и могли смотреть логи и ошибки в графическом интерфейсе, а не в черном окошке. Поэтому тут будут моменты, когда было бы проще сделать «все в одной корзине» и Вы бы просто ноубрейн вставляли код, но я буду объяснять почему так и зачем. Чтобы в дальнейшем вы понимали что Вы делали и зачем это делали. Мы будем идти немного более сложным путем, чем могли бы, но это Вам пригодится потом, когда Вы, например, захотите вынести свою базу данных на отдельный VPS сервер и держать ее там для повышения производительности и безопасности. Опыт из данного руководства подготовит Вас к этому. Так что старт будет немного тернист, но перспективы прекрасны.
Что у Вас уже есть перед началом:
- Арендованный у cloud-провайдера VPS сервер Ubuntu 22.04 (рекомендую Timeweb);
- Ваш домен куплен и его DNS А-записи указывают на IPv4 адрес вашего VPS сервера (например
example.com
). - Создан поддомен для Portainer и А-записи поддомена также указывают на IPv4 адрес вашего VPS сервера (например
panel.example.com
).
Подготовка
Для начала установим весь необходимый софт для установки и дальнейшего обслуживания нашей ноды Mastodon:
sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg gnupg2 ca-certificates lsb-release ubuntu-keyring unzip ufw htop -y
Зададим политики файрвола, чтобы контролировать порты на Вашем сервере:
sudo ufw allow OpenSSH sudo ufw allow http sudo ufw allow https
sudo ufw enable
Это все, что необходимо сделать с сервером для стабильной работы. Дальше устанавливаем Docker, который в дальнейшем будет отвечать за контейнеры Mastodon.
Сначала убедимся, что у Вас нет никаких старых установок Docker и от него нет никакого мусора в системе, а если есть, то удалим это:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get update
Добавляем APT репозиторий Docker на сервер:
sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
Теперь устанавливаем сам Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Удостоверимся, что Docker работает правильно:
sudo docker run hello-world
Чтобы два раза не возвращаться к Docker, сразу установим к нему Portainer. Это делается в пару команд.
Для начала создадим docker-том, где будет работать Portainer:
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Все. Теперь, если Вы перейдете по вашему IP адресу сервера (например х.х.х.х:9443) или по адресу домена, который вы привязали к вашему серверу (например panel.example.com:9443), то вы попадаете в графический интерфейс панели управления Portainer, который в свою очередь управляет Docker установленный на вашем сервере. В дальнейшем Вы избавитесь от необходимости указывать порт 9443 для доступа к Portainer.
Установка Mastodon
Для начала Вам необходимо создать директории на нашем сервере, где Вы будете хранить ваши данные. Я предпочитаю все разделять по директориям, чтобы потом понимать где что искать.
Начнем с создания директорий для базы данных:
sudo mkdir -p /opt/database/mastodon/{postgresql,pgbackups,redis}
и сразу задаем права для директории:
sudo chown 70:70 /opt/database/mastodon/pgbackups
Точно так же создаем директорию для данных самого Mastodon:
sudo mkdir -p /opt/mastodon/web/{public,system} sudo mkdir -p /opt/mastodon/branding
sudo chown 991:991 /opt/mastodon/web/{public,system}
После этого идем в установленный ранее Portainer. При первом запуске он предложит вам зарегистрировать аккаунт администратора.
примечание:
при первом заходе в Portainer, возможно он Вас попросит перезагрузить свой контейнер и не даст создать аккаунт. В этом случае просто перезагрузите контейнер командойdocker restart portainer_agent
и зайдите в Portainer снова.
После входа в Portainer перейдите на вкладку Home
и нажмите Live Connect
к вашему единственному серверу. Дальше в левой части экрана у вас появится новое меню, где Вас интересует пункт Stack
. Переходите в него и нажимайте +add stack
.
Перед Вами откроется окно для создания файла docker-compose.yml, выглядит это так:
Здесь вводите название на Ваш выбор. Главное, чтобы Вы сами понимали что оно означает. Например mastodon_db
, а в основное окно ниже вставляем следующий код:
version: '3' services: postgres: image: postgres:15-alpine container_name: postgres shm_size: 512mb restart: always network_mode: bridge ports: - '5432:5432' healthcheck: test: ['CMD', 'pg_isready', '-U', 'postgres'] volumes: - postgresql:/var/lib/postgresql/data - pgbackups:/backups environment: - 'POSTGRES_HOST_AUTH_METHOD=trust' redis: image: redis:7-alpine container_name: redis restart: always network_mode: bridge ports: - '6379:6379' healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: - redis:/data redis-volatile: image: redis:7-alpine container_name: redis-volatile restart: always network_mode: bridge healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: postgresql: driver_opts: type: none device: /opt/database/mastodon/postgresql o: bind pgbackups: driver_opts: type: none device: /opt/database/mastodon/pgbackups o: bind redis: driver_opts: type: none device: /opt/database/mastodon/redis o: bind
После этого внизу экрана нажимаем Deploy the stack
и ждем, когда появится уведомление о удачном развертываний Ваших баз данных.
Теперь точно так же делаем новый Stack
, называем его как-то удобно для Вас, например mastodon_web
и копируем следующий код:
version: '3' services: website: image: ghcr.io/mastodon/mastodon:v4.2.1 container_name: website env_file: stack.env command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" restart: always ports: - '127.0.0.1:3000:3000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] volumes: - uploads:/mastodon/public/system streaming: image: ghcr.io/mastodon/mastodon:v4.2.1 container_name: streaming env_file: stack.env command: node ./streaming restart: always ports: - '127.0.0.1:4000:4000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] sidekiq: image: ghcr.io/mastodon/mastodon:v4.2.1 container_name: sidekiq env_file: stack.env command: bundle exec sidekiq restart: always depends_on: - website networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] volumes: - uploads:/mastodon/public/system shell: image: ghcr.io/mastodon/mastodon:v4.2.1 container_name: shell env_file: stack.env command: /bin/bash restart: "no" networks: - internal_network - external_network volumes: - uploads:/mastodon/public/system - static:/static networks: external_network: internal_network: internal: true volumes: uploads: driver_opts: type: none device: /opt/mastodon/web/system o: bind static: driver_opts: type: none device: /opt/mastodon/web/public o: bind
Ниже этого окна будет еще один пункт, где вам нужно нажать advanced mode
:
В открывшееся окно вставляем значение переменных окружения (.env), которыми будет пользоваться Ваш Mastodon:
LOCAL_DOMAIN=example.com SINGLE_USER_MODE=false SECRET_KEY_BASE=257935a5e78673fc79b8888888888bb8a9e58452aa8aab6896794b0e31d8b77cf8888888888a96818913f3213472bb857e3f888888888805da1daeb1e88b9b53 OTP_SECRET=03d99fe6cd8dd316bb962ec366888888888822fcc0b4a31795554b5cee1f5d685fd88888888885c96979ca4f8097851cf5ca898888888888dfcdaa6ddce2fae1 VAPID_PRIVATE_KEY=8hk8888888888RpDA8888888888ZWHm9KYKIpIrhMj0= VAPID_PUBLIC_KEY=BPZJW5ieC8888888888Zo9uyp05qUn1tbi8888888888Dxa81dvabtLCxgLUg94fliD4UJyY8888888888885lFdE= DB_HOST=postgres DB_PORT=5432 DB_NAME=postgres DB_USER=mastodon DB_PASS=verysecretpass REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD= SMTP_SERVER=smtp.timeweb.ru SMTP_PORT=25 SMTP_LOGIN=admin@example.com SMTP_PASSWORD=0088664422 SMTP_AUTH_METHOD=plain SMTP_OPENSSL_VERIFY_MODE=none SMTP_ENABLE_STARTTLS=auto SMTP_FROM_ADDRESS=Mastodon <admin@example.com>
примечание:
Тут присутствует настройка отправки почты через SMTP. Настоятельно рекомендую это сделать. Получите почтовый ящик к своему домену там же, где вы купили домен. В примере выше указаны настройки для Timeweb, в данном случаем Вам нужно будет изменить толькоSMTP_LOGIN
иSMTP_PASSWORD
на свои и все. Так же нужно заменитьSMTP_FROM_ADDRESS
на что-то свое.SMTP_FROM_ADDRESS
задает какой адрес электронной почты отправителя будут видеть Ваши пользователи, когда им будут приходить письма от Вас с уведомлениями или регистрацией.
После этого нажимаем Deploy the stack
и ждем, когда все контейнеры загрузятся. Это может занять несколько минут.
примечание:
при попытке первого деплоя этого стака, возможно, спустя пару минут у Вас появится ошибка в верхнем правом углу о неудаче. Ничего страшного, можно сказать что так и должно быть. Нажимаем еще разDeploy the stack
и он запустится без ошибок, если вы все сделали до этого правильно.
На данном этапе у Вас есть 2 стака, в первом находится база данных, во втором сам Mastodon. Сейчас нужно будет объединить их в одну сеть, чтобы они друг друга видели и могла общаться между собой. Для этого во втором стаке с Mastodon поочередно заходите (просто нажимайте на название) в каждый из контейнеров website
, streaming
и sidekiq
и в самом низу страницы добавляйте их в сеть базы данных выбрав нужную сеть нажатием на Select a network
. Если вы стак с базой данных назвали как я предлагал выше, то нужная сеть будет называться mastodon_db_default
. Каждый из контейнеров website
, streaming
и sidekiq
должен быть сразу в двух сетях - в своей родной и сети от базы данных, в данном случае в mastodon_db_default
.
Конфигурация контейнеров
В целом мы сделали уже самое основное и по большому счету нам осталось это между собой подружить и запустить в рабочем состоянии, т.к. сейчас это запущено, но ничего не работает. И начинаем с конфигурации базы данных:
sudo docker run --name postgres14 -v /opt/database/mastodon/postgresql:/var/lib/postgresql/data -e POSTGRES_PASSWORD=verysecretpass --rm -d postgres:14-alpine
Заходим в контейнер с базой данных:
sudo docker exec -it postgres14 psql -U postgres
CREATE USER mastodon WITH PASSWORD 'verysecretpass' CREATEDB;
Выходим из базы данных обратно:
exit
sudo docker stop postgres14
На этом наша база данных настроена и готова в работе. Осталось закончить с конфигурацией контейнера Mastodon, но тут совсем просто, т.к. он будет просить Вас ввести те значения переменных (.env), которые вы указывали выше во время запуска второго стака. Например первое, что он попросит Вас указать - это адрес вашего домена example.com
. В самом конце Вам будет предложено проверить правильность настройки SMTP и попросит ввести e-mail адрес куда отправить тестовое письмо. Сделайте это, чтобы быть уверенным, что все работает исправно. Когда будут введены все переменные из таблицы выше (то, что вы указывали в advanced mode
в Portainer), соглашайтесь на предпоследний вопрос о подготовке базы данных и он Вам выдаст новый список переменных (для поля advanced mode
в Portainer). Дальше будет предложено создать аккаунт администратора, от этого откажитесь.
Начинаем конфигурацию Mastodon:
sudo docker exec -it streaming bundle exec rake mastodon:setup
Скопируйте список переменных из терминала, вернитесь в Portainer во второй стак mastodon_web
и вставьте теперь уже правильные переменные в advanced mode
. После этого нажмите внизу страницы update the stack
.
После того, как контейнеры будут перезагружены, убедитесь, что все 3 контейнера website
, streaming
и sidekiq
находятся в сети mastodon_db_default
, как мы это делали ранее заходя в каждый из них по очереди, если нет, то добавьте их снова в сеть.
Теперь нам осталось только создать администратора и на этом конфигурация самого Mastodon будет окончена. Для этого используйте пару следующих команд.
sudo docker exec -it streaming /bin/bash
Создаем аккаунт администратора:
RAILS_ENV=production bin/tootctl accounts create admin --email admin@example.com --role=Owner
Можете заменить admin
на свой ник и почту тоже заменить на свою.
примечание:
Обратите внимание, что после выполнения команды выше, в окне терминала будет указан пароль от этого аккаунта. Запишите его сразу куда-то, чтобы не потерять.
Сразу подтверждаем свой аккаунт, без необходимости делать это через почту:
RAILS_ENV=production bin/tootctl accounts modify admin --confirm
Замените admin
на Ваш ник, если вы его заменили в прошлой команде.
exit
На этом экземпляр Mastodon готов и полностью готов к работе. Осталось дело за малым - выпустить SSL сертификаты и настроить nginx.
Установка NGINX
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Добавляем репозиторий стабильной версии nginx:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \ http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx
sudo systemctl start nginx
Получаем SSL-сертификаты
Для получения сертификатов нам нужен Certbot. Есть разные версии, но мы будем использовать версию последнюю версию в Snapd:
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
Для исправной работы Certbot создаем символическую ссылку:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Если вы правильно настроили свои DNS A-записи для своего домена, то следующая команда сгенерирует Вам SSL сертификаты:
sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d example.com
Замените почту и адрес домена example.com
на свои.
Так же сразу получите сертификаты для своего поддомена для Portainer, заменив example.com
на panel.example.com
.
Получаем сертификат Diffie-Hellman:
sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Убедитесь, что обновление сертификатов работает исправно, выполнив следующую команду:
sudo certbot renew --dry-run
Настраиваем NGINX
Открываем файлик конфига с помощью редактора nano
:
sudo nano /etc/nginx/nginx.conf
В открывшемся файле найдите строку include /etc/nginx/conf.d/*.conf;
и перед этой
строкой вставьте следующую строку:
server_names_hash_bucket_size 64;
Нажмите Ctrl + S
, чтобы сохранить изменения и закройте редактор нажатием Ctrl + X
.
Создайте и откройте в редакторе файл конфигурации Nginx:
sudo nano /etc/nginx/conf.d/mastodon.conf
и вставьте туда следующий код:
map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream backend { server 127.0.0.1:3000 fail_timeout=0; } upstream streaming { # Instruct nginx to send connections to the server with the least number of connections # to ensure load is distributed evenly. least_conn; server 127.0.0.1:4000 fail_timeout=0; # Uncomment these lines for load-balancing multiple instances of streaming for scaling, # this assumes your running the streaming server on ports 4000, 4001, and 4002: # server 127.0.0.1:4001 fail_timeout=0; # server 127.0.0.1:4002 fail_timeout=0; } proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; server { listen 80; listen [::]:80; server_name example.com; root /opt/mastodon/web/public; location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com; ssl_protocols TLSv1.2 TLSv1.3; # You can use https://ssl-config.mozilla.org/ to generate your cipher set. # We recommend their "Intermediate" level. ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Uncomment these lines once you acquire a certificate: ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; keepalive_timeout 70; sendfile on; client_max_body_size 99m; root /opt/mastodon/web/public; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon; location / { try_files $uri @proxy; } # If Docker is used for deployment and Rails serves static files, # then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`. location = /sw.js { add_header Cache-Control "public, max-age=604800, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/assets/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/avatars/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/emoji/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/headers/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/packs/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/shortcuts/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/sounds/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; try_files $uri @proxy; } location ~ ^/system/ { add_header Cache-Control "public, max-age=2419200, immutable"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; add_header X-Content-Type-Options nosniff; add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; try_files $uri @proxy; } location ^~ /api/v1/streaming { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Proxy ""; proxy_pass http://streaming; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; tcp_nodelay on; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://backend; proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_cache CACHE; proxy_cache_valid 200 7d; proxy_cache_valid 410 24h; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; add_header X-Cached $upstream_cache_status; tcp_nodelay on; } error_page 404 500 501 502 503 504 /500.html; }
В этом коде есть 4 места, где нужно заменить example.com
на ваш адрес домена Mastodon.
И сразу создайте файл конфига Nginx для Portainer:
sudo nano /etc/nginx/conf.d/portainer.conf
И вставьте туда следующий код:
upstream portainer { server 0.0.0.0:9443; } server { listen 80; server_name panel.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; # The block below works only for the selected domains server_name panel.example.com; ssl_certificate /etc/letsencrypt/live/panel.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem; # managed by Certbot ssl_trusted_certificate /etc/letsencrypt/live/panel.example.com/chain.pem; access_log /var/log/nginx/portainer.access.log; error_log /var/log/nginx/portainer.error.log; location / { proxy_pass https://portainer/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } location /api/websocket/ { proxy_pass https://portainer/api/websocket/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } }
В этом коде так же есть 4 места, где нужно заменить panel.example.com
на ваш адрес поддомена Portainer.
Теперь перезапустим Nginx командой:
sudo systemctl restart nginx
Если все работает исправно, что никакого вывода в терминале не будет. Вы перезапустите Nginx и все.
Можете проверить синтаксис файлов конфигов Nginx следующей командой:
sudo nginx -t
Теперь, если вы перейдете по адресу своего домена example.com
, то у вас будет открываться Ваш экземпляр Mastodon.
А переход по адресу panel.example.com
будет открывать Ваш Portainer.
На этом все. У вас есть возможность отслеживать логи своего инстанса Mastodon, его поведение, обновление, поддержка и много другой работы через графический интерфейс на вашем домене Portainer, без необходимости постоянно открывать терминал и подключаться к VPS по SSH. Теперь дело за Вами, как Вы будете это развивать и администрировать. Удачи Вам на просторах федиверса!
Послесловие
Этим руководством я решил открыть свой маленький блог, где я планирую писать различные руководства для open-source софта, self-host ПО, Linux и т.д.