]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - doc/md/Server-configuration.md
Merge pull request #896 from ArthurHoaro/hotfix/firefox-social-subdir
[github/shaarli/Shaarli.git] / doc / md / Server-configuration.md
1 *Example virtual host configurations for popular web servers*
2
3 - [Apache](#apache)
4 - [Nginx](#nginx)
5
6 ## Prerequisites
7 ### Shaarli
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
14 ### HTTPS, TLS and self-signed certificates
15 Related guides:
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)
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
21 If 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
26 See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
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!
37 This configuration will log both Apache and PHP errors, which may prove useful to identify server configuration errors.
38
39 See:
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/)
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)
72 See [Server-side TLS](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache) (Mozilla).
73
74 ```apache
75 <VirtualHost *:443>
76 ServerName shaarli.my-domain.org
77 DocumentRoot /absolute/path/to/shaarli/
78
79 SSLEngine on
80 SSLCertificateFile /absolute/path/to/the/website/certificate.pem
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
104 ### .htaccess
105
106 Shaarli 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
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.
109
110 Apache 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.
111
112 ## LightHttpd
113
114 ## Nginx
115 ### Foreword
116 Nginx 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.
117
118 Required packages:
119 - [nginx](http://nginx.org)
120 - [php-fpm](http://php-fpm.org) - PHP FastCGI Process Manager
121
122 Official documentation:
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)
126
127 Community resources:
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)
130
131 ### Common setup
132 Once 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
138 On 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
142 On 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
146 For all following configuration examples, this user/group pair will be used:
147 - `user:group = john:users`,
148
149 which corresponds to the following service configuration:
150
151 ```ini
152 ; /etc/php/php-fpm.conf
153 user = john
154 group = users
155
156 [...]
157 listen.owner = john
158 listen.group = users
159 ```
160
161 ```nginx
162 # /etc/nginx/nginx.conf
163 user john users;
164
165 http {
166 [...]
167 }
168 ```
169
170 ### (Optional) Increase the maximum file upload size
171 Some 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
173 To increase upload size, you will need to modify both nginx and PHP configuration:
174
175 ```nginx
176 # /etc/nginx/nginx.conf
177
178 http {
179 [...]
180
181 client_max_body_size 10m;
182
183 [...]
184 }
185 ```
186
187 ```ini
188 # /etc/php5/fpm/php.ini
189
190 [...]
191 post_max_size = 10M
192 [...]
193 upload_max_filesize = 10M
194 ```
195
196 ### Minimal
197 _WARNING: Use for development only!_
198
199 ```nginx
200 user john users;
201 worker_processes 1;
202 events {
203 worker_connections 1024;
204 }
205
206 http {
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/ {
222 try_files $uri /shaarli/index.php$is_args$args;
223 access_log /var/log/nginx/shaarli.access.log;
224 error_log /var/log/nginx/shaarli.error.log;
225 }
226
227 location ~ (index)\.php$ {
228 try_files $uri =404;
229 fastcgi_split_path_info ^(.+\.php)(/.+)$;
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
239 The 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
246 To solve this, we will split Nginx configuration in several parts, that will be included when needed:
247
248 ```nginx
249 # /etc/nginx/deny.conf
250 location ~ /\. {
251 # deny access to dotfiles
252 access_log off;
253 log_not_found off;
254 deny all;
255 }
256
257 location ~ ~$ {
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
267 location ~ (index)\.php$ {
268 # Slim - split URL path into (script_filename, path_info)
269 try_files $uri =404;
270 fastcgi_split_path_info ^(.+\.php)(/.+)$;
271
272 # filter and proxy PHP requests to PHP-FPM
273 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
274 fastcgi_index index.php;
275 include fastcgi.conf;
276 }
277
278 location ~ \.php$ {
279 # deny access to all other PHP scripts
280 deny all;
281 }
282 ```
283
284 ```nginx
285 # /etc/nginx/static_assets.conf
286 location ~* \.(?: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
295 [...]
296
297 http {
298 [...]
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/ {
310 # Slim - rewrite URLs
311 try_files $uri /shaarli/index.php$is_args$args;
312
313 access_log /var/log/nginx/shaarli.access.log;
314 error_log /var/log/nginx/shaarli.error.log;
315 }
316
317 location = /shaarli/favicon.ico {
318 # serve the Shaarli favicon from its custom location
319 alias /var/www/shaarli/images/favicon.ico;
320 }
321
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
345 Assuming 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
349 [...]
350
351 http {
352 [...]
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/ {
375 # Slim - rewrite URLs
376 try_files $uri /index.php$is_args$args;
377
378 access_log /var/log/nginx/shaarli.access.log;
379 error_log /var/log/nginx/shaarli.error.log;
380 }
381
382 location = /shaarli/favicon.ico {
383 # serve the Shaarli favicon from its custom location
384 alias /var/www/shaarli/images/favicon.ico;
385 }
386
387 include deny.conf;
388 include static_assets.conf;
389 include php.conf;
390 }
391 }
392 ```