Fix names of parsercache_selective_* stats
[mediawiki.git] / DEVELOPERS.md
blob48a7c9f08d9e00c48b3bd0be7d80865563238f49
1 # MediaWiki Developers
3 Welcome to the MediaWiki community! Please see [How to become a MediaWiki
4 hacker](https://www.mediawiki.org/wiki/How_to_become_a_MediaWiki_hacker) for
5 general information on contributing to MediaWiki.
7 ## Development environment
9 MediaWiki provides an extendable local development environment based on Docker Compose. This environment provides PHP,
10 Apache, Xdebug and a SQLite database.
12 **Do not use the development environment to serve a public website! Bad things would happen!**
14 More documentation, examples, and configuration recipes are available at [mediawiki.org/wiki/MediaWiki-Docker][mw-docker].
16 Support is available on the [Libera IRC network][libera-home] in the [#mediawiki channel][libera-webchat], and on
17 Phabricator by creating tasks with the [MediaWiki-Docker][mw-docker-phab] tag.
19 [mw-docker]: https://www.mediawiki.org/wiki/MediaWiki-Docker
20 [mw-docker-phab]: https://phabricator.wikimedia.org/tag/mediawiki-docker/
21 [libera-home]: https://libera.chat/
22 [libera-webchat]: https://web.libera.chat/#mediawiki
24 ## Quickstart
26 ### 1. Requirements
28 You'll need to have Docker installed:
30 * [Docker Desktop][docker-install] for macOS or Windows.
31 * [Docker engine][docker-linux] for Linux.
33 [docker-install]: https://docs.docker.com/get-docker/
34 [docker-linux]: https://docs.docker.com/engine/install/
36 **Linux users**:
38 * We recommend installing `docker-ce`, `docker-ce-cli`, `containerd.io`, and `docker-compose-plugin` by [downloading the server
39   releases][dc-release] for your distribution rather than Docker Desktop. You can also install the [binaries][dc-binaries].
40 * Follow the instructions to ["Manage Docker as a non-root user"][dc-non-root]
42 [dc-release]: https://docs.docker.com/engine/install/
43 [dc-binaries]: https://docs.docker.com/engine/install/binaries/
44 [dc-non-root]: https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user
46 **Windows users**:
48 Running Docker from a Windows terminal and using the Windows file system will result in MediaWiki being very slow. For Windows 10 and higher, we recommend configuring Docker and Windows to use the [Windows Subsystem for Linux (WSL)](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux). Turn on WSL in your Windows settings, then run the following commands: `wsl --install -d ubuntu` and `wsl --set-version ubuntu 2`. Then go into Docker -> Settings -> General -> tick "Use the WSL 2 based engine", then go into Docker -> Settings -> Resources -> WSL Integration -> tick "Ubuntu". `git clone` the mediawiki repository into a WSL folder such as `home/yourusername/mediawiki` so that the files are inside WSL. Then you can run most of the commands in this tutorial outside of WSL, by opening PowerShell, navigating to the WSL directory with `cd \\wsl.localhost\Ubuntu\home\yourusername\mediawiki`, and executing shell commands as normal. To access WSL from PowerShell (rare but may be needed sometimes), you can use the command `ubuntu` to turn a PowerShell console into a WSL console. To navigate to WSL folders in [File Explorer](https://en.wikipedia.org/wiki/File_Explorer), show the Navigation Pane, then towards the bottom, look for "Linux" (it will be close to "This PC").
50 **Mac users**:
52 If you're using Docker Desktop and have the `Use Rosetta for x86/amd64 emulation on Apple Silicon` setting enabled, you may encounter an issue where loading the wiki results in a blank page or a 503 error. To resolve this, disable the setting and restart Docker Desktop. See [this page](https://phabricator.wikimedia.org/P49617) for more information.
54 ### 2. Download MediaWiki files
56 Download the latest MediaWiki files to your computer. One way to download the latest alpha version of MediaWiki is to
57 [install git](https://git-scm.com/), open a shell, navigate to the directory where you want to save the files, then type
58 `git clone https://gerrit.wikimedia.org/r/mediawiki/core.git mediawiki`.
60 Optional: If you plan to submit patches to this repository, you will probably want to [create a Gerrit account](https://wikitech.wikimedia.org/wiki/Help:Create_a_Wikimedia_developer_account),
61 then type `git remote set-url origin ssh://YOUR-GERRIT-USERNAME-HERE@gerrit.wikimedia.org:29418/mediawiki/core`,
62 replacing YOUR-GERRIT-USERNAME-HERE with your Gerrit username. Please see the official
63 [MediaWiki Gerrit tutorial](https://www.mediawiki.org/wiki/Gerrit/Tutorial) for more information.
65 ### 3. Prepare `.env` file
67 Using a text editor, create a `.env` file in the root of the MediaWiki core repository, and copy these contents into
68 that file:
70 ```sh
71 MW_SCRIPT_PATH=/w
72 MW_SERVER=http://localhost:8080
73 MW_DOCKER_PORT=8080
74 MEDIAWIKI_USER=Admin
75 MEDIAWIKI_PASSWORD=dockerpass
76 XDEBUG_CONFIG=
77 XDEBUG_ENABLE=true
78 XHPROF_ENABLE=true
79 ```
81 Windows users: Run the following command to add a blank user ID and group ID to your `.env` file:
83 ```sh
84 echo "
85 MW_DOCKER_UID=
86 MW_DOCKER_GID=" >> .env
87 ```
89 Non-Windows users: Run the following command to add your user ID and group ID to your `.env` file:
91 ```sh
92 echo "MW_DOCKER_UID=$(id -u)
93 MW_DOCKER_GID=$(id -g)" >> .env
94 ```
96 Linux users: If you'd like to use Xdebug features inside your IDE, then create a `docker-compose.override.yml` file as
97 well:
99 ```yaml
100 services:
101   mediawiki:
102     # For Linux: This extra_hosts section enables Xdebug-IDE communication:
103     extra_hosts:
104       - "host.docker.internal:host-gateway"
107 ### 4. Create the environment
109 * Start the containers:
110   ```sh
111   docker compose up -d
112   ```
113   The "up" command makes sure that the PHP and webserver containers are running (and any others in the
114   `docker-compose.yml` file). It is safe to run at any time, and will do nothing if the containers are already running.
116   The first time, it may take a few minutes to download new Docker images.
118   The `-d` argument stands for "detached" mode, which run the services in the background. If you suspect a problem with
119   one of the services, you can run it without `-d` to follow the server logs directly from your terminal. You don't have
120   to stop the services first, if you ran it with `-d` and then without, you'll get connected to the already running
121   containers including a decent back scroll of server logs.
123   Note that MediaWiki debug logs go to `/cache/*.log` files (not sent to docker).
125 * Install PHP dependencies from Composer:
126   ```sh
127   docker compose exec mediawiki composer update
128   ```
130 * Install MediaWiki:
131   ```sh
132   docker compose exec mediawiki /bin/bash /docker/install.sh
133   ```
134   Windows users: make sure you run the above command in PowerShell as it does not work in Bash.
136 * Windows users: Make sure to set the SQLite directory to be writable.
137   ```sh
138   docker compose exec mediawiki chmod -R o+rwx cache/sqlite
139   ```
141 Done! The wiki should now be available for you at <http://localhost:8080>.
143 ## Usage
145 ### Running commands
147 You can use `docker compose exec mediawiki bash` to open a Bash shell in the
148 MediaWiki container. You can then run one or more commands as needed and stay
149 within the container shell.
151 You can also run a single command in the container directly from your host
152 shell, for example: `docker compose exec mediawiki php maintenance/run.php update`.
154 ### PHPUnit
156 Run a single PHPUnit file or directory:
158 ```sh
159 docker compose exec mediawiki bash
160 instance:/w$ cd tests/phpunit
161 instance:/w/tests/phpunit$ composer phpunit -- path/to/my/test/
164 See [PHPUnit on mediawiki.org][phpunit-testing] for more examples.
166 [phpunit-testing]: https://www.mediawiki.org/wiki/Manual:PHP_unit_testing/Running_the_tests
168 ### Selenium
170 You can use [Fresh][fresh] to run [Selenium in a dedicated
171 container][selenium-dedicated]. Example usage:
173 ```sh
174 fresh-node -env -net
175 npm ci
176 npm run selenium-test
179 [selenium-dedicated]: https://www.mediawiki.org/wiki/Selenium/Getting_Started/Run_tests_using_Fresh
181 ### API Testing
183 You can use [Fresh][fresh] to run [API tests in a dedicated
184 container][api-dedicated]. Example usage:
186 ```sh
187 export MW_SERVER=http://localhost:8080/
188 export MW_SCRIPT_PATH=/w
189 export MEDIAWIKI_USER=Admin
190 export MEDIAWIKI_PASSWORD=dockerpass
191 fresh-node -env -net
192 # Create .api-testing.config.json as documented on
193 # https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
194 npm ci
195 npm run api-testing
198 [fresh]: https://github.com/wikimedia/fresh
199 [api-dedicated]: https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
201 ## Modify the development environment
203 You can override the default services from a `docker-compose.override.yml`
204 file, and make use of those overrides by changing `LocalSettings.php`.
206 Example overrides and configurations can be found under
207 [MediaWiki-Docker on mediawiki.org][mw-docker].
209 After updating `docker-compose.override.yml`, run `docker compose down`
210 followed by `docker compose up -d` for changes to take effect.
212 ### Install extra packages
214 If you need root on the container to install system packages with `apt-get` for
215 troubleshooting, you can open a shell as root with
216 `docker compose exec --user root mediawiki bash`.
218 ### Install extensions and skins
220 To install an extension or skin, follow the instructions of the mediawiki.org
221 page for the extension or skin in question, and look for any dependencies
222 or additional steps that may be needed.
224 For most extensions, only two steps are needed: download the code to the
225 right directory, and then enable the component from `LocalSettings.php`.
227 To install the Vector skin:
229 1. Clone the skin:
230     ```sh
231     cd skins/
232     git clone https://gerrit.wikimedia.org/r/mediawiki/skins/Vector
233     ```
235 2. Enable the skin, by adding the following to `LocalSettings.php`:
236     ```php
237     wfLoadSkin( 'Vector' );
238     ```
240 To install the EventLogging extension:
242 1. Clone the extension repository:
244     ```sh
245     cd extensions/
246     git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/EventLogging
247     ```
249     Alternatively, if you have extension repositories elsewhere on disk, mount each one as an overlapping volume in
250     `docker-compose.override.yml`. This is comparable to a symlink, but those are not well-supported in Docker.
252     ```yaml
253    services:
254      mediawiki:
255        volumes:
256          - ~/Code/EventLogging:/var/www/html/w/extensions/EventLogging:cached
257     ```
259 2. Enable the extension, by adding the following to `LocalSettings.php`:
260     ```php
261     wfLoadExtension( 'EventLogging' );
262     ```
264 ### Xdebug
266 By default, you will need to set `XDEBUG_TRIGGER=1` in the GET/POST, or as an
267 environment variable, to turn on Xdebug for a request.
269 You can also install a browser extension for controlling whether Xdebug is
270 active. See the [official Xdebug Step Debugging][step-debug], particularly the
271 "Activating Step Debugging" section, for more details.
273 [step-debug]: https://xdebug.org/docs/step_debug
275 If you wish to run Xdebug on every request, you can set
276 `start_with_request=yes` in `XDEBUG_CONFIG` in your .env file:
279 XDEBUG_CONFIG=start_with_request=yes
282 You can pass any of Xdebug's configuration values in this variable. For example:
285 XDEBUG_CONFIG=client_host=192.168.42.34 client_port=9000 log=/tmp/xdebug.log
288 This shouldn't be necessary for basic use cases, but see [the Xdebug settings
289 documentation](https://xdebug.org/docs/all_settings) for available settings.
291 ### Codex
293 You can use your local version of Codex instead of the one bundled with MediaWiki. This is useful
294 when testing how changes in Codex affect Codex-based features in MediaWiki.
296 1. Clone the Codex repository and build Codex, if you haven't done this already:
297     ```sh
298     cd ../
299     git clone https://gerrit.wikimedia.org/r/design/codex
300     cd codex
301     npm run build-all
302     ```
303 2. If your clone of the Codex repository is outside of the MediaWiki directory (this is common),
304    add the following to your `docker-compose.override.yml`. Replace `~/git/codex` with the path to
305    your Codex clone.
307     ```yaml
308    services:
309      mediawiki:
310        volumes:
311          - ~/git/codex:/var/www/html/w/codex:cached
312     ```
313 3. To apply the change to `docker-compose.override.yml`, you have to recreate the environment:
314     ```sh
315     docker compose down
316     docker compose up -d
317     ```
318 4. Enable Codex development mode by adding the following to the bottom of `LocalSettings.php`:
320     ```php
321     $wgCodexDevelopmentDir = MW_INSTALL_PATH . '/codex';
322     ```
324    To disable Codex development mode and use the regular version of Codex, delete or comment out
325    this line.
326 5. Every time you make a change to your local copy of Codex (or download a Gerrit change), you
327    have to rerun Codex's build process for these changes to take effect. To do this, run
328    `npm run build-all` in the Codex directory.
330 ### Stop or recreate environment
332 Stop the environment, perhaps to reduce the load when working on something
333 else. This preserves the containers, to be restarted later quickly with
334 the `docker compose up -d` command.
336 ```sh
337 docker compose stop
340 Destroy and re-create the environment. This will delete the containers,
341 including any logs, caches, and other modifications you may have made
342 via the shell.
344 ```sh
345 docker compose down
346 docker compose up -d
349 ### Re-install the database
351 To empty the wiki database and re-install it:
353 * Remove or rename the `LocalSettings.php` file.
354 * Delete the `cache/sqlite` directory.
355 * Re-run the "Install MediaWiki database" command.
357 You can now restore or copy over any modifications you had in your previous `LocalSettings.php` file.
358 And if you have any additional extensions installed that required a database table, then also run:
359 `docker compose exec mediawiki php maintenance/run.php update`.
361 ## Troubleshooting
363 ### Caching
365 If you suspect a change is not applying due to caching, start by [hard
366 refreshing](https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache) the browser.
368 If that doesn't work, you can narrow it down by disabling various server-side
369 caching layers in `LocalSettings.php`, as follows:
371 ```php
372 $wgMainCacheType = CACHE_NONE;
373 $wgMessageCacheType = CACHE_NONE;
374 $wgParserCacheType = CACHE_NONE;
375 $wgResourceLoaderMaxage = [
376   'versioned' => 0,
377   'unversioned' => 0
381 The default settings of MediaWiki are such that caching is smart and changes
382 propagate immediately. Using the above settings may slow down your wiki
383 significantly. Especially on macOS and Windows, where Docker Desktop uses
384 a VM internally and thus has longer file access times.
386 See [Manual:Caching][manual-caching] on mediawiki.org for more information.
388 [manual-caching]: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Caching
390 ### Xdebug ports
392 Older versions of Xdebug used port 9000, which could conflict with php-fpm
393 running on the host. This document used to recommend a workaround of telling
394 your IDE to listen on a different port (e.g., 9009) and setting
395 `XDEBUG_CONFIG=remote_port=9009` in your `.env`.
397 Xdebug 3.x now uses the `client_port` value, which defaults to 9003. This
398 should no longer conflict with local php-fpm installations, but you may need
399 to change the settings in your IDE or debugger.
401 ### Linux desktop, host not found
403 The image uses `host.docker.internal` as the `client_host` value which
404 should allow Xdebug work for Docker for Mac/Windows.
406 On Linux, you need to create a `docker-compose.override.yml` file with the following
407 contents:
409 ```yaml
410 services:
411   mediawiki:
412     extra_hosts:
413       - "host.docker.internal:host-gateway"
416 With the latest version of Docker on Linux hosts, this _should_ work
417 transparently as long as you're using the recommended
418 `docker-compose.override.yml`. If it doesn't, first check `docker version` to
419 make sure you're running Docker 20.10.2 or above, and `docker compose version`
420 to make sure it's 1.27.4 or above.
422 If Xdebug still doesn't work, try specifying the hostname or IP address of your
423 host. The IP address works more reliably. You can obtain it by running e.g.
424 `ip -4 addr show docker0` and copying the IP address into the config in `.env`,
425 like `XDEBUG_CONFIG=remote_host=172.17.0.1`
427 ### Generating logs
429 Switching on the remote log for Xdebug comes at a performance cost so only
430 use it while troubleshooting. You can enable it like so: `XDEBUG_CONFIG=remote_log=/tmp/xdebug.log`
432 ### "(Permission Denied)" errors on running docker compose
434 See if you're able to run any docker commands to start with. Try running
435 `docker container ls`, which should also throw a permission error. If not,
436 go through the following steps to get access to the socket that the docker
437 client uses to talk to the daemon.
439 `sudo usermod -aG docker $USER`
441 And then `relogin` (or `newgrp docker`) to re-login with the new group membership.
443 ### "(Cannot access the database: Unknown error (localhost))"
445 The environment's working directory has recently changed to `/var/www/html/w`.
446 Reconfigure this in your `LocalSettings.php` by ensuring that the following
447 values are set correctly:
449 ```php
450 $wgScriptPath = '/w';
451 $wgSQLiteDataDir = "/var/www/html/w/cache/sqlite";
454 ### Windows users, "(Cannot access the database: No database connection (unknown))"
456 The permissions with the `cache/sqlite` directory have to be set manually on Windows:
458 ```sh
459 docker compose exec mediawiki chmod -R o+rwx cache/sqlite
462 ### Linux users, "(Cannot access the database: No database connection (localhost))"
464 Make sure you have the `MW_DOCKER_UID` and `MW_DOCKER_GID` set in your `.env` file (instructions above).