Deployment and security
A Joomla site is a folder of files and a database. Moving it to a server is not hard, but before launch the site must be switched to production mode and checked against a list: most Joomla break-ins happen because of forgotten updates and careless settings.
Moving the site
- Copy all site files to the server.
- Dump the local database and load it into the database on the server.
- Fix the connection settings in the
configuration.phpfile in the site root.
// configuration.php
public $host = 'localhost';
public $db = 'joomla_prod';
public $user = 'joomla_user';
public $password = 'a-strong-password';
public $dbprefix = 'abc12_';
public $log_path = '/var/www/site/administrator/logs';
public $tmp_path = '/var/www/site/tmp';These are properties of the JConfig class. After the edit open the site: it should work the same as locally. The log_path and tmp_path paths must point to folders on the new server.
Folder permissions
The web server needs write access to the folders tmp, cache, administrator/cache, administrator/logs, images and media. Read access is enough for the other files. You can check everything at once in the panel: System → System Information, the Folder Permissions tab.
Production settings
In System → Global Configuration:
| Setting | Tab | Value |
|---|---|---|
| Debug System | System | No |
| Debug Language | System | No |
| Error Reporting | Server | None or System Default |
| Force HTTPS | Server | Entire Site |
| System Cache | System | On |
| Gzip Page Compression | Server | Yes |
| Search Engine Friendly URLs | Site | Yes |
For URL rewriting on Apache rename the htaccess.txt file in the site root to .htaccess.
Site security
| Measure | Why |
|---|---|
| Update Joomla and extensions | Most break-ins use vulnerabilities fixed long ago |
| Remove unused extensions | A disabled extension is still on disk and may be vulnerable |
| Multi-factor login for administrators | A stolen password alone is not enough |
| A separate database user for the site | Breaking into one site does not open the other databases |
| Regular backups of files and database | The only way to recover after a failure or a break-in |
| Keep backups off the server | A copy on the same disk is lost together with the site |
Multi-factor login is turned on in the user profile, on the Multi-factor Authentication tab.
Security of your own extensions
The rules from the earlier lessons, gathered together:
| What to check | How |
|---|---|
| Direct access to files | defined('_JEXEC') or die; at the top of every PHP file |
| Output in layouts | $this->escape() or htmlspecialchars() for everything from the database or the user |
| Database queries | Values only through bind(), names through quoteName() |
| Actions that change data | $this->checkToken() in the controller and form.token in the form |
| Permissions | authorise() where the action is performed |
| Request data | Typed methods: getInt(), getString(), getCmd() |
| Form fields | A filter attribute on every field |
Request data is read from the input object, not from $_GET and $_POST:
$input = Factory::getApplication()->getInput();
$id = $input->getInt('id');
$search = $input->getString('q', '');getInt() returns an integer whatever the visitor sent; the second argument is the default value.
After launch
Open the site in a browser window without logging in to the panel and walk through the main pages. Then check the PHP error log on the server and System → Update: both Joomla and the extensions should be at their latest versions.
Common mistake
The local copy of configuration.php is uploaded to the server over the production one — together with debugging turned on and the local database details. The site either fails to connect to the database or shows everyone the debug bar with queries. Keep the production configuration.php separately and exclude this file from transfers when you update code.