FileBackend::isStoragePath() Handle being passed null
[mediawiki.git] / DEVELOPERS.md
blob6176c5f50cfc9c4488ac1b5e1968dbaaf25fece8
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, Apache, Xdebug and a SQLite database.
11 **Do not use the development environment to serve a public website! Bad things would happen!**
13 More documentation, examples, and configuration recipes are available at [mediawiki.org/wiki/MediaWiki-Docker][mw-docker].
15 Support is available on the [Libera IRC network][libera-home] in the [`#mediawiki` channel][libera-webchat], and on Phabricator by creating tasks with the [MediaWiki-Docker][mw-docker-phab] tag.
17 [mw-docker]: https://www.mediawiki.org/wiki/MediaWiki-Docker
18 [mw-docker-phab]: https://phabricator.wikimedia.org/tag/mediawiki-docker/
19 [libera-home]: https://libera.chat/
20 [libera-webhcat]: https://web.libera.chat/#mediawiki
22 ## Quickstart
24 ### 1. Requirements
26 You'll need to have Docker installed:
28 * [Docker Desktop][docker-install] for macOS or Windows.
29 * [docker][docker-linux] and [docker-compose][docker-compose] for Linux.
31 [docker-install]: https://docs.docker.com/get-docker/
32 [docker-linux]: https://docs.docker.com/engine/install/
33 [docker-compose]: https://docs.docker.com/compose/install/
35 **Linux users**:
37 * We recommend installing `docker-compose` by [downloading the binary
38   release][dc-release]. You can also use `pip`, your OS package manager, or
39   even run it in a container, but downloading the binary release is the easiest
40   method.
41 * Follow the instructions to ["Manage Docker as a non-root user"][dc-non-root]
43 [dc-release]: https://docs.docker.com/compose/install/#install-compose-on-linux-systems
44 [dc-non-root]: https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user
46 ### 2. Prepare `.env` file
48 Using a text editor, create a `.env` file in the root of the MediaWiki core
49 repository, and copy these contents into that file:
51 ```sh
52 MW_SCRIPT_PATH=/w
53 MW_SERVER=http://localhost:8080
54 MW_DOCKER_PORT=8080
55 MEDIAWIKI_USER=Admin
56 MEDIAWIKI_PASSWORD=dockerpass
57 XDEBUG_CONFIG=
58 XDEBUG_ENABLE=true
59 XHPROF_ENABLE=true
60 ```
62 Next, run the following command to add your user ID and group ID to your `.env` file:
64 ```sh
65 echo "MW_DOCKER_UID=$(id -u)
66 MW_DOCKER_GID=$(id -g)" >> .env
67 ```
69 Linux users: If you'd like to use Xdebug features inside your IDE, then create a `docker-compose.override.yml` file as well:
71 ```yaml
72 version: '3.7'
73 services:
74   mediawiki:
75     # For Linux: This extra_hosts section enables Xdebug-IDE communication:
76     extra_hosts:
77       - "host.docker.internal:host-gateway"
78 ```
80 ### 3. Create the environment
82 * Start the containers:
83   ```sh
84   docker-compose up -d
85   ```
86   The "up" command makes sure that the PHP and webserver containers are running (and any others in the `docker-compose.yml` file). It is safe to run at any time, and will do nothing if the containers are already running.
88   The first time, it may take a few minutes to download new Docker images.
90   The `-d` argument stands for "detached" mode, which run the services in the background. If you suspect a problem with one of the services, you can run it without `-d` to follow the server logs directly from your termimnal. You don't have to stop the services first, if you ran it with `-d` and then without, you'll get connected to the already running containers including a decent backscroll of server logs.
92   Note that MediaWiki debug logs go to `/cache/*.log` files (not sent to docker).
94 * Install PHP dependencies from Composer:
95   ```sh
96   docker-compose exec mediawiki composer update
97   ```
99 * Install MediaWiki:
100   ```sh
101   docker-compose exec mediawiki /bin/bash /docker/install.sh
102   ```
104 Done! The wiki should now be available for you at <http://localhost:8080>.
106 ## Usage
108 ### Running commands
110 You can use `docker-compose exec mediawiki bash` to open a bash shell in the
111 MediaWiki container. You can then run one or more commands as needed and stay
112 within the container shell.
114 You can also run a single command in the container directly from your host
115 shell, for example: `docker-compose exec mediawiki php maintenance/update.php`.
117 ### PHPUnit
119 Run a single PHPUnit file or directory:
121 ```sh
122 docker-compose exec mediawiki bash
123 instance:/w$ cd tests/phpunit
124 instance:/w/tests/phpunit$ php phpunit.php path/to/my/test/
127 See [PHPUnit on mediawiki.org][phpunit-testing] for more examples.
129 [phpunit-testing]: https://www.mediawiki.org/wiki/Manual:PHP_unit_testing/Running_the_tests
131 ### Selenium
133 You can use [Fresh][fresh] to run [Selenium in a dedicated
134 container][selenium-dedicated]. Example usage:
136 ```sh
137 fresh-node -env -net
138 npm ci
139 npm run selenium-test
142 [selenium-dedicated]: https://www.mediawiki.org/wiki/Selenium/Getting_Started/Run_tests_using_Fresh
144 ### API Testing
146 You can use [Fresh][fresh] to run [API tests in a dedicated
147 container][api-dedicated]. Example usage:
149 ```sh
150 export MW_SERVER=http://localhost:8080/
151 export MW_SCRIPT_PATH=/w
152 export MEDIAWIKI_USER=Admin
153 export MEDIAWIKI_PASSWORD=dockerpass
154 fresh-node -env -net
155 # Create .api-testing.config.json as documented on
156 # https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
157 npm ci
158 npm run api-testing
161 [fresh]: https://github.com/wikimedia/fresh
162 [api-dedicated]: https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
164 ## Modify the development environment
166 You can override the default services from a `docker-compose.override.yml`
167 file, and make use of those overrides by changing `LocalSettings.php`.
169 Example overrides and configurations can be found under
170 [MediaWiki-Docker on mediawiki.org][mw-docker].
172 After updating `docker-compose.override.yml`, run `docker-compose down`
173 followed by `docker-compose up -d` for changes to take effect.
175 ### Install extra packages
177 If you need root on the container to install system packages with `apt-get` for
178 troubleshooting, you can open a shell as root with
179 `docker-compose exec --user root mediawiki bash`.
181 ### Install extensions and skins
183 To install an extension or skin, follow the intructions of the mediawiki.org
184 page for the extension or skin in question, and look for any dependencies
185 or additional steps that may be needed.
187 For most extensions, only two steps are needed: download the code to the
188 right directory, and then enable the component from `LocalSettings.php`.
190 To install the Vector skin:
192 1. Clone the skin:
193     ```sh
194     cd skins/
195     git clone https://gerrit.wikimedia.org/r/mediawiki/skins/Vector
196     ```
198 2. Enable the skin, by adding the following to `LocalSettings.php`:
199     ```php
200     wfLoadSkin( 'Vector' );
201     ```
203 To install the EventLogging extension:
205 1. Clone the extension repository:
207     ```sh
208     cd extensions/
209     git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/EventLogging
210     ```
212     Alternatively, if you need to extension repositories elsewhere on disk, mount each one as a overlapping volume in `docker-compose.override.yml`. The is comparable to a symlink, but those are not well-supported in Docker.
214     ```yaml
215    version: '3.7'
216    services:
217      mediawiki:
218        volumes:
219          - ~/Code/Vector:/var/www/html/w/skins/vector:cached
220     ```
222 2. Enable the extension, by adding the following to `LocalSettings.php`:
223     ```php
224     wfLoadExtension( 'EventLogging' );
225     ```
227 ### Xdebug
229 By default, you will need to set `XDEBUG_TRIGGER=1` in the GET/POST, or as an
230 environment variable, to turn on Xdebug for a request.
232 You can also install a browser extension for controlling whether Xdebug is
233 active.  See the [official Xdebug Step Debugging][step-debug], particularly the
234 "Activating Step Debugging" section, for more details.
236 [step-debug]: https://xdebug.org/docs/step_debug
238 If you wish to run Xdebug on every request, you can set
239 `start_with_request=yes` in `XDEBUG_CONFIG` in your .env file:
242 XDEBUG_CONFIG=start_with_request=yes
245 You can pass any of Xdebug's configuration values in this variable.  For example:
248 XDEBUG_CONFIG=client_host=192.168.42.34 client_port=9000 log=/tmp/xdebug.log
251 This shouldn't be necessary for basic use cases, but see [the Xdebug settings
252 documentation](https://xdebug.org/docs/all_settings) for available settings.
254 ### Stop or recreate environment
256 Stop the environment, perhaps to reduce load when working on something
257 else. This preserves the containers, to be restarted later quickly with
258 the `docker-compose up -d` command.
260 ```sh
261 docker-compose stop
264 Destroy and re-create the environment. This will delete the containers,
265 including any logs, caches, and other modifications you may have made
266 via the shell.
268 ```sh
269 docker-compose down
270 docker-compose up -d
273 ### Re-install the database
275 To empty the wiki database and re-install it:
277 * Remove or rename the `LocalSettings.php` file.
278 * Delete the `cache/sqlite` directory.
279 * Re-run the "Install MediaWiki database" command.
281 You can now restore or copy over any modifications you had in your previous `LocalSettings.php` file. And if you have additonal extensions installed that required a database table, then also run: `docker-compose exec mediawiki php maintenance/update.php`.
283 ## Troubleshooting
285 ### Caching
287 If you suspect a change is not applying due to caching, start by [hard
288 refreshing](https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache) the browser.
290 If that doesn't work, you can narrow it down by disabling various server-side
291 caching layers in `LocalSettings.php`, as follows:
293 ```php
294 $wgMainCacheType = CACHE_NONE;
295 $wgMessageCacheType = CACHE_NONE;
296 $wgParserCacheType = CACHE_NONE;
297 $wgResourceLoaderMaxage = [
298   'versioned' => 0,
299   'unversioned' => 0
303 The default settings of MediaWiki are such that caching is smart and changes
304 propagate immediately. Using the above settings may slow down your wiki
305 significantly. Especially on macOS and Windows, where Docker Desktop uses
306 a VM internally and thus has longer file access times.
308 See [Manual:Caching][manual-caching] on mediawiki.org for more information.
310 [manual-caching]: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Caching
312 ### Xdebug ports
314 Older versions of Xdebug used port 9000, which could conflict with php-fpm
315 running on the host.  This document used to recommend a workaround of telling
316 your IDE to listen on a different port (e.g. 9009) and setting
317 `XDEBUG_CONFIG=remote_port=9009` in your `.env`.
319 Xdebug 3.x now uses the `client_port` value, which defaults to 9003.  This
320 should no longer conflict with local php-fpm installations, but you may need
321 to change the settings in your IDE or debugger.
323 ### Linux desktop, host not found
325 The image uses `host.docker.internal` as the `client_host` value which
326 should allow Xdebug work for Docker for Mac/Windows.
328 On Linux, you need to create a `docker-compose.override.yml` file with the following
329 contents:
331 ```yaml
332 version: '3.7'
333 services:
334   mediawiki:
335     extra_hosts:
336       - "host.docker.internal:host-gateway"
339 With the latest version of Docker on Linux hosts, this _should_ work
340 transparently as long as you're using the recommended
341 `docker-compose.override.yml`.  If it doesn't, first check `docker version` to
342 make sure you're running Docker 20.10.2 or above, and `docker-compose version`
343 to make sure it's 1.27.4 or above.
345 If Xdebug still doesn't work, try specifying the hostname or IP address of your
346 host. The IP address works more reliably.  You can obtain it by running e.g.
347 `ip -4 addr show docker0` and copying the IP address into the config in `.env`,
348 like `XDEBUG_CONFIG=remote_host=172.17.0.1`
350 ### Generating logs
352 Switching on the remote log for Xdebug comes at a performance cost so only
353 use it while troubleshooting. You can enable it like so: `XDEBUG_CONFIG=remote_log=/tmp/xdebug.log`
355 ### "(Permission Denied)" errors on running docker-compose
357 See if you're able to run any docker commands to start with. Try running
358 `docker container ls`, which should also throw a permission error. If not,
359 go through the following steps to get access to the socket that the docker
360 client uses to talk to the daemon.
362 `sudo usermod -aG docker $USER`
364 And then relogin (or `newgrp docker`) to re-login with the new group membership.
366 ### "(Cannot access the database: Unknown error (localhost))"
368 The environment's working directory has recently changed to `/var/www/html/w`.
369 Reconfigure this in your `LocalSettings.php` by ensuring that the following
370 values are set correctly:
372 ```php
373 $wgScriptPath = '/w';
374 $wgSQLiteDataDir = "/var/www/html/w/cache/sqlite";