Rocky Linux 9에서 Docker로 Mastodon 소셜 네트워크를 설치하는 방법
이 페이지에서
- 전제 조건
- 1단계 - 방화벽 구성\n
- 2단계 - Docker 및 Docker Compose 설치
- 3단계 - 설치 준비
- 4단계 - Mastodon 설치
- 디렉토리 생성 및 소유권 설정
- 환경 생성 및 docker compose 파일\n
- 응용 프로그램 암호 만들기\n
- Mastodon 환경 파일\n
- 마스토돈 준비
- Tootctl CLI 도구
- Mastodon 서비스 파일
- 검색 초기화\n
- 추가 도우미 서비스
- 마스토돈 액세스
Mastodon은 무료 분산형 오픈 소스 소셜 네트워크입니다. Twitter의 대안으로 만들어졌습니다. Twitter와 마찬가지로 사람들은 서로를 팔로우하고 메시지, 이미지 및 비디오를 게시할 수 있습니다. 그러나 Twitter와 달리 콘텐츠에 대한 중앙 저장소나 권한이 없습니다.
대신 Mastodon은 커뮤니티의 다양한 구성원이 각각 실행하는 수천 개의 서로 다른 서버에서 작동합니다. 한 서버에 등록된 사용자는 다른 네트워크의 사용자에게 쉽게 연결하고 인스턴스 간에 서로를 따를 수 있습니다.
누구나 마스토돈 서버 인스턴스를 설치할 수 있습니다. 이 튜토리얼은 Docker를 사용하여 Rocky Linux 9이 설치된 서버에서 Mastodon 인스턴스를 설정하는 방법을 알려줍니다. Docker를 사용하면 컨테이너에 필요한 모든 패키지와 서비스를 포함하여 Mastodon을 쉽게 설치할 수 있습니다.
전제 조건
-
A server running Rocky Linux 9 with a minimum of 2 CPU cores and 2GB of memory. You will need to upgrade the server as per requirements.
-
A non-root user with sudo privileges.
-
A fully qualified domain name (FQDN) pointing to your server. For our purposes, we will use
mastodon.example.com
as the domain name. -
Mastodon sends email notifications to users. We will recommend you use a 3rd party Transactional mail service like Mailgun, Sendgrid, Amazon SES, or Sparkpost. The instructions in the guide will be using Amazon SES.
-
Make sure everything is updated.
$ sudo dnf update
-
Install basic utility packages. Some of them may already be installed.
$ sudo dnf install wget curl nano unzip yum-utils -y
1단계 - 방화벽 구성
첫 번째 단계는 방화벽을 구성하는 것입니다. Rocky Linux는 Firewalld Firewall을 사용합니다. 방화벽 상태를 확인하십시오.
$ sudo firewall-cmd --state running
방화벽은 다른 영역에서 작동하며 공개 영역은 우리가 사용할 기본 영역입니다. 방화벽에서 활성화된 모든 서비스와 포트를 나열합니다.
$ sudo firewall-cmd --permanent --list-services
다음 출력이 표시되어야 합니다.
cockpit dhcpv6-client ssh
Wiki.js가 작동하려면 HTTP 및 HTTPS 포트가 필요합니다. 열어보세요.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
응용 프로그램이 다른 인스턴스에 연결하므로 마스커레이드를 추가합니다.
$ sudo firewall-cmd --permanent --add-masquerade
변경 사항을 적용하려면 방화벽을 다시 로드하십시오.
$ sudo firewall-cmd --reload
2단계 - Docker 및 Docker Compose 설치
Rocky Linux는 이전 버전의 Docker와 함께 제공됩니다. 최신 버전을 설치하려면 먼저 공식 Docker 리포지토리를 설치합니다.
$ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
최신 버전의 Docker를 설치합니다.
$ sudo dnf install docker-ce docker-ce-cli containerd.io
Docker를 설치하는 동안 다음 오류가 발생할 수 있습니다.
ror: Problem: problem with installed package buildah-1:1.26.2-1.el9_0.x86_64 - package buildah-1:1.26.2-1.el9_0.x86_64 requires runc >= 1.0.0-26, but none of the providers can be installed - package containerd.io-1.6.9-3.1.el9.x86_64 conflicts with runc provided by runc-4:1.1.3-2.el9_0.x86_64 - package containerd.io-1.6.9-3.1.el9.x86_64 obsoletes runc provided by runc-4:1.1.3-2.el9_0.x86_64 - cannot install the best candidate for the job
위의 오류가 발생하면 다음 명령을 사용하십시오.
$ sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin --allowerasing
Docker 데몬을 활성화하고 실행합니다.
$ sudo systemctl enable docker --now
실행 중인지 확인합니다.
? docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2022-11-12 00:19:44 UTC; 6s ago TriggeredBy: ? docker.socket Docs: https://docs.docker.com Main PID: 99263 (dockerd) Tasks: 8 Memory: 28.1M CPU: 210ms CGroup: /system.slice/docker.service ??99263 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
기본적으로 Docker에는 루트 권한이 필요합니다.
sudo
명령을 실행할 때마다sudo
를 사용하지 않으려면docker
명령에 사용자 이름을 추가하세요. > 그룹.$ sudo usermod -aG docker $(whoami)
이 변경 사항을 활성화하려면 서버에서 로그아웃하고 동일한 사용자로 다시 로그인하거나 다음 명령을 사용해야 합니다.
$ su - ${USER}
사용자가 Docker 그룹에 추가되었는지 확인합니다.
$ groups navjot wheel docker
3단계 - 설치 준비
mmap 수의 기본 제한은 Elasticsearch에서 매우 낮습니다. 다음 명령을 실행하여 기본값을 확인하십시오.
$ sysctl vm.max_map_count
다음과 같은 결과가 표시됩니다.
vm.max_map_count = 65530
다음 명령을 사용하여 값을 늘립니다.
$ echo "vm.max_map_count=262144" | sudo tee /etc/sysctl.d/90-max_map_count.conf $ sudo sysctl --load /etc/sysctl.d/90-max_map_count.conf
네트워크 연결을 허용하도록 SELinux를 구성합니다.
$ sudo setsebool -P httpd_can_network_connect 1
4단계 - 마스토돈 설치
디렉토리 생성 및 소유권 설정
Mastodon 및 관련 서비스에 대한 디렉토리를 생성합니다.
$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch} $ sudo mkdir -p /opt/mastodon/web/{public,system} $ sudo mkdir -p /opt/mastodon/branding
Elasticsearch, 웹 및 백업 디렉터리에 적절한 소유권을 설정합니다.
$ sudo chown 991:991 /opt/mastodon/web/{public,system} $ sudo chown 1000 /opt/mastodon/database/elasticsearch $ sudo chown 70:70 /opt/mastodon/database/pgbackups
Mastodon 디렉터리로 전환합니다.
$ cd /opt/mastodon
환경 및 docker 작성 파일 만들기
애플리케이션 및 데이터베이스에 대한 환경 파일을 생성합니다.
$ sudo touch application.env database.env
편집을 위해 Docker 작성 파일을 만들고 엽니다.
$ sudo nano docker-compose.yml
다음 코드를 붙여넣습니다.
version: '3' services: postgresql: image: postgres:15-alpine env_file: database.env restart: always shm_size: 512mb healthcheck: test: ['CMD', 'pg_isready', '-U', 'postgres'] volumes: - postgresql:/var/lib/postgresql/data - pgbackups:/backups networks: - internal_network redis: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: - redis:/data networks: - internal_network redis-volatile: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] networks: - internal_network elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.17.7 restart: always env_file: database.env environment: - cluster.name=elasticsearch-mastodon - discovery.type=single-node - bootstrap.memory_lock=true - xpack.security.enabled=true - ingest.geoip.downloader.enabled=false ulimits: memlock: soft: -1 hard: -1 healthcheck: test: ["CMD-SHELL", "nc -z elasticsearch 9200"] volumes: - elasticsearch:/usr/share/elasticsearch/data networks: - internal_network website: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: bash -c "bundle exec rails s -p 3000" restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch 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 shell: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: /bin/bash restart: "no" networks: - internal_network - external_network volumes: - uploads:/mastodon/public/system - static:/static streaming: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: node ./streaming restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch 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: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: bundle exec sidekiq restart: always depends_on: - postgresql - redis - redis-volatile - website networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] volumes: - uploads:/mastodon/public/system networks: external_network: internal_network: #internal:true volumes: postgresql: driver_opts: type: none device: /opt/mastodon/database/postgresql o: bind pgbackups: driver_opts: type: none device: /opt/mastodon/database/pgbackups o: bind redis: driver_opts: type: none device: /opt/mastodon/database/redis o: bind elasticsearch: driver_opts: type: none device: /opt/mastodon/database/elasticsearch o: bind uploads: driver_opts: type: none device: /opt/mastodon/web/system o: bind static: driver_opts: type: none device: /opt/mastodon/web/public o: bind
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
튜토리얼 작성 시점에 사용 가능한 최신 Mastodon 버전은 v4.0.2입니다. Mastodon GitHub Releases 페이지를 확인하고 Docker compose 파일의 버전을 적절하게 조정하십시오. 최신 버전의 PostgreSQL과 Redis도 사용하고 있습니다. 요구 사항에 따라 조정할 수 있습니다. 현재 Elasticsearch 7.x를 사용하고 있습니다. Docker Hub 페이지에서 따를 수 있는 Elasticsearch의 주 버전이 없으므로 Java와 관련된 보안 업데이트를 위해 수동으로 계속 업데이트해야 합니다.
internal: true
는 firewalld에서 작동하지 않으므로 위 파일에서 주석 처리됩니다. 이 문제가 해결되면 추가 제한을 다시 추가할 수 있습니다.애플리케이션 비밀 만들기
다음 단계는 애플리케이션 비밀 값을 만드는 것입니다.
다음 명령을 두 번 실행하여
SECRET_KEY_BASE
및OTP_SECRET
값을 생성합니다. 처음에는 이미지를 가져오기 때문에 시간이 좀 걸립니다.$ docker compose run --rm shell bundle exec rake secret
동일한 용도로
openssl
유틸리티를 사용할 수도 있습니다.$ openssl rand -hex 64
다음 명령을 사용하여
VAPID_PRIVATE_KEY
및VAPID_PUBLIC_KEY
값을 생성합니다.$ docker compose run --rm shell bundle exec rake mastodon:webpush:generate_vapid_key
비슷한 출력을 얻을 수 있습니다.
VAPID_PRIVATE_KEY=u2qsCs5JdmdmMLnUuU0sgmFGvZedteJz-lFB_xF4_ac= VAPID_PUBLIC_KEY=BJXjE2hIXvFpo6dnHqyf1i-2PcP-cBoL95UCmhhxwlAgtFw_vnrYp4GBneR7_cmI9LZUYjHFh-TBAPSb9WTqH9A=
PostgreSQL 및 Elasticsearch 암호를 생성하려면
openssl
유틸리티를 사용하십시오.$ openssl rand -hex 15
마스토돈 환경 파일
편집을 위해
application.env
파일을 엽니다.$ sudo nano application.env
다음 줄을 붙여넣습니다.
# environment RAILS_ENV=production NODE_ENV=production # domain LOCAL_DOMAIN=mastodon.example.com # redirect to the first profile SINGLE_USER_MODE=false # do not serve static files RAILS_SERVE_STATIC_FILES=false # concurrency WEB_CONCURRENCY=2 MAX_THREADS=5 # pgbouncer #PREPARED_STATEMENTS=false # locale DEFAULT_LOCALE=en # email, not used SMTP_SERVER=email-smtp.us-west-2.amazonaws.com SMTP_PORT=587 SMTP_LOGIN=AKIA3FIG4NVFNSC3AHXE SMTP_PASSWORD=BHM4MVOjBmnGhSJ9lH3PAXKJ/9AiLWcUghG/kEN2kkFo # secrets SECRET_KEY_BASE=c09fa403575e0b431e54a2e228f20cd5a5fdfdbba0da80598959753b829a4e3c0266eedbac7e3cdf9f3345db36c56302c0e1bc5bfc8c5d516be59a2c41de7e37 OTP_SECRET=febb7dbb0d3308094083733fc923a430e52ccec767d48d7d2e0c577bfcb6863dbdfc920b1004b1f8c2967b9866bd7a0b4a15460f9fc7687aa4a42acf54e5a3d4 # Changing VAPID keys will break push notifications VAPID_PRIVATE_KEY=13RgrfOY2tkwuUycylDPOkoHennkJ0ZAPV_fUwDy7-g= VAPID_PUBLIC_KEY=BDAQuGwPbh1kbCV904adYXHvz9lLRaJHkiQkihRDPyBn3QmkAYbR21WHYoP8TkyG6dylG6IXpEVfLwdoW7fJVns=
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
편집을 위해
database.env
파일을 엽니다.$ sudo nano database.env
다음 줄을 붙여넣습니다.
# postgresql configuration POSTGRES_USER=mastodon POSTGRES_DB=mastodon POSTGRES_PASSWORD=15ff12dcb93aa60680d2aadb4032ee PGPASSWORD=15ff12dcb93aa60680d2aadb4032ee PGPORT=5432 PGHOST=postgresql PGUSER=mastodon # pgbouncer configuration #POOL_MODE=transaction #ADMIN_USERS=postgres,mastodon #DATABASE_URL="postgres://mastodon::5432/mastodon" # elasticsearch ES_JAVA_OPTS=-Xms512m -Xmx512m ELASTIC_PASSWORD=13382e99f6b2d4dc7f3d66e4b9872d # mastodon database configuration #DB_HOST=pgbouncer DB_HOST=postgresql DB_USER=mastodon DB_NAME=mastodon DB_PASS=15ff12dcb93aa60680d2aadb4032ee DB_PORT=5432 REDIS_HOST=redis REDIS_PORT=6379 CACHE_REDIS_HOST=redis-volatile CACHE_REDIS_PORT=6379 ES_ENABLED=true ES_HOST=elasticsearch ES_PORT=9200 ES_USER=elastic ES_PASS=13382e99f6b2d4dc7f3d66e4b9872d
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
마스토돈 준비하기
Nginx에서 제공할 정적 파일을 준비합니다.
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
데이터 계층을 불러옵니다.
$ docker compose up -d postgresql redis redis-volatile
컨테이너의 상태를 확인합니다.
$ watch docker compose ps
실행 중(정상)
을 기다린 후Ctrl + C
를 누르고 다음 명령을 사용하여 데이터베이스를 초기화합니다.$ docker compose run --rm shell bundle exec rake db:setup
5단계 - Nginx 설치
Rocky Linux는 이전 버전의 Nginx와 함께 제공됩니다. 최신 버전을 설치하려면 공식 Nginx 저장소를 다운로드해야 합니다.
공식 Nginx 리포지토리를 만들기 위한
/etc/yum.repos.d/nginx.repo
파일을 만들고 엽니다.$ sudo nano /etc/yum.repos.d/nginx.repo
다음 코드를 붙여넣습니다.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
Nginx 서버를 설치합니다.
$ sudo dnf install nginx
설치를 확인하십시오.
$ nginx -v nginx version: nginx/1.22.1
Nginx 서버를 활성화하고 시작합니다.
$ sudo systemctl enable nginx --now
서버의 상태를 확인하십시오.
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2022-11-13 13:49:55 UTC; 1s ago Docs: http://nginx.org/en/docs/ Process: 230797 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 230798 (nginx) Tasks: 3 (limit: 12355) Memory: 2.8M CPU: 13ms CGroup: /system.slice/nginx.service ??230798 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??230799 "nginx: worker process" ??230800 "nginx: worker process"
6단계 - SSL 설치
Certbot 도구는 Lets Encrypt API를 사용하여 SSL 인증서를 생성합니다. 작동하려면 EPEL 저장소가 필요합니다.
$ sudo dnf install epel-release
Snapd를 사용하여 Certbot을 설치합니다. 스냅드를 설치합니다.
$ sudo dnf install snapd
Snap 서비스를 활성화하고 시작합니다.
$ sudo systemctl enable snapd --now
Snap 코어 패키지를 설치합니다.
$ sudo snap install core $ sudo snap refresh core
Snapd가 작동하는 데 필요한 링크를 만듭니다.
$ sudo ln -s /var/lib/snapd/snap /snap $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
다음 명령을 실행하여 Certbot을 설치합니다.
$ sudo snap install --classic certbot
실행 파일에 대한 symlink를 생성하여 Certbot을 활성화합니다.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
SSL 인증서를 생성합니다.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m -d mastodon.example.com
위의 명령은 서버의
/etc/letsencrypt/live/mastodon.example.com
디렉토리에 인증서를 다운로드합니다.Diffie-Hellman 그룹 인증서를 생성합니다.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
SSL 갱신이 제대로 작동하는지 확인하려면 프로세스를 시험 실행하십시오.
$ sudo certbot renew --dry-run
오류가 표시되지 않으면 모든 설정이 완료된 것입니다. 인증서가 자동으로 갱신됩니다.
7단계 - Nginx 구성
편집을 위해
/etc/nginx/nginx.conf
파일을 엽니다.$ sudo nano /etc/nginx/nginx.conf
include /etc/nginx/conf.d/*.conf;
줄 앞에 다음 줄을 추가합니다.server_names_hash_bucket_size 64;
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
편집을 위해
/etc/nginx/conf.d/mastodon.conf
파일을 만들고 엽니다.$ 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 { server 127.0.0.1:4000 fail_timeout=0; } proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; server { listen 80 default_server; server_name mastodon.example.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; server_name mastodon.example.com; access_log /var/log/nginx/mastodon.access.log; error_log /var/log/nginx/mastodon.error.log; http2_push_preload on; # Enable HTTP/2 Server Push ssl_certificate /etc/letsencrypt/live/mastodon.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mastodon.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/mastodon.example.com/chain.pem; ssl_session_timeout 1d; # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC). ssl_protocols TLSv1.2 TLSv1.3; # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to # prevent replay attacks. # # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data ssl_early_data on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; keepalive_timeout 70; sendfile on; client_max_body_size 80m; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header X-Early-Data $tls1_3_early_data; 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; add_header Strict-Transport-Security "max-age=31536000" always; location / { try_files $uri @proxy; } location ~ ^/(system/accounts/avatars|system/media_attachments/files) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; root /opt/mastodon/; try_files $uri @proxy; } location ~ ^/(emoji|packs) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } location /sw.js { add_header Cache-Control "public, max-age=0"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } 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; add_header Strict-Transport-Security "max-age=31536000" always; tcp_nodelay on; } 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; tcp_nodelay on; } error_page 500 501 502 503 504 /500.html; } # This block is useful for debugging TLS v1.3. Please feel free to remove this # and use the `$ssl_early_data` variable exposed by NGINX directly should you # wish to do so. map $ssl_early_data $tls1_3_early_data { "~." $ssl_early_data; default ""; }
완료되면 Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
Nginx 구성 파일 구문을 확인합니다.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Nginx 서버를 다시 시작합니다.
$ sudo systemctl restart nginx
다음 오류가 발생하면 SELinux 제한 때문일 가능성이 큽니다.
nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)
오류를 수정하려면 다음 명령을 실행하십시오.
$ sudo ausearch -c 'nginx' --raw | audit2allow -M my-nginx $ sudo semodule -X 300 -i my-nginx.pp
Nginx 서비스를 다시 시작하십시오.
$ sudo systemctl start nginx
8단계 - 마스토돈 시작
Tootctl CLI 도구
Tootctl CLI 도구는 Mastodon에서 관리 작업을 수행하는 데 사용됩니다. 호스트 셸에서 액세스할 수 있도록 해야 합니다.
/usr/local/bin/tootctl
파일을 만들고 편집을 위해 엽니다.$ sudo nano /usr/local/bin/tootctl
다음 코드를 붙여넣습니다.
#!/bin/bash docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl ""
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
파일 실행 권한을 부여하십시오.
$ sudo chmod +x /usr/local/bin/tootctl
마스토돈 서비스 파일
Docker 작성 명령을 사용하여 Mastodon 컨테이너를 시작할 수 있지만 시스템 단위 파일을 통해 더 쉽게 수행할 수 있습니다.
편집을 위해 Mastodon 서비스 파일을 생성하고 엽니다.
$ sudo nano /etc/systemd/system/mastodon.service
다음 코드를 붙여넣습니다.
[Unit] Description=Mastodon service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml up -d ExecStop=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml down [Install] WantedBy=multi-user.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
시스템 데몬을 다시 로드하여 서비스 파일을 시작합니다.
$ sudo systemctl daemon-reload
Mastodon 서비스를 활성화하고 시작합니다.
$ sudo systemctl enable --now mastodon.service
Docker 컨테이너의 상태를 확인합니다.
$ watch docker compose -f /opt/mastodon/docker-compose.yml ps
컨테이너 상태가
실행 중(정상)
으로 변경되면 Ctrl + C를 눌러 화면을 종료합니다.Mastodon에 대한 관리 사용자를 생성하고 제공된 암호를 기록해 둡니다.
$ tootctl accounts create navjot --email --confirmed --role admin OK New password: 1338afbe1b4e06e823b6625da80cb537
사용자 등록을 종료하려면 다음 명령을 사용하십시오.
$ tootctl settings registrations close
등록을 다시 열려면 다음 명령을 실행하십시오.
$ tootctl settings registrations open
검색 초기화
Elasticsearch 인덱스를 생성하고 채우기 전에 툿트를 만들어야 합니다. 툿을 만든 후 다음 명령을 내립니다.
$ tootctl search deploy
다음과 같은 오류가 발생할 수 있습니다.
/opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/progress.rb:76:in `total=': You can't set the item's total value to less than the current progress. (ProgressBar::InvalidProgressError) from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:178:in `block in update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/output.rb:43:in `with_refresh' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:177:in `update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:101:in `total=' from /opt/mastodon/lib/mastodon/search_cli.rb:67:in `deploy' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:116:in `invoke' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:243:in `block in subcommand' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start' from /opt/mastodon/bin/tootctl:8:in `<main>'
이 경우 웹 사이트 컨테이너 셸을 입력합니다.
$ docker exec -it mastodon-web-1 /bin/bash
다음 명령을 실행합니다.
$ sed -E 's/indices.sum.+/2000/g' -i lib/mastodon/search_cli.rb
컨테이너 셸을 종료합니다.
$ exit
Elasticsearch 배포 명령을 다시 실행합니다.
$ tootctl search deploy
추가 도우미 서비스
다운로드한 미디어 파일을 제거하기 위한 다른 서비스를 만들어 보겠습니다.
편집을 위해 Mastodon 미디어 제거 서비스를 생성하고 엽니다.
$ sudo nano /etc/systemd/system/mastodon-media-remove.service
다음 코드를 붙여넣습니다.
[Unit] Description=Mastodon - media remove service Wants=mastodon-media-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl media remove [Install] WantedBy=multi-user.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
미디어 제거를 예약하려면 타이머 서비스를 설정할 수 있습니다.
$ sudo nano /etc/systemd/system/mastodon-media-remove.timer
다음 코드를 붙여넣습니다.
[Unit] Description=Schedule a media remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-media-remove.service [Install] WantedBy=timers.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
OpenGraph 태그를 사용하여 생성된 리치 미리보기 카드를 제거하도록 다른 서비스를 설정할 수 있습니다.
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.service
다음 코드를 붙여넣습니다.
[Unit] Description=Mastodon - preview cards remove service Wants=mastodon-preview_cards-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl preview_cards remove [Install] WantedBy=multi-user.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
해당 타이머 서비스를 설정합니다.
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.timer
다음 코드를 붙여넣습니다.
[Unit] Description=Schedule a preview cards remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-preview_cards-remove.service [Install] WantedBy=timers.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
시스템 데몬을 다시 로드합니다.
$ sudo systemctl daemon-reload
타이머를 활성화하고 시작합니다.
$ sudo systemctl enable --now mastodon-preview_cards-remove.timer $ sudo systemctl enable --now mastodon-media-remove.timer
모든 타이머를 나열하여 Mastodon 서비스 일정을 확인하십시오.
$ systemctl list-timers
액세스 마스토돈
URL
https://mastodon.example.com
을 방문하여 인스턴스에 액세스하면 유사한 페이지가 표시됩니다.위의 스크린샷에서 2명의 사용자가 있고 그 중 1명(나)이 관리자로 설정되어 있는 것을 볼 수 있습니다. 일반적으로 그렇지 않습니다. 관리자 계정을 생성해도 최초 실행시 메인페이지에 노출되지 않습니다. 그렇게 하려면 인스턴스에 로그인하면 다음 페이지로 이동합니다.
오른쪽 사이드바에서 기본 설정 옵션을 클릭하여 설정에 액세스합니다. 여기에서 왼쪽 메뉴의 관리 옵션을 클릭하여 Mastodons 관리 패널에 액세스합니다.
왼쪽 사이드바에서 사이트 설정 옵션을 클릭합니다.
여기에서 서버 홈페이지에 반영될 연락처 사용자 이름과 비즈니스 이메일을 입력하십시오. 또한 서버 설명, 로고 및 서버 규칙을 포함한 다양한 기타 정보를 입력하여 Mastodon 인스턴스를 사용자 정의하십시오.
9단계 - 마스토돈 유지 관리
Mastodon 인스턴스의 성능 및 로그를 보려면
https://mastodon.example.com/sidekiq/
로 이동하십시오.여기에서 Mastodon 인스턴스와 관련된 다양한 프로세스 및 예약된 작업 목록을 볼 수 있습니다. Dead 또는 Retries 섹션에서 실패한 작업을 확인할 수도 있습니다. 또한 인스턴스의 메모리 사용량도 알려줍니다.
https://mastodon.example.com/pghero/
에서 인스턴스 데이터베이스의 상태를 확인할 수 있습니다.데이터베이스 유지 관리를 수행하고, SQL 쿼리를 실행하고, 사용하지 않는 인덱스를 제거할 수 있습니다. 쿼리 통계를 활성화하려면 위 페이지에서 활성화 버튼을 클릭하면 다음 정보가 표시됩니다.
루트 사용자로 전환합니다.
$ sudo -i su
/opt/mastodon/database/postgresql
디렉터리로 전환합니다.$ cd /opt/mastodon/database/postgresql
postgresql.conf
파일을 엽니다.$ nano postgresql.conf
#shared_preload_libraries=# (change wants restart)
줄을 찾아 다음으로 바꿉니다.shared_preload_libraries = 'pg_stat_statements'
파일 끝에 다음 줄을 추가합니다.
pg_stat_statements.track = all
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
Mastodon 컨테이너를 다시 시작합니다.
$ systemctl restart mastodon.service
루트 쉘을 종료하십시오.
$ exit
데이터베이스 상태 페이지를 확인하면 지금 느린 쿼리가 있는지 확인할 수 있습니다.
참고: 기본 설정 메뉴에서 PgHero 및 Sidekiq URL을 실행할 수도 있습니다.
어떤 이유로 사이트가 로드되지 않으면 Docker에서 생성된 로그를 확인할 수 있습니다.
$ docker logs <container-name>
10단계 - 마스토돈 백업
Mastodon을 백업하기 위해 Restic이라는 타사 도구를 사용합니다. Restic을 사용하여 백업하는 첫 번째 단계는 모든 파일과 디렉토리를 저장소 목록에 추가하는 것입니다.
편집을 위해 리포지토리 목록 파일을 만들고 엽니다.
$ sudo nano /opt/mastodon/backup-files
다음 줄을 붙여넣습니다.
/etc/nginx /etc/letsencrypt /etc/systemd/system /root /opt/mastodon/database/pgbackups /opt/mastodon/*.env /opt/mastodon/docker-compose.yml /opt/mastodon/branding /opt/mastodon/database/redis /opt/mastodon/web/system /opt/mastodon/backup-files /opt/mastodon/mastodon-backup
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
레스틱을 설치합니다.
$ sudo dnf install restic
백업 리포지토리를 만들고 초기 백업을 만듭니다. 데이터를 S3 서비스에 백업하고 있습니다.
$ restic -r s3:https://$SERVER:$PORT/mybucket init $ restic -r s3:https://$SERVER:$PORT/mybucket backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql
Mastodon 백업 서비스 타이머를 생성하고 편집을 위해 엽니다.
$ sudo nano /etc/systemd/system/mastodon-backup.timer
다음 코드를 붙여넣습니다.
[Unit] Description=Schedule a mastodon backup every hour [Timer] Persistent=true OnCalendar=*:00:00 Unit=mastodon-backup.service [Install] WantedBy=timers.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
Mastodon 백업 서비스 파일을 생성하고 편집을 위해 엽니다.
$ sudo nano /etc/systemd/system/mastodon-backup.service
다음 코드를 붙여넣습니다.
[Unit] Description=Mastodon - backup service # Without this, they can run at the same time and race to docker compose, # double-creating networks and failing due to ambiguous network definition # requiring `docker network prune` and restarting After=mastodon.service [Service] Type=oneshot StandardError=file:/var/log/mastodon-backup.err StandardOutput=file:/var/log/mastodon-backup.log WorkingDirectory=/opt/mastodon ExecStart=/bin/bash /opt/mastodon/mastodon-backup [Install] WantedBy=multi-user.target
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
다음으로 편집을 위해
/opt/mastodon/mastodon-backup
파일을 만들고 엽니다. 여기에는 실제 백업 명령이 포함됩니다.$ sudo nano /opt/mastodon/mastodon-backup
다음 코드를 붙여넣습니다.
#!/bin/bash set -e AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= SERVER= PORT= RESTIC_PASSWORD_FILE=/root/restic-pasword docker compose -f /opt/mastodon/docker-compose.yml run --rm postgresql sh -c "pg_dump -Fp mastodon | gzip > /backups/dump.sql.gz" restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root forget --prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.
백업 스크립트에 실행 권한을 부여하십시오.
$ sudo chmod +x /opt/mastodon/mastodon-backup
서비스 데몬을 다시 로드하고 백업 서비스 및 타이머를 시작합니다.
$ sudo systemctl daemon-reload $ sudo systemctl enable --now mastodon-backup.service $ sudo systemctl enable --now mastodon-backup.timer
다음 명령을 사용하여 시간별 백업이 발생하고 액세스 가능한지 확인합니다.
$ restic -r s3:https://$SERVER:$PORT/mybucket snapshots $ restic -r s3:https://$SERVER:$PORT/mybucket mount /mnt
11단계 - 마스토돈 업그레이드
Mastodon을 업그레이드하려면 여러 단계가 필요합니다. 먼저 디렉터리로 전환합니다.
$ cd /opt/mastodon
Mastodon의 최신 컨테이너 이미지를 가져옵니다.
$ docker compose pull
원하는 경우
docker-compose.yml
을 변경합니다.모든 데이터베이스 마이그레이션을 수행합니다.
$ docker compose run --rm shell bundle exec rake db:migrate
정적 파일의 사본을 업데이트하십시오.
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
Mastodon 컨테이너를 다시 시작합니다.
$ sudo systemctl restart mastodon.service
위의 지침은 일반적인 업데이트 지침입니다. 항상 Mastodon의 GitHub 릴리스 페이지를 확인하여 모든 것이 원활하게 진행되도록 버전 간의 특정 업데이트 작업 및 명령을 찾습니다.
결론
이것으로 Rocky Linux 9 서버에서 Docker를 사용하여 Mastodon Social Network를 설치하는 방법에 대한 자습서를 마칩니다. 질문이 있으시면 아래 의견에 게시하십시오.