##// END OF EJS Templates
docs: drop odd verbose note on writeable root path...
Mads Kiilerich -
r8325:4742b8c8 default
parent child Browse files
Show More
@@ -1,662 +1,657 b''
1 .. _setup:
1 .. _setup:
2
2
3 =====
3 =====
4 Setup
4 Setup
5 =====
5 =====
6
6
7
7
8 Setting up Kallithea
8 Setting up Kallithea
9 --------------------
9 --------------------
10
10
11 Some further details to the steps mentioned in the overview.
11 Some further details to the steps mentioned in the overview.
12
12
13 Create low level configuration file
13 Create low level configuration file
14 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15
15
16 First, you will need to create a Kallithea configuration file. Run the
16 First, you will need to create a Kallithea configuration file. Run the
17 following command to do so::
17 following command to do so::
18
18
19 kallithea-cli config-create my.ini
19 kallithea-cli config-create my.ini
20
20
21 This will create the file ``my.ini`` in the current directory. This
21 This will create the file ``my.ini`` in the current directory. This
22 configuration file contains the various settings for Kallithea, e.g.
22 configuration file contains the various settings for Kallithea, e.g.
23 proxy port, email settings, usage of static files, cache, Celery
23 proxy port, email settings, usage of static files, cache, Celery
24 settings, and logging. Extra settings can be specified like::
24 settings, and logging. Extra settings can be specified like::
25
25
26 kallithea-cli config-create my.ini host=8.8.8.8 "[handler_console]" formatter=color_formatter
26 kallithea-cli config-create my.ini host=8.8.8.8 "[handler_console]" formatter=color_formatter
27
27
28 Populate the database
28 Populate the database
29 ^^^^^^^^^^^^^^^^^^^^^
29 ^^^^^^^^^^^^^^^^^^^^^
30
30
31 Next, you need to create the databases used by Kallithea. It is recommended to
31 Next, you need to create the databases used by Kallithea. It is recommended to
32 use PostgreSQL or SQLite (default). If you choose a database other than the
32 use PostgreSQL or SQLite (default). If you choose a database other than the
33 default, ensure you properly adjust the database URL in your ``my.ini``
33 default, ensure you properly adjust the database URL in your ``my.ini``
34 configuration file to use this other database. Kallithea currently supports
34 configuration file to use this other database. Kallithea currently supports
35 PostgreSQL, SQLite and MariaDB/MySQL databases. Create the database by running
35 PostgreSQL, SQLite and MariaDB/MySQL databases. Create the database by running
36 the following command::
36 the following command::
37
37
38 kallithea-cli db-create -c my.ini
38 kallithea-cli db-create -c my.ini
39
39
40 This will prompt you for a "root" path. This "root" path is the location where
40 This will first prompt you for a "root" path. This "root" path is the location
41 Kallithea will store all of its repositories on the current machine. After
41 where Kallithea will store all of its repositories on the current machine. This
42 entering this "root" path ``db-create`` will also prompt you for a username
42 location must be writable for the running Kallithea application. Next,
43 and password for the initial admin account which ``db-create`` sets
43 ``db-create`` will prompt you for a username and password for the initial admin
44 up for you.
44 account it sets up for you.
45
45
46 The ``db-create`` values can also be given on the command line.
46 The ``db-create`` values can also be given on the command line.
47 Example::
47 Example::
48
48
49 kallithea-cli db-create -c my.ini --user=nn --password=secret --email=nn@example.com --repos=/srv/repos
49 kallithea-cli db-create -c my.ini --user=nn --password=secret --email=nn@example.com --repos=/srv/repos
50
50
51 The ``db-create`` command will create all needed tables and an
51 The ``db-create`` command will create all needed tables and an
52 admin account. When choosing a root path you can either use a new
52 admin account. When choosing a root path you can either use a new
53 empty location, or a location which already contains existing
53 empty location, or a location which already contains existing
54 repositories. If you choose a location which contains existing
54 repositories. If you choose a location which contains existing
55 repositories Kallithea will add all of the repositories at the chosen
55 repositories Kallithea will add all of the repositories at the chosen
56 location to its database. (Note: make sure you specify the correct
56 location to its database. (Note: make sure you specify the correct
57 path to the root).
57 path to the root).
58
58
59 .. note:: the given path for Mercurial_ repositories **must** be write
60 accessible for the application. It's very important since
61 the Kallithea web interface will work without write access,
62 but when trying to do a push it will fail with permission
63 denied errors unless it has write access.
64
59
65 Prepare front-end files
60 Prepare front-end files
66 ^^^^^^^^^^^^^^^^^^^^^^^
61 ^^^^^^^^^^^^^^^^^^^^^^^
67
62
68 Finally, the front-end files must be prepared. This requires ``npm`` version 6
63 Finally, the front-end files must be prepared. This requires ``npm`` version 6
69 or later, which needs ``node.js`` (version 12 or later). Prepare the front-end
64 or later, which needs ``node.js`` (version 12 or later). Prepare the front-end
70 by running::
65 by running::
71
66
72 kallithea-cli front-end-build
67 kallithea-cli front-end-build
73
68
74 Running
69 Running
75 ^^^^^^^
70 ^^^^^^^
76
71
77 You are now ready to use Kallithea. To run it simply execute::
72 You are now ready to use Kallithea. To run it simply execute::
78
73
79 gearbox serve -c my.ini
74 gearbox serve -c my.ini
80
75
81 - This command runs the Kallithea server. The web app should be available at
76 - This command runs the Kallithea server. The web app should be available at
82 http://127.0.0.1:5000. The IP address and port is configurable via the
77 http://127.0.0.1:5000. The IP address and port is configurable via the
83 configuration file created in the previous step.
78 configuration file created in the previous step.
84 - Log in to Kallithea using the admin account created when running ``db-create``.
79 - Log in to Kallithea using the admin account created when running ``db-create``.
85 - The default permissions on each repository is read, and the owner is admin.
80 - The default permissions on each repository is read, and the owner is admin.
86 Remember to update these if needed.
81 Remember to update these if needed.
87 - In the admin panel you can toggle LDAP, anonymous, and permissions
82 - In the admin panel you can toggle LDAP, anonymous, and permissions
88 settings, as well as edit more advanced options on users and
83 settings, as well as edit more advanced options on users and
89 repositories.
84 repositories.
90
85
91
86
92 Internationalization (i18n support)
87 Internationalization (i18n support)
93 -----------------------------------
88 -----------------------------------
94
89
95 The Kallithea web interface is automatically displayed in the user's preferred
90 The Kallithea web interface is automatically displayed in the user's preferred
96 language, as indicated by the browser. Thus, different users may see the
91 language, as indicated by the browser. Thus, different users may see the
97 application in different languages. If the requested language is not available
92 application in different languages. If the requested language is not available
98 (because the translation file for that language does not yet exist or is
93 (because the translation file for that language does not yet exist or is
99 incomplete), English is used.
94 incomplete), English is used.
100
95
101 If you want to disable automatic language detection and instead configure a
96 If you want to disable automatic language detection and instead configure a
102 fixed language regardless of user preference, set ``i18n.enabled = false`` and
97 fixed language regardless of user preference, set ``i18n.enabled = false`` and
103 specify another language by setting ``i18n.lang`` in the Kallithea
98 specify another language by setting ``i18n.lang`` in the Kallithea
104 configuration file.
99 configuration file.
105
100
106
101
107 Using Kallithea with SSH
102 Using Kallithea with SSH
108 ------------------------
103 ------------------------
109
104
110 Kallithea supports repository access via SSH key based authentication.
105 Kallithea supports repository access via SSH key based authentication.
111 This means:
106 This means:
112
107
113 - repository URLs like ``ssh://kallithea@example.com/name/of/repository``
108 - repository URLs like ``ssh://kallithea@example.com/name/of/repository``
114
109
115 - all network traffic for both read and write happens over the SSH protocol on
110 - all network traffic for both read and write happens over the SSH protocol on
116 port 22, without using HTTP/HTTPS nor the Kallithea WSGI application
111 port 22, without using HTTP/HTTPS nor the Kallithea WSGI application
117
112
118 - encryption and authentication protocols are managed by the system's ``sshd``
113 - encryption and authentication protocols are managed by the system's ``sshd``
119 process, with all users using the same Kallithea system user (e.g.
114 process, with all users using the same Kallithea system user (e.g.
120 ``kallithea``) when connecting to the SSH server, but with users' public keys
115 ``kallithea``) when connecting to the SSH server, but with users' public keys
121 in the Kallithea system user's `.ssh/authorized_keys` file granting each user
116 in the Kallithea system user's `.ssh/authorized_keys` file granting each user
122 sandboxed access to the repositories.
117 sandboxed access to the repositories.
123
118
124 - users and admins can manage SSH public keys in the web UI
119 - users and admins can manage SSH public keys in the web UI
125
120
126 - in their SSH client configuration, users can configure how the client should
121 - in their SSH client configuration, users can configure how the client should
127 control access to their SSH key - without passphrase, with passphrase, and
122 control access to their SSH key - without passphrase, with passphrase, and
128 optionally with passphrase caching in the local shell session (``ssh-agent``).
123 optionally with passphrase caching in the local shell session (``ssh-agent``).
129 This is standard SSH functionality, not something Kallithea provides or
124 This is standard SSH functionality, not something Kallithea provides or
130 interferes with.
125 interferes with.
131
126
132 - network communication between client and server happens in a bidirectional
127 - network communication between client and server happens in a bidirectional
133 stateful stream, and will in some cases be faster than HTTP/HTTPS with several
128 stateful stream, and will in some cases be faster than HTTP/HTTPS with several
134 stateless round-trips.
129 stateless round-trips.
135
130
136 .. note:: At this moment, repository access via SSH has been tested on Unix
131 .. note:: At this moment, repository access via SSH has been tested on Unix
137 only. Windows users that care about SSH are invited to test it and report
132 only. Windows users that care about SSH are invited to test it and report
138 problems, ideally contributing patches that solve these problems.
133 problems, ideally contributing patches that solve these problems.
139
134
140 Users and admins can upload SSH public keys (e.g. ``.ssh/id_rsa.pub``) through
135 Users and admins can upload SSH public keys (e.g. ``.ssh/id_rsa.pub``) through
141 the web interface. The server's ``.ssh/authorized_keys`` file is automatically
136 the web interface. The server's ``.ssh/authorized_keys`` file is automatically
142 maintained with an entry for each SSH key. Each entry will tell ``sshd`` to run
137 maintained with an entry for each SSH key. Each entry will tell ``sshd`` to run
143 ``kallithea-cli`` with the ``ssh-serve`` sub-command and the right Kallithea user ID
138 ``kallithea-cli`` with the ``ssh-serve`` sub-command and the right Kallithea user ID
144 when encountering the corresponding SSH key.
139 when encountering the corresponding SSH key.
145
140
146 To enable SSH repository access, Kallithea must be configured with the path to
141 To enable SSH repository access, Kallithea must be configured with the path to
147 the ``.ssh/authorized_keys`` file for the Kallithea user, and the path to the
142 the ``.ssh/authorized_keys`` file for the Kallithea user, and the path to the
148 ``kallithea-cli`` command. Put something like this in the ``.ini`` file::
143 ``kallithea-cli`` command. Put something like this in the ``.ini`` file::
149
144
150 ssh_enabled = true
145 ssh_enabled = true
151 ssh_authorized_keys = /home/kallithea/.ssh/authorized_keys
146 ssh_authorized_keys = /home/kallithea/.ssh/authorized_keys
152 kallithea_cli_path = /srv/kallithea/venv/bin/kallithea-cli
147 kallithea_cli_path = /srv/kallithea/venv/bin/kallithea-cli
153
148
154 The SSH service must be running, and the Kallithea user account must be active
149 The SSH service must be running, and the Kallithea user account must be active
155 (not necessarily with password access, but public key access must be enabled),
150 (not necessarily with password access, but public key access must be enabled),
156 all file permissions must be set as sshd wants it, and ``authorized_keys`` must
151 all file permissions must be set as sshd wants it, and ``authorized_keys`` must
157 be writeable by the Kallithea user.
152 be writeable by the Kallithea user.
158
153
159 .. note:: The ``authorized_keys`` file will be rewritten from scratch on
154 .. note:: The ``authorized_keys`` file will be rewritten from scratch on
160 each update. If it already exists with other data, Kallithea will not
155 each update. If it already exists with other data, Kallithea will not
161 overwrite the existing ``authorized_keys``, and the server process will
156 overwrite the existing ``authorized_keys``, and the server process will
162 instead throw an exception. The system administrator thus cannot ssh
157 instead throw an exception. The system administrator thus cannot ssh
163 directly to the Kallithea user but must use su/sudo from another account.
158 directly to the Kallithea user but must use su/sudo from another account.
164
159
165 If ``/home/kallithea/.ssh/`` (the directory of the path specified in the
160 If ``/home/kallithea/.ssh/`` (the directory of the path specified in the
166 ``ssh_authorized_keys`` setting of the ``.ini`` file) does not exist as a
161 ``ssh_authorized_keys`` setting of the ``.ini`` file) does not exist as a
167 directory, Kallithea will attempt to create it. If that path exists but is
162 directory, Kallithea will attempt to create it. If that path exists but is
168 *not* a directory, or is not readable-writable-executable by the server
163 *not* a directory, or is not readable-writable-executable by the server
169 process, the server process will raise an exception each time it attempts to
164 process, the server process will raise an exception each time it attempts to
170 write the ``authorized_keys`` file.
165 write the ``authorized_keys`` file.
171
166
172 .. note:: It is possible to configure the SSH server to look for authorized
167 .. note:: It is possible to configure the SSH server to look for authorized
173 keys in multiple files, for example reserving ``ssh/authorized_keys`` to be
168 keys in multiple files, for example reserving ``ssh/authorized_keys`` to be
174 used for normal SSH and with Kallithea using
169 used for normal SSH and with Kallithea using
175 ``.ssh/authorized_keys_kallithea``. In ``/etc/ssh/sshd_config`` set
170 ``.ssh/authorized_keys_kallithea``. In ``/etc/ssh/sshd_config`` set
176 ``AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys_kallithea``
171 ``AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys_kallithea``
177 and restart sshd, and in ``my.ini`` set ``ssh_authorized_keys =
172 and restart sshd, and in ``my.ini`` set ``ssh_authorized_keys =
178 /home/kallithea/.ssh/authorized_keys_kallithea``. Note that this new
173 /home/kallithea/.ssh/authorized_keys_kallithea``. Note that this new
179 location will apply to all system users, and that multiple entries for the
174 location will apply to all system users, and that multiple entries for the
180 same SSH key will shadow each other.
175 same SSH key will shadow each other.
181
176
182 .. warning:: The handling of SSH access is steered directly by the command
177 .. warning:: The handling of SSH access is steered directly by the command
183 specified in the ``authorized_keys`` file. There is no interaction with the
178 specified in the ``authorized_keys`` file. There is no interaction with the
184 web UI. Once SSH access is correctly configured and enabled, it will work
179 web UI. Once SSH access is correctly configured and enabled, it will work
185 regardless of whether the Kallithea web process is actually running. Hence,
180 regardless of whether the Kallithea web process is actually running. Hence,
186 if you want to perform repository or server maintenance and want to fully
181 if you want to perform repository or server maintenance and want to fully
187 disable all access to the repositories, disable SSH access by setting
182 disable all access to the repositories, disable SSH access by setting
188 ``ssh_enabled = false`` in the correct ``.ini`` file (i.e. the ``.ini`` file
183 ``ssh_enabled = false`` in the correct ``.ini`` file (i.e. the ``.ini`` file
189 specified in the ``authorized_keys`` file.)
184 specified in the ``authorized_keys`` file.)
190
185
191 The ``authorized_keys`` file can be updated manually with ``kallithea-cli
186 The ``authorized_keys`` file can be updated manually with ``kallithea-cli
192 ssh-update-authorized-keys -c my.ini``. This command is not needed in normal
187 ssh-update-authorized-keys -c my.ini``. This command is not needed in normal
193 operation but is for example useful after changing SSH-related settings in the
188 operation but is for example useful after changing SSH-related settings in the
194 ``.ini`` file or renaming that file. (The path to the ``.ini`` file is used in
189 ``.ini`` file or renaming that file. (The path to the ``.ini`` file is used in
195 the generated ``authorized_keys`` file).
190 the generated ``authorized_keys`` file).
196
191
197
192
198 Setting up Whoosh full text search
193 Setting up Whoosh full text search
199 ----------------------------------
194 ----------------------------------
200
195
201 Kallithea provides full text search of repositories using `Whoosh`__.
196 Kallithea provides full text search of repositories using `Whoosh`__.
202
197
203 .. __: https://whoosh.readthedocs.io/en/latest/
198 .. __: https://whoosh.readthedocs.io/en/latest/
204
199
205 For an incremental index build, run::
200 For an incremental index build, run::
206
201
207 kallithea-cli index-create -c my.ini
202 kallithea-cli index-create -c my.ini
208
203
209 For a full index rebuild, run::
204 For a full index rebuild, run::
210
205
211 kallithea-cli index-create -c my.ini --full
206 kallithea-cli index-create -c my.ini --full
212
207
213 The ``--repo-location`` option allows the location of the repositories to be overridden;
208 The ``--repo-location`` option allows the location of the repositories to be overridden;
214 usually, the location is retrieved from the Kallithea database.
209 usually, the location is retrieved from the Kallithea database.
215
210
216 The ``--index-only`` option can be used to limit the indexed repositories to a comma-separated list::
211 The ``--index-only`` option can be used to limit the indexed repositories to a comma-separated list::
217
212
218 kallithea-cli index-create -c my.ini --index-only=vcs,kallithea
213 kallithea-cli index-create -c my.ini --index-only=vcs,kallithea
219
214
220 To keep your index up-to-date it is necessary to do periodic index builds;
215 To keep your index up-to-date it is necessary to do periodic index builds;
221 for this, it is recommended to use a crontab entry. Example::
216 for this, it is recommended to use a crontab entry. Example::
222
217
223 0 3 * * * /path/to/virtualenv/bin/kallithea-cli index-create -c /path/to/kallithea/my.ini
218 0 3 * * * /path/to/virtualenv/bin/kallithea-cli index-create -c /path/to/kallithea/my.ini
224
219
225 When using incremental mode (the default), Whoosh will check the last
220 When using incremental mode (the default), Whoosh will check the last
226 modification date of each file and add it to be reindexed if a newer file is
221 modification date of each file and add it to be reindexed if a newer file is
227 available. The indexing daemon checks for any removed files and removes them
222 available. The indexing daemon checks for any removed files and removes them
228 from index.
223 from index.
229
224
230 If you want to rebuild the index from scratch, you can use the ``-f`` flag as above,
225 If you want to rebuild the index from scratch, you can use the ``-f`` flag as above,
231 or in the admin panel you can check the "build from scratch" checkbox.
226 or in the admin panel you can check the "build from scratch" checkbox.
232
227
233
228
234 Integration with issue trackers
229 Integration with issue trackers
235 -------------------------------
230 -------------------------------
236
231
237 Kallithea provides a simple integration with issue trackers. It's possible
232 Kallithea provides a simple integration with issue trackers. It's possible
238 to define a regular expression that will match an issue ID in commit messages,
233 to define a regular expression that will match an issue ID in commit messages,
239 and have that replaced with a URL to the issue.
234 and have that replaced with a URL to the issue.
240
235
241 This is achieved with following three variables in the ini file::
236 This is achieved with following three variables in the ini file::
242
237
243 issue_pat = #(\d+)
238 issue_pat = #(\d+)
244 issue_server_link = https://issues.example.com/{repo}/issue/\1
239 issue_server_link = https://issues.example.com/{repo}/issue/\1
245 issue_sub =
240 issue_sub =
246
241
247 ``issue_pat`` is the regular expression describing which strings in
242 ``issue_pat`` is the regular expression describing which strings in
248 commit messages will be treated as issue references. The expression can/should
243 commit messages will be treated as issue references. The expression can/should
249 have one or more parenthesized groups that can later be referred to in
244 have one or more parenthesized groups that can later be referred to in
250 ``issue_server_link`` and ``issue_sub`` (see below). If you prefer, named groups
245 ``issue_server_link`` and ``issue_sub`` (see below). If you prefer, named groups
251 can be used instead of simple parenthesized groups.
246 can be used instead of simple parenthesized groups.
252
247
253 If the pattern should only match if it is preceded by whitespace, add the
248 If the pattern should only match if it is preceded by whitespace, add the
254 following string before the actual pattern: ``(?:^|(?<=\s))``.
249 following string before the actual pattern: ``(?:^|(?<=\s))``.
255 If the pattern should only match if it is followed by whitespace, add the
250 If the pattern should only match if it is followed by whitespace, add the
256 following string after the actual pattern: ``(?:$|(?=\s))``.
251 following string after the actual pattern: ``(?:$|(?=\s))``.
257 These expressions use lookbehind and lookahead assertions of the Python regular
252 These expressions use lookbehind and lookahead assertions of the Python regular
258 expression module to avoid the whitespace to be part of the actual pattern,
253 expression module to avoid the whitespace to be part of the actual pattern,
259 otherwise the link text will also contain that whitespace.
254 otherwise the link text will also contain that whitespace.
260
255
261 Matched issue references are replaced with the link specified in
256 Matched issue references are replaced with the link specified in
262 ``issue_server_link``, in which any backreferences are resolved. Backreferences
257 ``issue_server_link``, in which any backreferences are resolved. Backreferences
263 can be ``\1``, ``\2``, ... or for named groups ``\g<groupname>``.
258 can be ``\1``, ``\2``, ... or for named groups ``\g<groupname>``.
264 The special token ``{repo}`` is replaced with the full repository path
259 The special token ``{repo}`` is replaced with the full repository path
265 (including repository groups), while token ``{repo_name}`` is replaced with the
260 (including repository groups), while token ``{repo_name}`` is replaced with the
266 repository name (without repository groups).
261 repository name (without repository groups).
267
262
268 The link text is determined by ``issue_sub``, which can be a string containing
263 The link text is determined by ``issue_sub``, which can be a string containing
269 backreferences to the groups specified in ``issue_pat``. If ``issue_sub`` is
264 backreferences to the groups specified in ``issue_pat``. If ``issue_sub`` is
270 empty, then the text matched by ``issue_pat`` is used verbatim.
265 empty, then the text matched by ``issue_pat`` is used verbatim.
271
266
272 The example settings shown above match issues in the format ``#<number>``.
267 The example settings shown above match issues in the format ``#<number>``.
273 This will cause the text ``#300`` to be transformed into a link:
268 This will cause the text ``#300`` to be transformed into a link:
274
269
275 .. code-block:: html
270 .. code-block:: html
276
271
277 <a href="https://issues.example.com/example_repo/issue/300">#300</a>
272 <a href="https://issues.example.com/example_repo/issue/300">#300</a>
278
273
279 The following example transforms a text starting with either of 'pullrequest',
274 The following example transforms a text starting with either of 'pullrequest',
280 'pull request' or 'PR', followed by an optional space, then a pound character
275 'pull request' or 'PR', followed by an optional space, then a pound character
281 (#) and one or more digits, into a link with the text 'PR #' followed by the
276 (#) and one or more digits, into a link with the text 'PR #' followed by the
282 digits::
277 digits::
283
278
284 issue_pat = (pullrequest|pull request|PR) ?#(\d+)
279 issue_pat = (pullrequest|pull request|PR) ?#(\d+)
285 issue_server_link = https://issues.example.com/\2
280 issue_server_link = https://issues.example.com/\2
286 issue_sub = PR #\2
281 issue_sub = PR #\2
287
282
288 The following example demonstrates how to require whitespace before the issue
283 The following example demonstrates how to require whitespace before the issue
289 reference in order for it to be recognized, such that the text ``issue#123`` will
284 reference in order for it to be recognized, such that the text ``issue#123`` will
290 not cause a match, but ``issue #123`` will::
285 not cause a match, but ``issue #123`` will::
291
286
292 issue_pat = (?:^|(?<=\s))#(\d+)
287 issue_pat = (?:^|(?<=\s))#(\d+)
293 issue_server_link = https://issues.example.com/\1
288 issue_server_link = https://issues.example.com/\1
294 issue_sub =
289 issue_sub =
295
290
296 If needed, more than one pattern can be specified by appending a unique suffix to
291 If needed, more than one pattern can be specified by appending a unique suffix to
297 the variables. For example, also demonstrating the use of named groups::
292 the variables. For example, also demonstrating the use of named groups::
298
293
299 issue_pat_wiki = wiki-(?P<pagename>\S+)
294 issue_pat_wiki = wiki-(?P<pagename>\S+)
300 issue_server_link_wiki = https://wiki.example.com/\g<pagename>
295 issue_server_link_wiki = https://wiki.example.com/\g<pagename>
301 issue_sub_wiki = WIKI-\g<pagename>
296 issue_sub_wiki = WIKI-\g<pagename>
302
297
303 With these settings, wiki pages can be referenced as wiki-some-id, and every
298 With these settings, wiki pages can be referenced as wiki-some-id, and every
304 such reference will be transformed into:
299 such reference will be transformed into:
305
300
306 .. code-block:: html
301 .. code-block:: html
307
302
308 <a href="https://wiki.example.com/some-id">WIKI-some-id</a>
303 <a href="https://wiki.example.com/some-id">WIKI-some-id</a>
309
304
310 Refer to the `Python regular expression documentation`_ for more details about
305 Refer to the `Python regular expression documentation`_ for more details about
311 the supported syntax in ``issue_pat``, ``issue_server_link`` and ``issue_sub``.
306 the supported syntax in ``issue_pat``, ``issue_server_link`` and ``issue_sub``.
312
307
313
308
314 Hook management
309 Hook management
315 ---------------
310 ---------------
316
311
317 Hooks can be managed in similar way to that used in ``.hgrc`` files.
312 Hooks can be managed in similar way to that used in ``.hgrc`` files.
318 To manage hooks, choose *Admin > Settings > Hooks*.
313 To manage hooks, choose *Admin > Settings > Hooks*.
319
314
320 The built-in hooks cannot be modified, though they can be enabled or disabled in the *VCS* section.
315 The built-in hooks cannot be modified, though they can be enabled or disabled in the *VCS* section.
321
316
322 To add another custom hook simply fill in the first textbox with
317 To add another custom hook simply fill in the first textbox with
323 ``<name>.<hook_type>`` and the second with the hook path. Example hooks
318 ``<name>.<hook_type>`` and the second with the hook path. Example hooks
324 can be found in ``kallithea.lib.hooks``.
319 can be found in ``kallithea.lib.hooks``.
325
320
326
321
327 Changing default encoding
322 Changing default encoding
328 -------------------------
323 -------------------------
329
324
330 By default, Kallithea uses UTF-8 encoding.
325 By default, Kallithea uses UTF-8 encoding.
331 This is configurable as ``default_encoding`` in the .ini file.
326 This is configurable as ``default_encoding`` in the .ini file.
332 This affects many parts in Kallithea including user names, filenames, and
327 This affects many parts in Kallithea including user names, filenames, and
333 encoding of commit messages. In addition Kallithea can detect if the ``chardet``
328 encoding of commit messages. In addition Kallithea can detect if the ``chardet``
334 library is installed. If ``chardet`` is detected Kallithea will fallback to it
329 library is installed. If ``chardet`` is detected Kallithea will fallback to it
335 when there are encode/decode errors.
330 when there are encode/decode errors.
336
331
337 The Mercurial encoding is configurable as ``hgencoding``. It is similar to
332 The Mercurial encoding is configurable as ``hgencoding``. It is similar to
338 setting the ``HGENCODING`` environment variable, but will override it.
333 setting the ``HGENCODING`` environment variable, but will override it.
339
334
340
335
341 Celery configuration
336 Celery configuration
342 --------------------
337 --------------------
343
338
344 Kallithea can use the distributed task queue system Celery_ to run tasks like
339 Kallithea can use the distributed task queue system Celery_ to run tasks like
345 cloning repositories or sending emails.
340 cloning repositories or sending emails.
346
341
347 Kallithea will in most setups work perfectly fine out of the box (without
342 Kallithea will in most setups work perfectly fine out of the box (without
348 Celery), executing all tasks in the web server process. Some tasks can however
343 Celery), executing all tasks in the web server process. Some tasks can however
349 take some time to run and it can be better to run such tasks asynchronously in
344 take some time to run and it can be better to run such tasks asynchronously in
350 a separate process so the web server can focus on serving web requests.
345 a separate process so the web server can focus on serving web requests.
351
346
352 For installation and configuration of Celery, see the `Celery documentation`_.
347 For installation and configuration of Celery, see the `Celery documentation`_.
353 Note that Celery requires a message broker service like RabbitMQ_ (recommended)
348 Note that Celery requires a message broker service like RabbitMQ_ (recommended)
354 or Redis_.
349 or Redis_.
355
350
356 The use of Celery is configured in the Kallithea ini configuration file.
351 The use of Celery is configured in the Kallithea ini configuration file.
357 To enable it, simply set::
352 To enable it, simply set::
358
353
359 use_celery = true
354 use_celery = true
360
355
361 and add or change the ``celery.*`` configuration variables.
356 and add or change the ``celery.*`` configuration variables.
362
357
363 Configuration settings are prefixed with 'celery.', so for example setting
358 Configuration settings are prefixed with 'celery.', so for example setting
364 `broker_url` in Celery means setting `celery.broker_url` in the configuration
359 `broker_url` in Celery means setting `celery.broker_url` in the configuration
365 file.
360 file.
366
361
367 To start the Celery process, run::
362 To start the Celery process, run::
368
363
369 kallithea-cli celery-run -c my.ini
364 kallithea-cli celery-run -c my.ini
370
365
371 Extra options to the Celery worker can be passed after ``--`` - see ``-- -h``
366 Extra options to the Celery worker can be passed after ``--`` - see ``-- -h``
372 for more info.
367 for more info.
373
368
374 .. note::
369 .. note::
375 Make sure you run this command from the same virtualenv, and with the same
370 Make sure you run this command from the same virtualenv, and with the same
376 user that Kallithea runs.
371 user that Kallithea runs.
377
372
378
373
379 HTTPS support
374 HTTPS support
380 -------------
375 -------------
381
376
382 Kallithea will by default generate URLs based on the WSGI environment.
377 Kallithea will by default generate URLs based on the WSGI environment.
383
378
384 Alternatively, you can use some special configuration settings to control
379 Alternatively, you can use some special configuration settings to control
385 directly which scheme/protocol Kallithea will use when generating URLs:
380 directly which scheme/protocol Kallithea will use when generating URLs:
386
381
387 - With ``https_fixup = true``, the scheme will be taken from the
382 - With ``https_fixup = true``, the scheme will be taken from the
388 ``X-Url-Scheme``, ``X-Forwarded-Scheme`` or ``X-Forwarded-Proto`` HTTP header
383 ``X-Url-Scheme``, ``X-Forwarded-Scheme`` or ``X-Forwarded-Proto`` HTTP header
389 (default ``http``).
384 (default ``http``).
390 - With ``force_https = true`` the default will be ``https``.
385 - With ``force_https = true`` the default will be ``https``.
391 - With ``use_htsts = true``, Kallithea will set ``Strict-Transport-Security`` when using https.
386 - With ``use_htsts = true``, Kallithea will set ``Strict-Transport-Security`` when using https.
392
387
393 .. _nginx_virtual_host:
388 .. _nginx_virtual_host:
394
389
395
390
396 Nginx virtual host example
391 Nginx virtual host example
397 --------------------------
392 --------------------------
398
393
399 Sample config for Nginx using proxy:
394 Sample config for Nginx using proxy:
400
395
401 .. code-block:: nginx
396 .. code-block:: nginx
402
397
403 upstream kallithea {
398 upstream kallithea {
404 server 127.0.0.1:5000;
399 server 127.0.0.1:5000;
405 # add more instances for load balancing
400 # add more instances for load balancing
406 #server 127.0.0.1:5001;
401 #server 127.0.0.1:5001;
407 #server 127.0.0.1:5002;
402 #server 127.0.0.1:5002;
408 }
403 }
409
404
410 ## gist alias
405 ## gist alias
411 server {
406 server {
412 listen 443;
407 listen 443;
413 server_name gist.example.com;
408 server_name gist.example.com;
414 access_log /var/log/nginx/gist.access.log;
409 access_log /var/log/nginx/gist.access.log;
415 error_log /var/log/nginx/gist.error.log;
410 error_log /var/log/nginx/gist.error.log;
416
411
417 ssl on;
412 ssl on;
418 ssl_certificate gist.your.kallithea.server.crt;
413 ssl_certificate gist.your.kallithea.server.crt;
419 ssl_certificate_key gist.your.kallithea.server.key;
414 ssl_certificate_key gist.your.kallithea.server.key;
420
415
421 ssl_session_timeout 5m;
416 ssl_session_timeout 5m;
422
417
423 ssl_protocols SSLv3 TLSv1;
418 ssl_protocols SSLv3 TLSv1;
424 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
419 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
425 ssl_prefer_server_ciphers on;
420 ssl_prefer_server_ciphers on;
426
421
427 rewrite ^/(.+)$ https://kallithea.example.com/_admin/gists/$1;
422 rewrite ^/(.+)$ https://kallithea.example.com/_admin/gists/$1;
428 rewrite (.*) https://kallithea.example.com/_admin/gists;
423 rewrite (.*) https://kallithea.example.com/_admin/gists;
429 }
424 }
430
425
431 server {
426 server {
432 listen 443;
427 listen 443;
433 server_name kallithea.example.com
428 server_name kallithea.example.com
434 access_log /var/log/nginx/kallithea.access.log;
429 access_log /var/log/nginx/kallithea.access.log;
435 error_log /var/log/nginx/kallithea.error.log;
430 error_log /var/log/nginx/kallithea.error.log;
436
431
437 ssl on;
432 ssl on;
438 ssl_certificate your.kallithea.server.crt;
433 ssl_certificate your.kallithea.server.crt;
439 ssl_certificate_key your.kallithea.server.key;
434 ssl_certificate_key your.kallithea.server.key;
440
435
441 ssl_session_timeout 5m;
436 ssl_session_timeout 5m;
442
437
443 ssl_protocols SSLv3 TLSv1;
438 ssl_protocols SSLv3 TLSv1;
444 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
439 ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
445 ssl_prefer_server_ciphers on;
440 ssl_prefer_server_ciphers on;
446
441
447 ## uncomment root directive if you want to serve static files by nginx
442 ## uncomment root directive if you want to serve static files by nginx
448 ## requires static_files = false in .ini file
443 ## requires static_files = false in .ini file
449 #root /srv/kallithea/kallithea/kallithea/public;
444 #root /srv/kallithea/kallithea/kallithea/public;
450 include /etc/nginx/proxy.conf;
445 include /etc/nginx/proxy.conf;
451 location / {
446 location / {
452 try_files $uri @kallithea;
447 try_files $uri @kallithea;
453 }
448 }
454
449
455 location @kallithea {
450 location @kallithea {
456 proxy_pass http://127.0.0.1:5000;
451 proxy_pass http://127.0.0.1:5000;
457 }
452 }
458
453
459 }
454 }
460
455
461 Here's the proxy.conf. It's tuned so it will not timeout on long
456 Here's the proxy.conf. It's tuned so it will not timeout on long
462 pushes or large pushes::
457 pushes or large pushes::
463
458
464 proxy_redirect off;
459 proxy_redirect off;
465 proxy_set_header Host $host;
460 proxy_set_header Host $host;
466 ## needed for container auth
461 ## needed for container auth
467 #proxy_set_header REMOTE_USER $remote_user;
462 #proxy_set_header REMOTE_USER $remote_user;
468 #proxy_set_header X-Forwarded-User $remote_user;
463 #proxy_set_header X-Forwarded-User $remote_user;
469 proxy_set_header X-Url-Scheme $scheme;
464 proxy_set_header X-Url-Scheme $scheme;
470 proxy_set_header X-Host $http_host;
465 proxy_set_header X-Host $http_host;
471 proxy_set_header X-Real-IP $remote_addr;
466 proxy_set_header X-Real-IP $remote_addr;
472 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
467 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
473 proxy_set_header Proxy-host $proxy_host;
468 proxy_set_header Proxy-host $proxy_host;
474 proxy_buffering off;
469 proxy_buffering off;
475 proxy_connect_timeout 7200;
470 proxy_connect_timeout 7200;
476 proxy_send_timeout 7200;
471 proxy_send_timeout 7200;
477 proxy_read_timeout 7200;
472 proxy_read_timeout 7200;
478 proxy_buffers 8 32k;
473 proxy_buffers 8 32k;
479 client_max_body_size 1024m;
474 client_max_body_size 1024m;
480 client_body_buffer_size 128k;
475 client_body_buffer_size 128k;
481 large_client_header_buffers 8 64k;
476 large_client_header_buffers 8 64k;
482
477
483 .. _apache_virtual_host_reverse_proxy:
478 .. _apache_virtual_host_reverse_proxy:
484
479
485
480
486 Apache virtual host reverse proxy example
481 Apache virtual host reverse proxy example
487 -----------------------------------------
482 -----------------------------------------
488
483
489 Here is a sample configuration file for Apache using proxy:
484 Here is a sample configuration file for Apache using proxy:
490
485
491 .. code-block:: apache
486 .. code-block:: apache
492
487
493 <VirtualHost *:80>
488 <VirtualHost *:80>
494 ServerName kallithea.example.com
489 ServerName kallithea.example.com
495
490
496 <Proxy *>
491 <Proxy *>
497 # For Apache 2.4 and later:
492 # For Apache 2.4 and later:
498 Require all granted
493 Require all granted
499
494
500 # For Apache 2.2 and earlier, instead use:
495 # For Apache 2.2 and earlier, instead use:
501 # Order allow,deny
496 # Order allow,deny
502 # Allow from all
497 # Allow from all
503 </Proxy>
498 </Proxy>
504
499
505 #important !
500 #important !
506 #Directive to properly generate url (clone url) for Kallithea
501 #Directive to properly generate url (clone url) for Kallithea
507 ProxyPreserveHost On
502 ProxyPreserveHost On
508
503
509 #kallithea instance
504 #kallithea instance
510 ProxyPass / http://127.0.0.1:5000/
505 ProxyPass / http://127.0.0.1:5000/
511 ProxyPassReverse / http://127.0.0.1:5000/
506 ProxyPassReverse / http://127.0.0.1:5000/
512
507
513 #to enable https use line below
508 #to enable https use line below
514 #SetEnvIf X-Url-Scheme https HTTPS=1
509 #SetEnvIf X-Url-Scheme https HTTPS=1
515 </VirtualHost>
510 </VirtualHost>
516
511
517 Additional tutorial
512 Additional tutorial
518 http://pylonsbook.com/en/1.1/deployment.html#using-apache-to-proxy-requests-to-pylons
513 http://pylonsbook.com/en/1.1/deployment.html#using-apache-to-proxy-requests-to-pylons
519
514
520 .. _apache_subdirectory:
515 .. _apache_subdirectory:
521
516
522
517
523 Apache as subdirectory
518 Apache as subdirectory
524 ----------------------
519 ----------------------
525
520
526 Apache subdirectory part:
521 Apache subdirectory part:
527
522
528 .. code-block:: apache
523 .. code-block:: apache
529
524
530 <Location /PREFIX >
525 <Location /PREFIX >
531 ProxyPass http://127.0.0.1:5000/PREFIX
526 ProxyPass http://127.0.0.1:5000/PREFIX
532 ProxyPassReverse http://127.0.0.1:5000/PREFIX
527 ProxyPassReverse http://127.0.0.1:5000/PREFIX
533 SetEnvIf X-Url-Scheme https HTTPS=1
528 SetEnvIf X-Url-Scheme https HTTPS=1
534 </Location>
529 </Location>
535
530
536 Besides the regular apache setup you will need to add the following line
531 Besides the regular apache setup you will need to add the following line
537 into ``[app:main]`` section of your .ini file::
532 into ``[app:main]`` section of your .ini file::
538
533
539 filter-with = proxy-prefix
534 filter-with = proxy-prefix
540
535
541 Add the following at the end of the .ini file::
536 Add the following at the end of the .ini file::
542
537
543 [filter:proxy-prefix]
538 [filter:proxy-prefix]
544 use = egg:PasteDeploy#prefix
539 use = egg:PasteDeploy#prefix
545 prefix = /PREFIX
540 prefix = /PREFIX
546
541
547 then change ``PREFIX`` into your chosen prefix
542 then change ``PREFIX`` into your chosen prefix
548
543
549 .. _apache_mod_wsgi:
544 .. _apache_mod_wsgi:
550
545
551
546
552 Apache with mod_wsgi
547 Apache with mod_wsgi
553 --------------------
548 --------------------
554
549
555 Alternatively, Kallithea can be set up with Apache under mod_wsgi. For
550 Alternatively, Kallithea can be set up with Apache under mod_wsgi. For
556 that, you'll need to:
551 that, you'll need to:
557
552
558 - Install mod_wsgi. If using a Debian-based distro, you can install
553 - Install mod_wsgi. If using a Debian-based distro, you can install
559 the package libapache2-mod-wsgi::
554 the package libapache2-mod-wsgi::
560
555
561 aptitude install libapache2-mod-wsgi
556 aptitude install libapache2-mod-wsgi
562
557
563 - Enable mod_wsgi::
558 - Enable mod_wsgi::
564
559
565 a2enmod wsgi
560 a2enmod wsgi
566
561
567 - Add global Apache configuration to tell mod_wsgi that Python only will be
562 - Add global Apache configuration to tell mod_wsgi that Python only will be
568 used in the WSGI processes and shouldn't be initialized in the Apache
563 used in the WSGI processes and shouldn't be initialized in the Apache
569 processes::
564 processes::
570
565
571 WSGIRestrictEmbedded On
566 WSGIRestrictEmbedded On
572
567
573 - Create a WSGI dispatch script, like the one below. Make sure you
568 - Create a WSGI dispatch script, like the one below. Make sure you
574 check that the paths correctly point to where you installed Kallithea
569 check that the paths correctly point to where you installed Kallithea
575 and its Python Virtual Environment.
570 and its Python Virtual Environment.
576
571
577 .. code-block:: python
572 .. code-block:: python
578
573
579 import os
574 import os
580 os.environ['PYTHON_EGG_CACHE'] = '/srv/kallithea/.egg-cache'
575 os.environ['PYTHON_EGG_CACHE'] = '/srv/kallithea/.egg-cache'
581
576
582 # sometimes it's needed to set the current dir
577 # sometimes it's needed to set the current dir
583 os.chdir('/srv/kallithea/')
578 os.chdir('/srv/kallithea/')
584
579
585 import site
580 import site
586 site.addsitedir("/srv/kallithea/venv/lib/python3.7/site-packages")
581 site.addsitedir("/srv/kallithea/venv/lib/python3.7/site-packages")
587
582
588 ini = '/srv/kallithea/my.ini'
583 ini = '/srv/kallithea/my.ini'
589 from logging.config import fileConfig
584 from logging.config import fileConfig
590 fileConfig(ini, {'__file__': ini, 'here': '/srv/kallithea'})
585 fileConfig(ini, {'__file__': ini, 'here': '/srv/kallithea'})
591 from paste.deploy import loadapp
586 from paste.deploy import loadapp
592 application = loadapp('config:' + ini)
587 application = loadapp('config:' + ini)
593
588
594 Or using proper virtualenv activation:
589 Or using proper virtualenv activation:
595
590
596 .. code-block:: python
591 .. code-block:: python
597
592
598 activate_this = '/srv/kallithea/venv/bin/activate_this.py'
593 activate_this = '/srv/kallithea/venv/bin/activate_this.py'
599 execfile(activate_this, dict(__file__=activate_this))
594 execfile(activate_this, dict(__file__=activate_this))
600
595
601 import os
596 import os
602 os.environ['HOME'] = '/srv/kallithea'
597 os.environ['HOME'] = '/srv/kallithea'
603
598
604 ini = '/srv/kallithea/kallithea.ini'
599 ini = '/srv/kallithea/kallithea.ini'
605 from logging.config import fileConfig
600 from logging.config import fileConfig
606 fileConfig(ini, {'__file__': ini, 'here': '/srv/kallithea'})
601 fileConfig(ini, {'__file__': ini, 'here': '/srv/kallithea'})
607 from paste.deploy import loadapp
602 from paste.deploy import loadapp
608 application = loadapp('config:' + ini)
603 application = loadapp('config:' + ini)
609
604
610 - Add the necessary ``WSGI*`` directives to the Apache Virtual Host configuration
605 - Add the necessary ``WSGI*`` directives to the Apache Virtual Host configuration
611 file, like in the example below. Notice that the WSGI dispatch script created
606 file, like in the example below. Notice that the WSGI dispatch script created
612 above is referred to with the ``WSGIScriptAlias`` directive.
607 above is referred to with the ``WSGIScriptAlias`` directive.
613 The default locale settings Apache provides for web services are often not
608 The default locale settings Apache provides for web services are often not
614 adequate, with `C` as the default language and `ASCII` as the encoding.
609 adequate, with `C` as the default language and `ASCII` as the encoding.
615 Instead, use the ``lang`` parameter of ``WSGIDaemonProcess`` to specify a
610 Instead, use the ``lang`` parameter of ``WSGIDaemonProcess`` to specify a
616 suitable locale. See also the :ref:`overview` section and the
611 suitable locale. See also the :ref:`overview` section and the
617 `WSGIDaemonProcess documentation`_.
612 `WSGIDaemonProcess documentation`_.
618
613
619 Apache will by default run as a special Apache user, on Linux systems
614 Apache will by default run as a special Apache user, on Linux systems
620 usually ``www-data`` or ``apache``. If you need to have the repositories
615 usually ``www-data`` or ``apache``. If you need to have the repositories
621 directory owned by a different user, use the user and group options to
616 directory owned by a different user, use the user and group options to
622 WSGIDaemonProcess to set the name of the user and group.
617 WSGIDaemonProcess to set the name of the user and group.
623
618
624 Once again, check that all paths are correctly specified.
619 Once again, check that all paths are correctly specified.
625
620
626 .. code-block:: apache
621 .. code-block:: apache
627
622
628 WSGIDaemonProcess kallithea processes=5 threads=1 maximum-requests=100 \
623 WSGIDaemonProcess kallithea processes=5 threads=1 maximum-requests=100 \
629 python-home=/srv/kallithea/venv lang=C.UTF-8
624 python-home=/srv/kallithea/venv lang=C.UTF-8
630 WSGIProcessGroup kallithea
625 WSGIProcessGroup kallithea
631 WSGIScriptAlias / /srv/kallithea/dispatch.wsgi
626 WSGIScriptAlias / /srv/kallithea/dispatch.wsgi
632 WSGIPassAuthorization On
627 WSGIPassAuthorization On
633
628
634 Or if using a dispatcher WSGI script with proper virtualenv activation:
629 Or if using a dispatcher WSGI script with proper virtualenv activation:
635
630
636 .. code-block:: apache
631 .. code-block:: apache
637
632
638 WSGIDaemonProcess kallithea processes=5 threads=1 maximum-requests=100 lang=en_US.utf8
633 WSGIDaemonProcess kallithea processes=5 threads=1 maximum-requests=100 lang=en_US.utf8
639 WSGIProcessGroup kallithea
634 WSGIProcessGroup kallithea
640 WSGIScriptAlias / /srv/kallithea/dispatch.wsgi
635 WSGIScriptAlias / /srv/kallithea/dispatch.wsgi
641 WSGIPassAuthorization On
636 WSGIPassAuthorization On
642
637
643
638
644 Other configuration files
639 Other configuration files
645 -------------------------
640 -------------------------
646
641
647 A number of `example init.d scripts`__ can be found in
642 A number of `example init.d scripts`__ can be found in
648 the ``init.d`` directory of the Kallithea source.
643 the ``init.d`` directory of the Kallithea source.
649
644
650 .. __: https://kallithea-scm.org/repos/kallithea/files/tip/init.d/ .
645 .. __: https://kallithea-scm.org/repos/kallithea/files/tip/init.d/ .
651
646
652
647
653 .. _python: http://www.python.org/
648 .. _python: http://www.python.org/
654 .. _Python regular expression documentation: https://docs.python.org/2/library/re.html
649 .. _Python regular expression documentation: https://docs.python.org/2/library/re.html
655 .. _Mercurial: https://www.mercurial-scm.org/
650 .. _Mercurial: https://www.mercurial-scm.org/
656 .. _Celery: http://celeryproject.org/
651 .. _Celery: http://celeryproject.org/
657 .. _Celery documentation: http://docs.celeryproject.org/en/latest/getting-started/index.html
652 .. _Celery documentation: http://docs.celeryproject.org/en/latest/getting-started/index.html
658 .. _RabbitMQ: http://www.rabbitmq.com/
653 .. _RabbitMQ: http://www.rabbitmq.com/
659 .. _Redis: http://redis.io/
654 .. _Redis: http://redis.io/
660 .. _mercurial-server: http://www.lshift.net/mercurial-server.html
655 .. _mercurial-server: http://www.lshift.net/mercurial-server.html
661 .. _PublishingRepositories: https://www.mercurial-scm.org/wiki/PublishingRepositories
656 .. _PublishingRepositories: https://www.mercurial-scm.org/wiki/PublishingRepositories
662 .. _WSGIDaemonProcess documentation: https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
657 .. _WSGIDaemonProcess documentation: https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
General Comments 0
You need to be logged in to leave comments. Login now