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