]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - doc/md/Server-configuration.md
Generate HTML documentation using MkDocs (WIP)
[github/shaarli/Shaarli.git] / doc / md / Server-configuration.md
CommitLineData
992af0b9
V
1*Example virtual host configurations for popular web servers*
2
53ed6d7d 3- [Apache](#apache)
4- [Nginx](#nginx)
992af0b9
V
5
6## Prerequisites
5409ade2 7### Shaarli
992af0b9
V
8* Shaarli is installed in a directory readable/writeable by the user
9* the correct read/write permissions have been granted to the web server _user and/or group_
10* for HTTPS / SSL:
11 * a key pair (public, private) and a certificate have been generated
12 * the appropriate server SSL extension is installed and active
13
5409ade2 14### HTTPS, TLS and self-signed certificates
992af0b9 15Related guides:
53ed6d7d 16* [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)
17* [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
5409ade2
A
18* Generate a self-signed certificate (will trigger browser warnings) with apache2: `make-ssl-cert generate-default-snakeoil --force-overwrite` will create `/etc/ssl/certs/ssl-cert-snakeoil.pem` and `/etc/ssl/private/ssl-cert-snakeoil.key`
19
20### Proxies
21If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:
22- `X-Forwarded-Proto`;
23- `X-Forwarded-Host`;
24- `X-Forwarded-For`.
25
53ed6d7d 26See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
992af0b9
V
27
28## Apache
29### Minimal
30```apache
31<VirtualHost *:80>
32 ServerName shaarli.my-domain.org
33 DocumentRoot /absolute/path/to/shaarli/
34</VirtualHost>
35```
36### Debug - Log all the things!
37This configuration will log both Apache and PHP errors, which may prove useful to identify server configuration errors.
38
39See:
53ed6d7d 40* [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)
41* [PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)
992af0b9
V
42
43```apache
44<VirtualHost *:80>
45 ServerName shaarli.my-domain.org
46 DocumentRoot /absolute/path/to/shaarli/
47
48 LogLevel warn
49 ErrorLog /var/log/apache2/shaarli-error.log
50 CustomLog /var/log/apache2/shaarli-access.log combined
51
52 php_flag log_errors on
53 php_flag display_errors on
54 php_value error_reporting 2147483647
55 php_value error_log /var/log/apache2/shaarli-php-error.log
56</VirtualHost>
57```
58
59### Standard - Keep access and error logs
60```apache
61<VirtualHost *:80>
62 ServerName shaarli.my-domain.org
63 DocumentRoot /absolute/path/to/shaarli/
64
65 LogLevel warn
66 ErrorLog /var/log/apache2/shaarli-error.log
67 CustomLog /var/log/apache2/shaarli-access.log combined
68</VirtualHost>
69```
70
71### Paranoid - Redirect HTTP (:80) to HTTPS (:443)
53ed6d7d 72See [Server-side TLS](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache) (Mozilla).
992af0b9
V
73
74```apache
75<VirtualHost *:443>
76 ServerName shaarli.my-domain.org
77 DocumentRoot /absolute/path/to/shaarli/
78
79 SSLEngine on
5409ade2 80 SSLCertificateFile /absolute/path/to/the/website/certificate.pem
992af0b9
V
81 SSLCertificateKeyFile /absolute/path/to/the/website/key.key
82
83 <Directory /absolute/path/to/shaarli/>
84 AllowOverride All
85 Options Indexes FollowSymLinks MultiViews
86 Order allow,deny
87 allow from all
88 </Directory>
89
90 LogLevel warn
91 ErrorLog /var/log/apache2/shaarli-error.log
92 CustomLog /var/log/apache2/shaarli-access.log combined
93</VirtualHost>
94<VirtualHost *:80>
95 ServerName shaarli.my-domain.org
96 Redirect 301 / https://shaarli.my-domain.org
97
98 LogLevel warn
99 ErrorLog /var/log/apache2/shaarli-error.log
100 CustomLog /var/log/apache2/shaarli-access.log combined
101</VirtualHost>
102```
103
3cc8c898
A
104### .htaccess
105
106Shaarli use `.htaccess` Apache files to deny access to files that shouldn't be directly accessed (datastore, config, etc.). You need the directive `AllowOverride All` in your virtual host configuration for them to work.
107
53ed6d7d 108**Warning**: If you use Apache 2.2 or lower, you need [mod_version](https://httpd.apache.org/docs/current/mod/mod_version.html) to be installed and enabled.
b230bf20
A
109
110Apache module `mod_rewrite` **must** be enabled to use the REST API. URL rewriting rules for the Slim microframework are stated in the root `.htaccess` file.
3cc8c898 111
992af0b9
V
112## LightHttpd
113
114## Nginx
115### Foreword
53ed6d7d 116Nginx does not natively interpret PHP scripts; to this effect, we will run a [FastCGI](https://en.wikipedia.org/wiki/FastCGI) service, to which Nginx's FastCGI module will proxy all requests to PHP resources.
992af0b9
V
117
118Required packages:
53ed6d7d 119- [nginx](http://nginx.org)
120- [php-fpm](http://php-fpm.org) - PHP FastCGI Process Manager
992af0b9
V
121
122Official documentation:
53ed6d7d 123- [Beginner's guide](http://nginx.org/en/docs/beginners_guide.html)
124- [ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
125- [Pitfalls](http://wiki.nginx.org/Pitfalls)
992af0b9
V
126
127Community resources:
53ed6d7d 128- [Server-side TLS (Nginx)](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx) (Mozilla)
129- [PHP configuration examples](http://kbeezie.com/nginx-configuration-examples/) (Karl Blessing)
992af0b9
V
130
131### Common setup
132Once Nginx and PHP-FPM are installed, we need to ensure:
133- Nginx and PHP-FPM are running using the _same user and group_
134- both these user and group have
135 - `read` permissions for Shaarli resources
136 - `execute` permissions for Shaarli directories _AND_ their parent directories
137
138On a production server:
139- `user:group` will likely be `http:http`, `www:www` or `www-data:www-data`
140- files will be located under `/var/www`, `/var/http` or `/usr/share/nginx`
141
142On a development server:
143- files may be located in a user's home directory
144- in this case, make sure both Nginx and PHP-FPM are running as the local user/group!
145
3cc8c898 146For all following configuration examples, this user/group pair will be used:
992af0b9
V
147- `user:group = john:users`,
148
149which corresponds to the following service configuration:
150
151```ini
152; /etc/php/php-fpm.conf
153user = john
154group = users
155
53ed6d7d 156[...]
992af0b9
V
157listen.owner = john
158listen.group = users
159```
160
161```nginx
162# /etc/nginx/nginx.conf
163user john users;
164
165http {
53ed6d7d 166 [...]
992af0b9
V
167}
168```
169
3cc8c898
A
170### (Optional) Increase the maximum file upload size
171Some bookmark dumps generated by web browsers can be _huge_ due to the presence of Base64-encoded images and favicons, as well as extra verbosity when nesting links in (sub-)folders.
172
173To increase upload size, you will need to modify both nginx and PHP configuration:
174
175```nginx
176# /etc/nginx/nginx.conf
177
178http {
53ed6d7d 179 [...]
3cc8c898
A
180
181 client_max_body_size 10m;
182
53ed6d7d 183 [...]
3cc8c898
A
184}
185```
186
187```ini
188# /etc/php5/fpm/php.ini
189
53ed6d7d 190[...]
3cc8c898 191post_max_size = 10M
53ed6d7d 192[...]
3cc8c898
A
193upload_max_filesize = 10M
194```
195
992af0b9
V
196### Minimal
197_WARNING: Use for development only!_
198
199```nginx
200user john users;
201worker_processes 1;
202events {
203 worker_connections 1024;
204}
205
206http {
207 include mime.types;
208 default_type application/octet-stream;
209 keepalive_timeout 20;
210
211 index index.html index.php;
212
213 server {
214 listen 80;
215 server_name localhost;
216 root /home/john/web;
217
218 access_log /var/log/nginx/access.log;
219 error_log /var/log/nginx/error.log;
220
221 location /shaarli/ {
b230bf20 222 try_files $uri /shaarli/index.php$is_args$args;
992af0b9
V
223 access_log /var/log/nginx/shaarli.access.log;
224 error_log /var/log/nginx/shaarli.error.log;
225 }
226
227 location ~ (index)\.php$ {
b230bf20
A
228 try_files $uri =404;
229 fastcgi_split_path_info ^(.+\.php)(/.+)$;
992af0b9
V
230 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
231 fastcgi_index index.php;
232 include fastcgi.conf;
233 }
234 }
235}
236```
237
238### Modular
239The previous setup is sufficient for development purposes, but has several major caveats:
240- every content that does not match the PHP rule will be sent to client browsers:
241 - dotfiles - in our case, `.htaccess`
242 - temporary files, e.g. Vim or Emacs files: `index.php~`
243- asset / static resource caching is not optimized
244- if serving several PHP sites, there will be a lot of duplication: `location /shaarli/`, `location /mysite/`, etc.
245
246To solve this, we will split Nginx configuration in several parts, that will be included when needed:
247
248```nginx
249# /etc/nginx/deny.conf
250location ~ /\. {
251 # deny access to dotfiles
252 access_log off;
253 log_not_found off;
254 deny all;
255}
256
257location ~ ~$ {
258 # deny access to temp editor files, e.g. "script.php~"
259 access_log off;
260 log_not_found off;
261 deny all;
262}
263```
264
265```nginx
266# /etc/nginx/php.conf
267location ~ (index)\.php$ {
b230bf20
A
268 # Slim - split URL path into (script_filename, path_info)
269 try_files $uri =404;
270 fastcgi_split_path_info ^(.+\.php)(/.+)$;
271
f8b936e7 272 # filter and proxy PHP requests to PHP-FPM
992af0b9
V
273 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
274 fastcgi_index index.php;
275 include fastcgi.conf;
276}
f8b936e7
V
277
278location ~ \.php$ {
279 # deny access to all other PHP scripts
280 deny all;
281}
992af0b9
V
282```
283
284```nginx
285# /etc/nginx/static_assets.conf
286location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
287 expires max;
288 add_header Pragma public;
289 add_header Cache-Control "public, must-revalidate, proxy-revalidate";
290}
291```
292
293```nginx
294# /etc/nginx/nginx.conf
53ed6d7d 295[...]
992af0b9
V
296
297http {
53ed6d7d 298 [...]
992af0b9
V
299
300 root /home/john/web;
301 access_log /var/log/nginx/access.log;
302 error_log /var/log/nginx/error.log;
303
304 server {
305 # virtual host for a first domain
306 listen 80;
307 server_name my.first.domain.org;
308
309 location /shaarli/ {
b230bf20
A
310 # Slim - rewrite URLs
311 try_files $uri /shaarli/index.php$is_args$args;
312
992af0b9
V
313 access_log /var/log/nginx/shaarli.access.log;
314 error_log /var/log/nginx/shaarli.error.log;
315 }
316
3cc8c898
A
317 location = /shaarli/favicon.ico {
318 # serve the Shaarli favicon from its custom location
319 alias /var/www/shaarli/images/favicon.ico;
320 }
321
992af0b9
V
322 include deny.conf;
323 include static_assets.conf;
324 include php.conf;
325 }
326
327 server {
328 # virtual host for a second domain
329 listen 80;
330 server_name second.domain.com;
331
332 location /minigal/ {
333 access_log /var/log/nginx/minigal.access.log;
334 error_log /var/log/nginx/minigal.error.log;
335 }
336
337 include deny.conf;
338 include static_assets.conf;
339 include php.conf;
340 }
341}
342```
343
344### Redirect HTTP to HTTPS
345Assuming you have generated a (self-signed) key and certificate, and they are located under `/home/john/ssl/localhost.{key,crt}`, it is pretty straightforward to set an HTTP (:80) to HTTPS (:443) redirection to force SSL/TLS usage.
346
347```nginx
348# /etc/nginx/nginx.conf
53ed6d7d 349[...]
992af0b9
V
350
351http {
53ed6d7d 352 [...]
992af0b9
V
353
354 index index.html index.php;
355
356 root /home/john/web;
357 access_log /var/log/nginx/access.log;
358 error_log /var/log/nginx/error.log;
359
360 server {
361 listen 80;
362 server_name localhost;
363
364 return 301 https://localhost$request_uri;
365 }
366
367 server {
368 listen 443 ssl;
369 server_name localhost;
370
371 ssl_certificate /home/john/ssl/localhost.crt;
372 ssl_certificate_key /home/john/ssl/localhost.key;
373
374 location /shaarli/ {
b230bf20
A
375 # Slim - rewrite URLs
376 try_files $uri /index.php$is_args$args;
377
992af0b9
V
378 access_log /var/log/nginx/shaarli.access.log;
379 error_log /var/log/nginx/shaarli.error.log;
380 }
381
3cc8c898
A
382 location = /shaarli/favicon.ico {
383 # serve the Shaarli favicon from its custom location
384 alias /var/www/shaarli/images/favicon.ico;
385 }
386
992af0b9
V
387 include deny.conf;
388 include static_assets.conf;
389 include php.conf;
390 }
391}
392```