ICT:MW Installation procedure 1.43 LTS -v2
Installation Procedure for a New MediaWiki Instance (MediaWiki 1.43 LTS)
This document describes the clean, reproducible workflow for deploying a new MediaWiki instance on the existing 3‑VM infrastructure.
The installation is intentionally split into two phases:
- Phase 1: Local installation and testing on VM1 (Apache on port 8080)
- Phase 2: Public exposure through VM3 (nginx reverse‑proxy + HTTPS)
This staged approach ensures safe testing before the wiki becomes accessible from the internet.
VM Overview
- VM1 (Web Layer): 192.168.33.231
- VM2 (Database Layer): 192.168.33.232
- VM3 (Reverse‑Proxy Layer): 192.168.33.233
- DB user host address (VM1 → VM2): 10.10.10.1
1. Create the Database (VM2 – MariaDB)
All commands in this section run on VM2 (192.168.33.232).
1.1 Connect to MariaDB
mysql -u root -p
1.2 Create the database
CREATE DATABASE newwiki CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
1.3 Create the database user
VM1 connects to MariaDB using its internal DB‑facing address: 10.10.10.1.
CREATE USER 'newwikiuser'@'10.10.10.1' IDENTIFIED BY 'strongpassword';
1.4 Grant privileges
GRANT ALL PRIVILEGES ON newwiki.* TO 'newwikiuser'@'10.10.10.1'; FLUSH PRIVILEGES;
1.5 Exit
EXIT;
2. Prepare the Installation Directory (VM1 – Web Layer)
All commands below run on VM1 (192.168.33.231).
2.1 Create the target directory
mkdir /var/www/newMW
2.2 Move into /var/www
cd /var/www
3. Download MediaWiki
Example: MediaWiki 1.43.8 LTS.
wget https://releases.wikimedia.org/mediawiki/1.43/mediawiki-1.43.8.tar.gz
4. Extract MediaWiki
tar -xvzf mediawiki-1.43.8.tar.gz
5. Move Extracted Files into newMW
mv mediawiki-1.43.8/* newMW/ mv mediawiki-1.43.8/.* newMW/ 2>/dev/null rmdir mediawiki-1.43.8 rm mediawiki-1.43.8.tar.gz
6. Ownership and Permissions
Allows editing via VS Code while keeping Apache functional.
6.1 Set owner and group
chown -R mngr:apache /var/www/newMW
6.2 Ensure group write permissions
chmod -R g+w /var/www/newMW
6.3 Directory/file permissions
find /var/www/newMW -type d -exec chmod 775 {} \;
find /var/www/newMW -type f -exec chmod 664 {} \;
6.4 Enable group inheritance (setgid)
chmod g+s /var/www/newMW
7. Apache Configuration on VM1 (Port 8080)
7.1 Enable Apache to listen on port 8080
Edit:
/etc/httpd/conf/httpd.conf
Add:
Listen 8080
7.2 Validate and restart
apachectl configtest systemctl restart httpd
7.3 Verify Apache is listening
ss -tlnp | grep httpd
Expected:
0.0.0.0:80 0.0.0.0:8080
7.4 Firewall rule (VM1)
Allow port 8080:
firewall-cmd --add-port=8080/tcp --permanent firewall-cmd --reload
7.5 Local‑only Apache VirtualHost
<VirtualHost *:8080>
ServerName newmw.local
DocumentRoot /var/www/newMW
<Directory /var/www/newMW>
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/newmw-local-error.log
CustomLog /var/log/httpd/newmw-local-access.log combined
</VirtualHost>
Restart Apache:
systemctl restart httpd
8. Run the Installer Locally
Access:
http://192.168.33.231:8080http://newmw.local:8080(if added to /etc/hosts)
Internal DB Network Logic (10.10.10.x)
The internal network between VM1 and VM2 uses dedicated addresses:
- VM1 (Web Layer): 10.10.10.1
- VM2 (Database Layer): 10.10.10.2
When MediaWiki (running on VM1) connects to MariaDB on VM2, the connection originates from VM1’s internal NIC. Therefore:
- VM1 connects **to** MariaDB at:
10.10.10.2
- VM2 sees VM1 **coming from**:
10.10.10.1
Because MariaDB authorizes users based on the client’s source address, database users must be created as:
'wikiuser'@'10.10.10.1'
This is why all MediaWiki instances on VM1 use the same host restriction. It ensures that only VM1 can authenticate to MariaDB over the internal network.
Result after installation flow
Installer will generate:
$wgServer = "http://192.168.33.231:8080";
Place LocalSettings.php in:
/var/www/newMW/LocalSettings.php
9. Local Testing
Verify:
- Page creation
- Editing
- File uploads
- User accounts
- Extensions
- Permissions
- Logging
Only proceed when everything works locally.
10. Public Exposure via VM3 (Reverse‑Proxy Layer)
10.1 Create minimal HTTP‑only nginx config (VM3)
File:
/etc/nginx/conf.d/kb.costasano.club.conf
# ============================================
# Reverse proxy (HTTP only)
# kb.costasano.club
# ============================================
server {
listen 80;
listen [::]:80;
server_name kb.costasano.club;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
proxy_pass http://192.168.33.231:8080;
proxy_set_header Host kb.costasano.club;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
}
}
Reload nginx:
sudo nginx -t
sudo systemctl reload nginx
11. Issue the Certificate (VM3)
Use the nginx plugin:
sudo certbot --nginx -d kb.costasano.club
Certbot will:
- inject temporary ACME config
- validate the domain
- obtain the certificate
- install it
- register it for renewal
12. Replace with Full HTTPS Reverse‑Proxy (VM3)
# ============================================
# Reverse proxy (HTTPS)
# kb.costasano.club
# ============================================
# --- HTTP (redirect + ACME) ---
server {
listen 80;
listen [::]:80;
server_name kb.costasano.club;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
return 301 https://$host$request_uri;
}
# --- HTTPS ---
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name kb.costasano.club;
ssl_certificate /etc/letsencrypt/live/kb.costasano.club/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kb.costasano.club/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
proxy_pass http://192.168.33.231:8080;
proxy_set_header Host kb.costasano.club;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_buffering on;
proxy_buffers 16 16k;
proxy_buffer_size 16k;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
Reload nginx:
sudo nginx -t
sudo systemctl reload nginx
13. Update LocalSettings.php for Public Access
Change:
$wgServer = "https://kb.costasano.club";
Optional:
$wgCanonicalServer = "https://kb.costasano.club";
14. Final Verification
curl -I https://kb.costasano.clubreturns 200 or 301- Browser loads the wiki
- Editing works
- Uploads work
- No rewrite errors
- nginx proxies correctly
- MariaDB connections succeed
15. Login Issues After Changing LocalSettings.php
MediaWiki is very sensitive to stale cookies and cached sessions, especially after changing settings such as:
- $wgServer
- $wgCookieSecure
- $wgCookieSameSite
- $wgUseReverseProxy
- $wgUseCdn
If login suddenly fails or a Captcha appears even though no Captcha extension is enabled, the cause is usually old browser cookies.
Fix: open the wiki in a private/incognito window or clear cookies for the domain. This forces MediaWiki to create a fresh session and resolves the issue.
Differences Between MediaWiki 1.43 and 1.45 (Login, Captcha, Reverse‑Proxy)
MediaWiki 1.43 and 1.45 behave differently when installed behind a reverse‑proxy such as nginx. This affects login, session cookies, and the appearance of the “phantom Captcha” (a throttle challenge that cannot be solved).
MediaWiki 1.45 (more tolerant)
MediaWiki 1.45 includes improved session and cookie handling. It automatically:
- detects HTTPS behind a reverse‑proxy
- regenerates session cookies when needed
- accepts SameSite=None cookies more reliably
- avoids triggering login throttling on fresh installs
As a result, MediaWiki 1.45 usually works immediately behind nginx without showing any Captcha or blocking logins.
MediaWiki 1.43 (stricter behaviour)
MediaWiki 1.43 uses older, stricter session logic. If any of the following are misconfigured:
- $wgServer
- $wgCookieSecure
- $wgCookieSameSite
- $wgUseReverseProxy
- $wgUseCdn
- missing $wgCdnServers entry
…MediaWiki may fail to create a valid login session. When this happens, it displays a Captcha-like box even though no Captcha extension is enabled. This is not a real Captcha but the built‑in login throttle, and it always fails.
Why this did not happen on the previous install
The earlier wiki was installed on MediaWiki 1.45, which is more forgiving of reverse‑proxy setups. MediaWiki 1.43 requires explicit configuration to trust the proxy and accept secure cookies.
Fix
Add the following lines to LocalSettings.php:
$wgUseCdn = true; $wgUseReverseProxy = true; $wgCdnServers = [ "192.168.33.233" ]; # nginx reverse-proxy $wgCookieSecure = true; $wgCookieSameSite = "None";
If login still fails, clear browser cookies or open the wiki in a private window to force a fresh session.
16. Summary
This procedure installs MediaWiki in two safe phases:
- Phase 1: Local installation and validation on VM1
- Phase 2: Public exposure through VM3 with HTTPS
This ensures a clean, reproducible, low‑risk deployment workflow.
Apache fails to start after adding a new Listen port (SELinux)
When adding a new Apache Listen directive on AlmaLinux (e.g. Listen 8081 or Listen 8888),
httpd may refuse to start even though apachectl configtest reports Syntax OK.
Typical symptoms:
httpddoes not restart after adding a new portconfigtestshows no errorsjournalctl -xeor/var/log/audit/audit.logcontains an AVC denial similar to:
type=AVC msg=audit(...): avc: denied { name_bind } for pid=XXXX comm="httpd" \
scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:unreserved_port_t:s0 \
tclass=tcp_socket permissive=0
Cause
SELinux only allows Apache (httpd_t) to bind to ports labeled as http_port_t.
By default, this includes ports such as 80, 443, 8008, 8009, 8443, and sometimes 8080.
Any new port (e.g. 8081, 8888) is labeled as unreserved_port_t and is therefore blocked by SELinux.
Apache reports this as a binding failure, often misleadingly shown as:
No such device or address
Check which ports Apache is allowed to use
semanage port -l | grep http_port_t
Fix: allow Apache to bind to the new port
Add the port to the SELinux http_port_t type:
sudo semanage port -a -t http_port_t -p tcp 8081 sudo semanage port -a -t http_port_t -p tcp 8888
If the port already exists under a different SELinux type, modify it instead:
sudo semanage port -m -t http_port_t -p tcp 8081
Restart Apache
sudo systemctl restart httpd
Apache will now start normally and bind to the newly added port.
Notes for maintainers
- This behaviour is normal on RHEL/AlmaLinux systems with SELinux in enforcing mode.
- Always document newly opened ports in the infrastructure notes to avoid confusion for successors.
- Avoid disabling SELinux; adjusting port labels is the correct and safe approach.