Release 0.8.0
[phorkie.git] / README.rst
1 ****************************
2 phorkie - Git based pastebin
3 ****************************
4 Self-hosted pastebin software written in PHP.
5 Pastes are editable, may have multiple files and are stored in git repositories.
6
7 `Homepage <https://cweiske.de/phorkie.htm>`__
8 | `Bug tracker <https://github.com/cweiske/phorkie/issues>`__
9 | `Git repository <https://git.cweiske.de/phorkie.git>`__
10 ยท `GitHub mirror <https://github.com/cweiske/phorkie/>`__
11
12 .. contents:: Table of Contents
13
14 ========
15 Features
16 ========
17 - every paste is a git repository
18
19   - repositories can be cloned
20   - clone url can be displayed
21   - remote pastes can be forked (rel="vcs-git" and gist.github.com)
22   - single click forking of forks on different servers to your own
23 - paste editing
24
25   - add new files
26   - delete existing files
27   - replace file with upload
28 - embedding of pastes in your blog (via JavaScript or oEmbed)
29 - multiple files in one paste
30   - option to edit single files in a multi-file paste
31 - syntax highlighting with GeSHi
32 - rST and Markdown rendering
33 - image upload + display
34 - OpenID authentication
35 - external tool support
36
37   - xmllint
38   - php syntax check
39 - history in the sidebar
40
41   - old files can be downloaded easily
42 - search across pastes: description, file names and file content
43
44   - options: quoting, logical and, or, not, partial words
45 - webhook support - get notified when pastes are created, edited or deleted
46 - atom feed for new and updated pastes
47 - notifies remote instances via linkbacks when a paste has been forked
48 - text file detection for unknown file types
49
50
51 ========
52 Download
53 ========
54 phorkie is released as self-contained ``.phar`` file that includes
55 all dependencies, as well as a normal zip file.
56
57 .. LATESTRELEASE
58
59 See `phorkie downloads page <http://cweiske.de/phorkie-download.htm>`_
60 for all released versions.
61
62
63 ============
64 Installation
65 ============
66
67 .phar
68 =====
69 Download ``phorkie-0.8.0.phar`` and put it in your web server's document root
70 directory.
71
72 No further setup needed.
73
74 .. note:: Only valid if your webserver is configured to let
75    PHP handle ``.phar`` files.
76
77    Unfortunately, no Linux distribution has this activated by default.
78    You can do it yourself, though - see
79    `Enable .phar handling in your web server`__.
80
81 .. warning:: PHP has some bugs in its .phar handling code (e.g. with FPM).
82
83    So currently, the ``.phar`` option is considered experimental.
84
85 __ http://cweiske.de/tagebuch/phar-webserver.htm
86
87
88 Zip package
89 ===========
90 1. Unzip the phorkie release file::
91
92    $ tar xjvf phorkie-0.8.0.tar.bz2
93
94 2. Create the git directories::
95
96    $ mkdir -p www/repos/git www/repos/work
97    $ chmod og+w www/repos/git www/repos/work
98
99 3. Install dependencies_
100
101 4. Copy ``data/config.php.dist`` to ``data/config.php`` and adjust it
102    to your needs::
103
104    $ cp data/config.php.dist data/config.php
105    $ $EDITOR data/config.php
106
107    Look at ``config.default.php`` for values that you may adjust.
108
109 5. Set your web server's document root to ``/path/to/phorkie/www/``
110    Alternatively, you can add a symlink to the ``www`` folder into your
111    web server's existing document root tree (being careful to keep
112    main phorkie folder outside the document root for security purposes)
113    and ensure you set the ``baseurl`` config option appropriately. You
114    must also set the ``RewriteBase`` in the ``.htaccess`` file or adjust
115    the nginx configuration accordingly.
116
117 6. Open http://yourhost/setup in your web browser to see if everything
118    is working fine.
119
120 7. Go to http://yourhost/
121
122 8. If you like phorkie, send a mail to `cweiske+phorkie@cweiske.de`__
123
124 __ mailto:cweiske+phorkie@cweiske.de
125
126
127 Dependencies
128 ============
129 phorkie stands on the shoulders of giants.
130
131 It requires the following programs to be installed
132 on your machine:
133
134 - Git v1.7.5 or later
135 - PHP v5.3.0 or later
136
137   - optionally the ``mbstring`` extension
138 - PEAR v1.9.2 or later
139
140 ::
141
142   $ pear install versioncontrol_git-alpha
143   $ pear install services_libravatar-alpha
144   $ pear install http_request2
145   $ pear install pager
146   $ pear install date_humandiff-alpha
147   $ pear install openid-alpha
148
149   $ pear channel-discover pear.twig-project.org
150   $ pear install twig/Twig
151
152   $ pear channel-discover pear.geshi.org
153   $ pear install geshi/geshi
154
155   $ pear channel-discover zustellzentrum.cweiske.de
156   $ pear install zz/mime_type_plaindetect-alpha
157
158   $ pear channel-discover pear.michelf.ca
159   $ pear install michelf/Markdown
160
161   $ pear channel-discover pear2.php.net
162   $ pear install pear2/pear2_services_linkback-alpha
163
164
165 You can use composer to install all dependencies automatically::
166
167   $ composer install
168
169 Note that the ``.phar`` package already contains all dependencies.
170
171
172 ======
173 Search
174 ======
175
176 phorkie makes use of an Elasticsearch__ installation, if you have one.
177
178 It is used to provide search capabilities and the list of recent pastes.
179
180 Elasticsearch version 2.0 is supported.
181
182 You have to install the `delete-by-query`__ plugin::
183
184     $ cd /usr/share/elasticsearch
185     $ bin/plugin install delete-by-query
186
187 __ http://www.elasticsearch.org/
188 __ https://www.elastic.co/guide/en/elasticsearch/plugins/2.0/plugins-delete-by-query.html
189
190
191 Setup
192 =====
193 Edit ``config.php``, setting the ``elasticsearch`` property to the HTTP URL
194 of the index, e.g. ::
195
196   http://localhost:9200/phorkie/
197
198 You must use a search namespace with Elasticsearch such as ``phorkie/``.
199 Run the index script to import all existing pastes into the index::
200
201   php scripts/index.php
202
203 That's all. Open phorkie in your browser, and you'll notice the search box
204 in the top menu.
205
206
207 Reset
208 =====
209 In case something really went wrong and you need to reset the search
210 index, run the following command::
211
212   $ curl -XDELETE http://localhost:9200/phorkie/
213   {"ok":true,"acknowledged"}
214
215 Phorkie will automatically re-index everything when ``setupcheck`` is enabled
216 in the configuration file.
217
218 You may also manually run the reindexing script with::
219
220   $ php scripts/index.php
221
222
223 =====
224 HowTo
225 =====
226
227 Make git repositories clonable
228 ==============================
229
230 HTTP
231 ----
232 By default, the pastes are clonable via ``http`` as long as the ``repos/git/``
233 directory is within the ``www/`` directory.
234
235 No further setup needed.
236
237
238 git-daemon
239 ----------
240 You may use ``git-daemon`` to provide public ``git://`` clone urls.
241 Install the ``git-daemon-run`` package on Debian/Ubuntu.
242
243 Make the repositories available by symlinking the paste repository
244 directory (``$GLOBALS['phorkie']['cfg']['repos']`` setting) into
245 ``/var/cache/git``, e.g.::
246
247   $ ln -s /home/user/www/paste/repos/git /var/cache/git/paste
248
249 Edit your ``config.php`` and set the ``$GLOBALS['phorkie']['cfg']['git']['public']``
250 setting to ``git://$yourhostname/git/paste/``.
251 The rest will be appended automatically.
252
253
254 You're on your own to setup writable repositories.
255
256
257 Protect your site with OpenID
258 =============================
259 You have the option of enabling OpenID authentication to help secure your
260 pastes on phorkie.
261 Set the ``$GLOBALS['phorkie']['auth']`` values in the
262 ``data/config.php`` file as desired.
263
264 There are two different types of security you can apply.
265 First, you can restrict to one of three ``securityLevels``:
266
267 - completely open (``0``)
268 - protection of write-enabled functions such as add, edit, etc. (``1``)
269 - full site protection (``2``)
270
271 Additionally, you can restrict your site to ``listedUsersOnly``.
272 You will need to add the individual OpenID urls to the
273 ``$GLOBALS['phorkie']['auth']['users']`` variable.
274
275
276 Get information about paste editors
277 ===================================
278 Phorkie stores the user's OpenID or IP address (when not logged in) when
279 a paste is edited.
280 It is possible to get this information for each single commit::
281
282     // IP / OpenID for the latest commit
283     $ git notes --ref=identity show
284     127.0.0.1
285
286     // show IP / OpenID for a given commit
287     $ git notes --ref=identity show 29f82a
288     http://cweiske.de/
289
290
291 Notifications via webhooks
292 ==========================
293 Depending on how you use phorkie, it might be nice to notify some other service
294 when pastes are added or updated.
295 Phorkie contains a simply mechanism to post data to a given URL which
296 you can then use as needed.
297
298 The data are json-encoded POSTed to the URLs contained in the
299 ``$GLOBALS['phorkie']['cfg']['webhooks']`` setting array, with
300 a MIME type of ``application/vnd.phorkie.webhook+json``::
301
302   {
303       'event': 'create',
304       'author': {
305           'name':'Anonymous',
306           'email': 'anonymous@phorkie',
307       },
308       'repository': {
309           'name': 'webhooktest',
310           'url': 'http://example.org/33',
311           'description': 'webhooktest',
312           'owner': {
313               'name': 'Anonymous',
314               'email': 'anonymous@phorkie',
315           }
316       }
317   }
318
319 The event may be ``create``, ``edit`` or ``delete``.
320
321
322 =================
323 Technical details
324 =================
325
326
327 URLs
328 ====
329
330 ``/``
331   Index page.
332 ``/[0-9]+``
333   Display page for paste
334 ``/[0-9]+/edit``
335   Edit the paste
336 ``/[0-9]+/edit/(.+)``
337   Edit a single file of the paste
338 ``/[0-9]+/embed``
339   JavaScript code that embeds the whole paste in a HTML page
340 ``/[0-9]+/embed/(.+)``
341   JavaScript code that embeds a single file in a HTML page
342 ``/[0-9]+/raw/(.+)``
343   Display raw file contents
344 ``/[0-9]+/tool/[a-zA-Z]+/(.+)``
345   Run a tool on the given file
346 ``/[0-9]+/rev/[a-z0-9]+``
347   Show specific revision of the paste
348 ``/[0-9]+/delete``
349   Delete the paste
350 ``/[0-9]+/doap``
351   Show DOAP document for paste
352 ``/[0-9]+/fork``
353   Create a fork of the paste
354 ``/search?q=..(&page=[0-9]+)?``
355   Search for term, with optional page
356 ``/list(/[0-9]+)?``
357   List all pastes, with optional page
358 ``/fork-remote``
359   Fork a remote URL
360 ``/help``
361   Show help page
362 ``/new``
363   Shows form for new paste
364 ``/login``
365   Login page for protecting site
366 ``/setup``
367   Check if everything is setup correctly and all dependencies are installed
368 ``/user``
369   Edit logged-in user information
370
371
372 Internal directory layout
373 =========================
374 ::
375
376   repos/
377     work/
378       1/ - work directory for paste #1
379       2/ - work directory for paste #2
380     git/
381       1.git/ - git repository for paste #1
382         description - Description for the repository
383       2.git/ - git repository for paste #2
384
385 nginx rewrites
386 ==============
387 If you use nginx, place the following lines into your ``server`` block:
388
389 ::
390
391   if (!-e $request_uri) {
392     rewrite ^/([0-9]+)$ /display.php?id=$1;
393     rewrite ^/([0-9]+)/delete$ /delete.php?id=$1;
394     rewrite ^/([0-9]+)/delete/confirm$ /delete.php?id=$1&confirm=1;
395     rewrite ^/([0-9]+)/doap$ /doap.php?id=$1;
396     rewrite ^/([0-9]+)/edit$ /edit.php?id=$1;
397     rewrite ^/([0-9]+)/edit/(.+)$ /edit.php?id=$1&file=$2;
398     rewrite ^/([0-9]+)/embed$ /embed.php?id=$1;
399     rewrite ^/([0-9]+)/embed/(.+)$ /embed.php?id=$1&file=$2;
400     rewrite ^/([0-9]+)/fork$ /fork.php?id=$1;
401     rewrite ^/([0-9]+)/raw/(.+)$ /raw.php?id=$1&file=$2;
402     rewrite ^/([0-9]+)/rev/(.+)$ /revision.php?id=$1&rev=$2;
403     rewrite ^/([0-9]+)/rev-raw/(.+)/(.+)$ /raw.php?id=$1&rev=$2&file=$3;
404     rewrite ^/([0-9]+)/tool/([^/]+)/(.+)$ /tool.php?id=$1&tool=$2&file=$3;
405
406     rewrite ^/fork-remote$ /fork-remote.php;
407     rewrite ^/help$ /help.php;
408     rewrite ^/new$ /new.php;
409
410     rewrite ^/feed/new$ /feed-new.php;
411     rewrite ^/feed/updated$ /feed-updated.php;
412
413     rewrite ^/list$ /list.php;
414     rewrite ^/list/([0-9]+)$ /list.php?page=$1;
415
416     rewrite ^/search$ /search.php;
417     rewrite ^/search/([0-9]+)$ /search.php?page=$1;
418
419     rewrite ^/login$ /login.php;
420     rewrite ^/setup$ /setup.php;
421     rewrite ^/user$ /user.php;
422   }
423
424 Lighttpd rewrites
425 =================
426
427 ::
428
429     url.rewrite-once += (
430         "^/([0-9]+)$" => "/display.php?id=$1",
431         "^/([0-9]+)/delete$" => "/delete.php?id=$1",
432         "^/([0-9]+)/delete/confirm" => "/delete.php?&id=$1&confirm=1",
433         "^/([0-9]+)/doap$" => "/doap.php?id=$1",
434         "^/([0-9]+)/edit$" => "/edit.php?id=$1",
435         "^/([0-9]+)/edit/(.+)" => "/edit.php?id=$1&file=$2",
436         "^/([0-9]+)/embed$" => "/embed.php?id=$1",
437         "^/([0-9]+)/embed/(.+)$" => "/embed.php?id=$1",
438         "^/([0-9]+)/fork$" => "/fork.php?id=$1",
439         "^/([0-9]+)/raw/(.+)$" => "/raw.php?id=$1&file=$2",
440         "^/([0-9]+)/rev/(.+)$" => "/revision.php?id=$1&rev=$2",
441         "^/([0-9]+)/rev-raw/(.+)/(.+)$" => "/raw.php?id=$1&rev=$2&file=$3",
442         "^/([0-9]+)/tool/([^/]+)/(.+)$" => "/tool.php?id=$1&tool=$2&file=$3",
443
444         "^/fork-remote$" => "/fork-remote.php",
445         "^/help$" => "/help.php",
446         "^/new$" => "/new.php",
447
448         "^/feed/new$" => "/feed-new.php",
449         "^/feed/updated$" => "/feed-updated.php",
450
451         "^/list$" => "/list.php",
452         "^/list/([0-9]+)$" => "/list.php?page=$1",
453
454         "^/search$" => "/search.php",
455         "^/search/([0-9]+)$" => "/search.php?page=$1",
456
457         "^/login$" => "/login.php",
458         "^/setup$" => "/setup.php",
459         "^/user$" => "/user.php"
460     )
461
462
463 ===========
464 Development
465 ===========
466
467 Releasing a new version
468 =======================
469
470 #. Update ``ChangeLog``, ``NEWS.rst``, ``build.xml`` and ``README.rst``.
471 #. Update local dependencies::
472
473     $ phing collectdeps
474 #. Build ``.tar.bz2`` and ``.phar`` release files with::
475
476     $ phing zip
477     $ phing phar
478 #. Test.
479 #. Tag the release in git
480 #. Run the script to update the homepage
481
482     $ cd /home/cweiske/Dev/html/cweiske.de
483     $ ./scripts/update-phorkie.sh