]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - support/doc/production.md
Import videos in the correct order
[github/Chocobozzz/PeerTube.git] / support / doc / production.md
1 # Production guide
2
3 * [Installation](#installation)
4 * [Upgrade](#upgrade)
5
6 ## Installation
7
8 **Please don't install PeerTube for production on a small device behind a low bandwidth connection because it could slow down the fediverse.**
9
10 ### Dependencies
11
12 Follow the steps of the [dependencies guide](dependencies.md).
13
14 ### PeerTube user
15
16 Create a `peertube` user with `/var/www/peertube` home:
17
18 ```
19 $ sudo useradd -m -d /var/www/peertube -s /bin/bash -p peertube peertube
20 ```
21
22 Set its password:
23 ```
24 $ sudo passwd peertube
25 ```
26
27 ### Database
28
29 Create the production database and a peertube user inside PostgreSQL:
30
31 ```
32 $ sudo -u postgres createuser -P peertube
33 $ sudo -u postgres createdb -O peertube peertube_prod
34 ```
35
36 ### Prepare PeerTube directory
37
38 Fetch the latest tagged version of Peertube
39 ```
40 $ VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"
41 ```
42
43 Open the peertube directory, create a few required directories
44 ```
45 $ cd /var/www/peertube && sudo -u peertube mkdir config storage versions && cd versions
46 ```
47
48 Download the latest version of the Peertube client, unzip it and remove the zip
49 ```
50 $ sudo -u peertube wget -q "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip"
51 $ sudo -u peertube unzip peertube-${VERSION}.zip && sudo -u peertube rm peertube-${VERSION}.zip
52 ```
53
54 Install Peertube
55 ```
56 $ cd ../ && sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
57 $ cd ./peertube-latest && sudo -H -u peertube yarn install --production --pure-lockfile
58 ```
59
60 ### PeerTube configuration
61
62 Copy example configuration:
63
64 ```
65 $ cd /var/www/peertube && sudo -u peertube cp peertube-latest/config/production.yaml.example config/production.yaml
66 ```
67
68 Then edit the `config/production.yaml` file according to your webserver
69 configuration.
70
71 ### Webserver
72
73 We only provide official configuration files for Nginx.
74
75 Copy the nginx configuration template:
76
77 ```
78 $ sudo cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertube
79 ```
80
81 Then modify the webserver configuration file. Please pay attention to the `alias` keys of the static locations.
82 It should correspond to the paths of your storage directories (set in the configuration file inside the `storage` key).
83
84 ```
85 $ sudo vim /etc/nginx/sites-available/peertube
86 ```
87
88 Your Mileage May Vary, but what follows is an example of configuration for nginx with a certificate made via `certbot` ([other utilities exist](https://letsencrypt.org/docs/client-options/)):
89
90 ```
91 server {
92 listen 80;
93 listen [::]:80;
94 server_name peertube.example.com;
95
96 access_log /var/log/nginx/peertube.example.com.access.log;
97 error_log /var/log/nginx/peertube.example.com.error.log;
98
99 rewrite ^ https://$server_name$request_uri? permanent;
100 }
101
102 server {
103 listen 443 ssl http2;
104 listen [::]:443 ssl http2;
105 server_name peertube.example.com;
106
107 # For example with Let's Encrypt (you need a certificate to run https)
108 ssl_certificate /etc/letsencrypt/live/peertube.example.com/fullchain.pem;
109 ssl_certificate_key /etc/letsencrypt/live/peertube.example.com/privkey.pem;
110
111 # Security hardening (as of 11/02/2018)
112 ssl_protocols TLSv1.3, TLSv1.2;# TLSv1.3 requires nginx >= 1.13.0 else use only TLSv1.2
113 ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
114 ssl_prefer_server_ciphers on;
115 ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
116 ssl_session_timeout 10m;
117 ssl_session_cache shared:SSL:10m;
118 ssl_session_tickets off; # Requires nginx >= 1.5.9
119 ssl_stapling on; # Requires nginx >= 1.3.7
120 ssl_stapling_verify on; # Requires nginx => 1.3.7
121 resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
122 resolver_timeout 5s;
123 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
124 add_header X-Frame-Options DENY;
125 add_header X-Content-Type-Options nosniff;
126 add_header X-XSS-Protection "1; mode=block";
127 add_header X-Robots-Tag none;
128
129 access_log /var/log/nginx/peertube.example.com.access.log;
130 error_log /var/log/nginx/peertube.example.com.error.log;
131
132 location ^~ '/.well-known/acme-challenge' {
133 default_type "text/plain";
134 root /var/www/certbot;
135 }
136
137 location ~ ^/client/(.*\.(js|css|woff2|otf|ttf|woff|eot))$ {
138 add_header Cache-Control "public, max-age=31536000, immutable";
139
140 alias /var/www/peertube/peertube-latest/client/dist/$1;
141 }
142
143 location ~ ^/static/(thumbnails|avatars)/(.*)$ {
144 add_header Cache-Control "public, max-age=31536000, immutable";
145
146 alias /var/www/peertube/storage/$1/$2;
147 }
148
149 location / {
150 proxy_pass http://localhost:9000;
151 proxy_set_header X-Real-IP $remote_addr;
152 proxy_set_header Host $host;
153 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
154
155 # For the video upload
156 client_max_body_size 2G;
157 proxy_connect_timeout 600;
158 proxy_send_timeout 600;
159 proxy_read_timeout 600;
160 send_timeout 600;
161 }
162
163 # Bypass PeerTube webseed route for better performances
164 location /static/webseed {
165 # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
166 limit_rate 800k;
167
168 if ($request_method = 'OPTIONS') {
169 add_header 'Access-Control-Allow-Origin' '*';
170 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
171 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
172 add_header 'Access-Control-Max-Age' 1728000;
173 add_header 'Content-Type' 'text/plain charset=UTF-8';
174 add_header 'Content-Length' 0;
175 return 204;
176 }
177
178 if ($request_method = 'GET') {
179 add_header 'Access-Control-Allow-Origin' '*';
180 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
181 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
182
183 # Don't spam access log file with byte range requests
184 access_log off;
185 }
186
187 alias /var/www/peertube/storage/videos;
188 }
189
190 # Websocket tracker
191 location /tracker/socket {
192 # Peers send a message to the tracker every 15 minutes
193 # Don't close the websocket before this time
194 proxy_read_timeout 1200s;
195 proxy_set_header Upgrade $http_upgrade;
196 proxy_set_header Connection "upgrade";
197 proxy_http_version 1.1;
198 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
199 proxy_set_header Host $host;
200 proxy_pass http://localhost:9000;
201 }
202 }
203 ```
204
205 To generate the certificate for your domain as required to make https work, you have two alternatives (note that the second command modifies itself the Nginx configuration to point the concerned server blocks to its certificate):
206
207 ```
208 $ sudo certbot --authenticator standalone certonly -d peertube.example.com && nginx -t && systemctl reload nginx
209 ```
210
211 ```
212 $ sudo certbot --authenticator standalone --installer nginx --post-hook "nginx -t && systemctl reload nginx"
213 ```
214
215 Remember your certificate will expire in 90 days, and thus needs renewal.
216
217 Activate the configuration file:
218
219 ```
220 $ sudo ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertube
221 $ sudo systemctl reload nginx
222 ```
223
224 ### Systemd
225
226 Copy the SystemD configuration template:
227
228 ```
229 $ sudo cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/
230 ```
231
232 Update the service file:
233
234 ```
235 $ sudo vim /etc/systemd/system/peertube.service
236 ```
237
238 It should look like this:
239
240 ```
241 [Unit]
242 Description=PeerTube daemon
243 After=network.target
244
245 [Service]
246 Type=simple
247 Environment=NODE_ENV=production
248 Environment=NODE_CONFIG_DIR=/var/www/peertube/config
249 User=peertube
250 Group=peertube
251 ExecStart=/usr/bin/npm start
252 WorkingDirectory=/var/www/peertube/peertube-latest
253 StandardOutput=syslog
254 StandardError=syslog
255 SyslogIdentifier=peertube
256 Restart=always
257
258 [Install]
259 WantedBy=multi-user.target
260 ```
261
262
263 Tell systemd to reload its config:
264
265 ```
266 $ sudo systemctl daemon-reload
267 ```
268
269 If you want to start PeerTube on boot:
270
271 ```
272 $ sudo systemctl enable peertube
273 ```
274
275 ### Run
276
277 ```
278 $ sudo systemctl start peertube
279 $ sudo journalctl -feu peertube
280 ```
281
282 ### Administrator
283
284 The administrator password is automatically generated and can be found in the
285 logs. You can set another password with:
286
287 ```
288 $ cd /var/www/peertube/peertube-latest && NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u root
289 ```
290
291 ## Upgrade
292
293 #### Auto (minor versions only)
294
295 ```
296 $ cd /var/www/peertube/peertube-latest/scripts && sudo -u peertube ./upgrade.sh
297 $ diff /var/www/peertube/versions/peertube-${VERSION}/config/production.yaml.example /var/www/peertube/config/production.yaml
298 $ sudo systemctl restart peertube && sudo journalctl -fu peertube
299 ```
300
301 #### Manually
302
303 Make a SQL backup
304
305 ```
306 $ SQL_BACKUP_PATH="backup/sql-peertube_prod-$(date -Im).bak" && \
307 cd /var/www/peertube && sudo -u peertube mkdir -p backup && \
308 sudo pg_dump -U peertube -W -h localhost -F c peertube_prod -f "$SQL_BACKUP_PATH"
309 ```
310
311 Fetch the latest tagged version of Peertube:
312
313 ```
314 $ VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"
315 ```
316
317 Download the new version and unzip it:
318
319 ```
320 $ cd /var/www/peertube/versions && \
321 sudo -u peertube wget -q "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip" && \
322 sudo -u peertube unzip -o peertube-${VERSION}.zip && \
323 sudo -u peertube rm peertube-${VERSION}.zip
324 ```
325
326 Install node dependencies:
327
328 ```
329 $ cd /var/www/peertube/versions/peertube-${VERSION} && \
330 sudo -u peertube yarn install --production --pure-lockfile
331 ```
332
333 Copy new configuration defaults values and update your configuration file:
334
335 ```
336 $ sudo -u peertube cp /var/www/peertube/versions/peertube-${VERSION}/config/default.yaml /var/www/peertube/config/default.yaml
337 $ diff /var/www/peertube/versions/peertube-${VERSION}/config/production.yaml.example /var/www/peertube/config/production.yaml
338 ```
339
340 Change the link to point to the latest version:
341
342 ```
343 $ cd /var/www/peertube && \
344 sudo rm ./peertube-latest && \
345 sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
346 ```
347
348
349 Restart PeerTube:
350 ```
351 $ sudo systemctl restart peertube
352 ```
353
354 ### Things went wrong?
355
356 Change `peertube-latest` destination to the previous version and restore your SQL backup:
357
358 ```
359 $ OLD_VERSION="v0.42.42" && SQL_BACKUP_PATH="backup/sql-peertube_prod-2018-01-19T10:18+01:00.bak" && \
360 cd /var/www/peertube && rm ./peertube-latest && \
361 sudo -u peertube ln -s "versions/peertube-$OLD_VERSION" peertube-latest && \
362 pg_restore -U peertube -W -h localhost -c -d peertube_prod "$SQL_BACKUP_PATH"
363 sudo systemctl restart peertube
364 ```