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