〇FLAG 속의 사람을 동경해 Mastodon×AWS로 몬스트돈 만들어 보았다

Mastodon을 시작하면 좋은 회사에 들어갈 것이라고 듣고 사악한 느낌으로. . . 아니, Mastodon과 몬스트는 궁합 좋을 것 같다고 생각들, 조금 뒤쳐진 느낌을 자아내면서, 완전히 AWS를 사용해 규모 확대해도 괜찮은 구성으로 만들어 보았다.

몬스트돈 ( htps : // Monstd. 이 m ) 폐쇄되었습니다. 2018.01.01

구성





최소 구성의 자율 요금($1=113엔, 1개월 30일 계산)


서비스
단가
월액 요금


ALB
1대 × $0.0243/1H + 데이터 전송적인 것
약 2000엔 + α

EC2
2대(t2.nano) × $0.008/1H + 데이터 전송적인 것
약 1300엔 + α

RDS
1대(db.t2.micro 싱글 AZ) $0.028/1H + 데이터 전송적인 것
약 2300엔 + α

ElasticCache
1대(cache.t2.micro) $0.026/1H + 데이터 전송적인 것
약 2100엔 + α

S3Bucket
$0.025/GB + 요청 수


SES
$0.10/1,000개당 + 데이터 전송


총    
(약 7700엔 + α이므로)
1만정도 정도


※무료 프레임이 있으므로 1년째는 좀 더 쉽게 할 수 있을 것 같다

했던 일


  • AWS 계정 생성
  • IAM 생성 및 계정 초기화 (2 단계 인증 또는 비밀번호 정책)
  • Route53에서 도메인 구매
  • SES에서 메일 설정 및 제한 해제 신청
  • ACM 취득 (무료로 HTTPS 통신)
  • S3 버킷 생성 (이미지 또는 업로드 파일 전송 용)
  • VPC 및 보안 그룹 만들기
  • SES, S3에 액세스하기위한 IAM 사용자 생성
  • ElasticCache에서 Redis 만들기
  • RDS에서 PostgreSQL 만들기
  • EC2에서 CentOS를 사용하여 Mastodon 빌드 (아래 세부 사항) 및 이미지 (AMI) 생성
  • AutoScalling 설정
  • ALB (ApplicationLoadBalancer) 만들기 (ACM 추가)
  • Route53에서 HostZone의 레코드 설정

  • CentOS에서 Mastdon 구축 (20170517 현재)


    sudo su -
    yum -y update
    yum -y install vim
    
    localectl set-locale LANG=ja_JP.utf8
    localectl set-keymap jp106
    localectl status
    
    timedatectl set-timezone Asia/Tokyo
    timedatectl status
    
    dd if=/dev/zero of=/mnt/swapfile bs=1M count=2560
    mkswap /mnt/swapfile
    swapon /mnt/swapfile
    chmod 0644 /mnt/swapfile
    echo "/mnt/swapfile                             swap                    swap    defaults                0 0" >> /etc/fstab
    free
    
    vim /etc/sysconfig/selinux
     SELINUX=enforcing
     ↓
     SELINUX=disabled
    
    systemctl disable postfix
    systemctl disable auditd.service
    
    yum -y install libxml2-devel ImageMagick libxslt-devel git curl nodejs file
    yum -y install epel-release
    rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
    rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
    yum -y install ffmpeg ffmpeg-devel
    
    yum -y group install "Development tools"
    curl -sL https://rpm.nodesource.com/setup_4.x | sudo bash -
    
    yum -y install nodejs
    npm -g install yarn
    
    yum -y install postgresql postgresql-contrib postgresql-devel
    yum install -y openssl-devel readline-devel
    
    useradd mastodon
    passwd mastodon
    su - mastodon
    git clone https://github.com/rbenv/rbenv.git ~/.rbenv
    cd ~/.rbenv && src/configure && make -C src && cd ~
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
    echo 'eval "$(rbenv init -)"' >> ~/.bash_profile && source ~/.bash_profile
    git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
    rbenv install 2.4.1 && rbenv global $_ && rbenv rehash
    
    # 確認
    ruby -v
    
    cd ~
    git clone https://github.com/tootsuite/mastodon.git live
    cd live
    git checkout $(git tag | tail -n 1)
    
    gem install bundler
    bundle install --deployment --without development test
    yarn install --pure-lockfile
    
    cp .env.production.sample .env.production
    sed -i "/^PAPERCLIP_SECRET=$/ s/$/`rake secret`/" .env.production
    sed -i "/^SECRET_KEY_BASE=$/ s/$/`rake secret`/" .env.production
    sed -i "/^OTP_SECRET=$/ s/$/`rake secret`/" .env.production
    
    vim .env.production
    #Redis,Postgresql,言語,SMTP,S3の設定
    
    RAILS_ENV=production bundle exec rails db:setup
    RAILS_ENV=production bundle exec rails assets:precompile
    
    exit
    
    cat << "_EOF_" > /etc/systemd/system/mastodon-web.service
    [Unit]
    Description=mastodon-web
    After=network.target
    
    [Service]
    Type=simple
    User=mastodon
    WorkingDirectory=/home/mastodon/live
    Environment="RAILS_ENV=production"
    Environment="PORT=3000"
    ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
    TimeoutSec=15
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    _EOF_
    
    
    cat << "_EOF_" > /etc/systemd/system/mastodon-sidekiq.service
    [Unit]
    Description=mastodon-sidekiq
    After=network.target
    
    [Service]
    Type=simple
    User=mastodon
    WorkingDirectory=/home/mastodon/live
    Environment="RAILS_ENV=production"
    Environment="DB_POOL=5"
    ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
    TimeoutSec=15
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    _EOF_
    
    cat << "_EOF_" > /etc/systemd/system/mastodon-streaming.service
    [Unit]
    Description=mastodon-streaming
    After=network.target
    
    [Service]
    Type=simple
    User=mastodon
    WorkingDirectory=/home/mastodon/live
    Environment="NODE_ENV=production"
    Environment="PORT=4000"
    ExecStart=/usr/bin/npm run start
    TimeoutSec=15
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    _EOF_
    
    systemctl enable mastodon-{web,sidekiq,streaming}
    systemctl start mastodon-{web,sidekiq,streaming}
    
    cat << "_EOF_" | crontab -
    RAILS_ENV=production
    @daily cd /home/mastodon/live && /home/mastodon/.rbenv/shims/bundle exec rake mastodon:daily > /dev/null
    _EOF_
    
    yum -y install nginx
    
    cat << "_EOF_" > /etc/nginx/conf.d/mastodon.conf
    map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
    }
    
    server {
      listen 80;
      listen [::]:80;
      server_name {domainName};
    
      keepalive_timeout    70;
      sendfile             on;
      client_max_body_size 0;
    
      root /home/mastodon/live/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;
    
      add_header Strict-Transport-Security "max-age=31536000";
    
      location / {
        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 https;
        proxy_set_header Proxy "";
        proxy_pass_header Server;
    
        proxy_pass http://127.0.0.1:3000;
        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;
      }
    
      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 https;
        proxy_set_header Proxy "";
    
        proxy_pass http://localhost:4000;
        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;
    }
    _EOF_
    
    systemctl enable nginx
    systemctl start nginx
    
    # ユーザ登録後 admin設定
    RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME={UserName}
    

    메모



    EC2의 Disk는 SSD로 (swap에서 사용)
    로드 밸런서는 Application이 아니면 webSocket이 작동하지 않습니다.
    커뮤니티 기반 시스템이기 때문에 CloudFront는 필요성을 느끼지 않았기 때문에 사용하지 않았습니다.
    (일본용이고 S3의 버킷 도쿄 리전에 있고, S3도 꽤 성능 좋고)
    CloudFront를 사용한다면 websocket 할 수 없기 때문에 S3 앞에 놓는 느낌
    이번 CloudFront의 장점이 있다면 "도메인"이 자신이 사용할 수있는 정도일까
    CentOS가 아니고 AmazonLinux 사용하고 싶었지만, ffmpeg 넣는데 시간이 걸렸기 때문에 그만두었다. 일단 움직였지만(순정 AWS가...)
    Docker는 Deploy까지 즐겁지 만 효율적이지 않았기 때문에 그만 두었습니다.
    AWS에서 Docker를 사용한다면 ECS를 사용해보고 싶지만 Mastodon은 쉽게 할 수 있습니까?
    보안적으로는 로드 밸런서로부터의 80번 포트 밖에 받아들이지 않도록 제어하고 있기 때문에 괜찮을까.
    ssh로의 로그인은 같은 VPC내에 발판 서버 세워서.

    마지막으로



    여기까지 읽어 주셔서 감사합니다.
    기술적인 내용을 게시하는 것은 이것이 처음이지만 누군가가 도움이되면 기쁩니다.
    평상시는 PHP와 AWS 적은 정도이므로 좋은 공부가 되었습니다.
    거의 공개되고 있는 문헌을 바탕으로 프라모델 감각으로 만들었으므로, 지적등 있으면 코멘트 받을 수 있으면이라고 생각합니다.
    개인의 사이트 운용이 되기 때문에, 떨어지면 미안해.

    좋은 웹페이지 즐겨찾기