documentation/Running-Mastodon/Production-guide.md

305 lines
8.9 KiB
Markdown
Raw Normal View History

2017-01-21 22:49:08 +01:00
Production guide
================
## Nginx
Regardless of whether you go with the Docker approach or not, here is an example Nginx server configuration:
```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
2017-04-05 03:43:21 +02:00
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://$host$request_uri;
}
2017-01-21 22:49:08 +01:00
server {
listen 443 ssl;
server_name example.com;
2017-04-05 03:43:21 +02:00
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
2017-04-07 21:10:39 +02:00
ssl_ecdh_curve prime256v1;
2017-04-05 03:43:21 +02:00
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
2017-01-21 22:49:08 +01:00
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 0;
root /home/mastodon/live/public;
2017-04-11 17:48:27 +02:00
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";
2017-01-21 22:49:08 +01:00
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;
2017-04-11 17:48:27 +02:00
proxy_set_header Proxy "";
2017-01-21 22:49:08 +01:00
proxy_pass_header Server;
proxy_pass http://localhost: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;
2017-04-11 17:48:27 +02:00
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;
}
2017-01-21 22:49:08 +01:00
error_page 500 501 502 503 504 /500.html;
}
```
## Apache
Setting up Mastodon behind Apache is possible as well, although you will need to enable [mod_proxy_wstunnel](https://httpd.apache.org/docs/trunk/mod/mod_proxy_wstunnel.html) beforehand. The configuration is then pretty straightforward.
```
<VirtualHost *:80>
ServerAdmin contact@example.com
ServerName example.com
Redirect Permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin contact@example.com
ServerName example.com
DocumentRoot /home/mastodon/live/public/
Header add Strict-Transport-Security "max-age=31536000"
SSLEngine on
SSLProtocol -all +TLSv1.2
SSLHonorCipherOrder on
SSLCipherSuite EECDH+AESGCM:AES256+EECDH:AES128+EECDH
SSLCertificateFile example.pem
SSLCertificateKeyFile example.key
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass /500.html !
ProxyPass /oops.png !
ProxyPass /api/v1/streaming/ ws://localhost:4000/
ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
ErrorDocument 500 /500.html
ErrorDocument 501 /500.html
ErrorDocument 502 /500.html
ErrorDocument 503 /500.html
ErrorDocument 504 /500.html
</VirtualHost>
```
2017-01-21 22:49:08 +01:00
## Running in production without Docker
It is recommended to create a special user for mastodon on the server (you could call the user `mastodon`), though remember to disable outside login for it. You should only be able to get into that user through `sudo su - mastodon`.
## General dependencies
sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file git curl
2017-01-21 22:49:08 +01:00
curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
2017-04-08 04:59:07 +02:00
sudo apt-get install nodejs
2017-04-08 04:59:07 +02:00
2017-01-21 22:49:08 +01:00
sudo npm install -g yarn
## Redis
sudo apt-get install redis-server redis-tools
## Postgres
sudo apt-get install postgresql postgresql-contrib
Setup a user and database for Mastodon:
sudo su - postgres
psql
In the prompt:
CREATE USER mastodon CREATEDB;
\q
2017-01-21 22:49:08 +01:00
## Rbenv
It is recommended to use rbenv (exclusively from the `mastodon` user) to install the desired Ruby version. Follow the guides to [install rbenv][1] and [rbenv-build][2] (I recommend checking the [prerequisites][3] for your system on the rbenv-build project and installing them beforehand, obviously outside the unprivileged `mastodon` user)
[1]: https://github.com/rbenv/rbenv#installation
[2]: https://github.com/rbenv/ruby-build#installation
[3]: https://github.com/rbenv/ruby-build/wiki#suggested-build-environment
2017-04-11 17:48:27 +02:00
Then once `rbenv` is ready, run `rbenv install 2.4.1` to install the Ruby version for Mastodon.
2017-01-21 22:49:08 +01:00
## Git
You need the `git-core` package installed on your system. If it is so, from the `mastodon` user:
cd ~
2017-04-04 23:45:29 +02:00
git clone https://github.com/tootsuite/mastodon.git live
2017-01-21 22:49:08 +01:00
cd live
Then you can proceed to install project dependencies:
gem install bundler
bundle install --deployment --without development test
yarn install
## Configuration
Then you have to configure your instance:
cp .env.production.sample .env.production
nano .env.production
Fill in the important data, like host/port of the redis database, host/port/username/password of the postgres database, your domain name, SMTP details (e.g. from Mailgun or equivalent transactional e-mail service, many have free tiers), whether you intend to use SSL, etc. If you need to generate secrets, you can use:
rake secret
2017-04-04 15:57:37 +02:00
To get a random string. If you are setting up on one single server (most likely), then `REDIS_HOST` is localhost and `DB_HOST` is `/var/run/postgresql`, `DB_USER` is `mastodon` and `DB_NAME` is `mastodon_production` while `DB_PASS` is empty because this setup will use the ident authentication method (system user "mastodon" maps to postgres user "mastodon").
2017-01-21 22:49:08 +01:00
## Setup
And setup the database for the first time, this will create the tables and basic data:
RAILS_ENV=production bundle exec rails db:setup
Finally, pre-compile all CSS and JavaScript files:
RAILS_ENV=production bundle exec rails assets:precompile
## Systemd
Example systemd configuration for the web workers, to be placed in `/etc/systemd/system/mastodon-web.service`:
```systemd
[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
```
Example systemd configuration for the background workers, to be placed in `/etc/systemd/system/mastodon-sidekiq.service`:
```systemd
[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
2017-01-21 22:49:08 +01:00
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
```
Example systemd configuration file for the streaming API, to be placed in `/etc/systemd/system/mastodon-streaming.service`:
```systemd
[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
```
2017-04-03 00:10:51 +02:00
This allows you to `sudo systemctl enable /etc/systemd/system/mastodon-*.service` and `sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service` to get things going.
2017-01-21 22:49:08 +01:00
## Cronjobs
2017-04-13 06:57:04 +02:00
There are several tasks that should be run once a day to ensure that mastodon is
running smoothly. As your mastodon user run `crontab -e` and enter the following
2017-01-21 22:49:08 +01:00
2017-04-13 06:57:04 +02:00
```
RAILS_ENV=production
2017-04-13 19:28:57 +02:00
@daily cd /home/mastodon/live && /home/mastodon/.rbenv/shims/bundle exec rake mastodon:media:clear > /dev/null
2017-04-13 06:57:04 +02:00
@daily cd /home/mastodon/live && /home/mastodon/.rbenv/shims/bundle exec rake mastodon:push:refresh > /dev/null
@daily cd /home/mastodon/live && /home/mastodon/.rbenv/shims/bundle exec rake mastodon:feeds:clear > /dev/null
```
2017-01-21 22:49:08 +01:00
## Things to look out for when upgrading Mastodon
You can upgrade Mastodon with a `git pull` from the repository directory. You may need to run:
- `RAILS_ENV=production bundle exec rails db:migrate`
- `RAILS_ENV=production bundle exec rails assets:precompile`
Depending on which files changed, e.g. if anything in the `/db/` or `/app/assets` directory changed, respectively. Also, Mastodon runs in memory, so you need to restart it before you see any changes. If you're using systemd, that would be:
sudo systemctl restart mastodon-*.service