Ubuntu web host
This chapter shows how to set up a LAMP stack on Ubuntu, suitable for a website or multiple vhosts, all with a suitable environment for running the Drupal or Grav.
Table of contents
- Introduction
- Install and enable Apache
- Install MySQL
- Install PHP
- Install phpMyAdmin
- Install miscellaneous package managers
- Install additional software globally
- Install composer
- Install webpack
- Test your configuration
- User administration
- Troubleshooting
- Final word
Introduction
This chapter assumes that you've already set up an Ubuntu instance on either a physical server, or a virtual cloud server (e.g. a DigitalOcean droplet). Inital set up of an instance is described in separate chapters:
shows how to set up a LAMP stack on Ubuntu 16.04 LTS, 18.04 LTS and 20.04 LTS, suitable for a website or multiple vhosts, all with a suitable environment for running the Drupal WCMS or the Grav WCMS.[Mumble]
CLI access to the web server
To learn about how to gain access to the web server's command line interface (CLI). see the section in “Unix notes” about using a terminal emulator.
Check for upgrades
After logging in to the CLI it is recommended that you check that the release you are running is up to date.
You do this by first updating the package list, look through the list of packages that can be upgraded, and then upgrade all packages. You do this with the following sequence of commands:
$ sudo apt update […] $ sudo apt list --upgradable […] $ sudo apt upgrade […]
To make your upgrade effective, you need to reboot:
$ sudo shutdown -r now
You may have to redo this from time to time to keep your configuration current.
The
command apt update
updates the list of available packages
and their versions, but it does not install or upgrade any packages.
After updating the lists, the package manager knows about available
updates for your configuration.
The command apt list --upgradable
will list these
packages.
The command apt upgrade
will perform all pending
non-distruptive upgrades. However, it will not perform upgrades that
requires installing, replacing and/or removing other packages.
Instead, it will say that those upgrades are being “kept back”.
To force those upgrades, you can use the command apt
full-upgrade
(previous: apt-get
dist-upgrade
). This command will perform
all pending upgrades and their dependencies. I.e. it
will install, replace and remove packages as required to force the
upgrade. This can be quite dangerous, as such changes may break
backwards compatility and change your system's behaviour.
In worst case, doing a full upgrade could leave you with a broken
system.
Removing packages
To remove a package that is installed globally, that you no longer neeed, and purge its configuration files, you may use these commands:
$ sudo apt remove package $ sudo apt --purge remove package $ sudo apt autoremove package $ sudo apt --purge autoremove package
The first pair of commands will remove the package and purge its configuration files if it was directly installed with apt. The second pair of commands will do the same if it was installed as an dependency, and is no longer needed.
Source: AskUbuntu.
Install and enable Apache
Make sure you always install Apache before PHP.
$ sudo apt update $ sudo apt install apache2 … $ apache2 -v Server version: Apache/2.4.54 (Ubuntu) Server built: 2022-07-21T19:38:00
At the end of the installation process, Ubuntu starts Apache. The web server should already be up and running.
We can check with the systemd
init system to make sure
the service is running by typing:
$ service apache2 status apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: e…) Active: active (running) since Fri 2020-05-01 13:47:40 UTC; 2min 49s ago Docs: https://httpd.apache.org/docs/2.4/ Main PID: 1773 (apache2) Tasks: 55 (limit: 2345) Memory: 5.2M CGroup: /system.slice/apache2.service ├─1773 /usr/sbin/apache2 -k start ├─1775 /usr/sbin/apache2 -k start └─1776 /usr/sbin/apache2 -k start …
Check that the configuration is OK. Just after installing Apacahe2 you may get the following::
$ sudo apache2ctl configtest AH00558: apache2: Could not reliably determine the server's fully qualified domain \ name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this \ message
To fix it put the following line in “ServerName
localhost
” in /etc/apache2/apache2.conf
, near the
end, like this:
# Include generic snippets of statements IncludeOptional conf-enabled/*.conf ServerName localhost # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Rerun the configtest. You should get this:
$ sudo apache2ctl configtest Syntax OK
To see the version of Apache the server is running, use one the following commands. The second one also provides compile info.
$ apache2ctl -v Server version: Apache/2.4.41 (Ubuntu) Server built: 2020-04-13T17:19:17 $ sudo apache2ctl -V Server version: Apache/2.4.41 (Ubuntu) Server built: 2020-04-13T17:19:17 Server's Module Magic Number: 20120211:88 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/etc/apache2" -D SUEXEC_BIN="/usr/lib/apache2/suexec" -D DEFAULT_PIDLOG="/var/run/apache2.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="mime.types" -D SERVER_CONFIG_FILE="apache2.conf"
To test your web server, type its domain name in a browser's address field.
If you haven't cobfigured the DNS yet, first get its public IP-address from the CLI. Examples:
$ curl ifconfig.me 192.0.2.0.12 … $ hostname -I 192.0.2.0.12 …
You can convert the IP-address to a URL
(e.g. http://192.0.2.0.12
) and use it in the address
field of your web browser.
If your web server is working, you should see the Apache2 Default Page and the text: "It works!"
Manage Apache
Prior to introduction of systemctl in Ubuntu 16, service was a wrapper for a number of scripts to start, stop and examine various services. Now service is a wrapper for systemctl as well. For good measure, there is also apache2ctl command that interacts with the Apache server using the CLI. It works for some (but not all) these contexts. In some contexts, it is the only command that works, in other contexts of works differently.
Below, all these are shown, but the systemctl version will only work on Ubuntu 16 and later.
To display the status of your web server, as perceived by the service manager, you can type:
$ systemctl status apache2 $ service apache2 status
Alternatvely, you can check status using apache2ctl:
$ apache2ctl status $ apache2ctl fullstatus
To stop your web server, you can type:
$ sudo systemctl stop apache2 $ sudo service apache2 stop $ sudo apache2ctl stop
To start the web server when it is stopped, type:
$ sudo systemctl start apache2 $ sudo service apache2 start $ sudo apache2ctl start
To stop and then start the service again, type:
$ sudo systemctl restart apache2 $ sudo service apache2 restart $ sudo apache2ctl restart
If you are simply making configuration changes, Apache can often reload without dropping connections. To do this, you can use this command for a graceful reload:
$ sudo systemctl reload apache2 $ sudo service apache2 reload $ sudo apache2ctl graceful
By default, Apache is configured to start automatically when the server boots. If this is not what you want, you can disable this behavior by typing:
$ sudo systemctl disable apache2 $ sudo service apache2 disable
To re-enable the service to start up at boot, you can use this command:
$ sudo systemctl enable apache2 $ sudo service apache2 enable
Check configuration.
$ sudo apache2ctl configtest
Enable site example.com.
$ sudo a2ensite example.com
Disable site example.com.
$ sudo a2dissite example.com
Enable Apache mod_rewrite
You can inspect /etc/apache2/mods-enabled/
to
see what modules are enabled.
In order to have clean URLs with Drupal, it is necessary to enable an extension to the Apache web-server known as mod_rewrite. You do this with the following pair of shell commands:
$ sudo a2enmod rewrite $ sudo systemctl restart apache2
You will also need to add the following directive for the
directories where you want .htaccess
to override the
defaults:
AllowOverride All
See, for example, the section about phpMyAdmin access control.
Set up a virtual host
To be able to create directories on the web server without having
to use sudo, it is recommended to change the ownership of the
direcory /var/www
. Example for a webmaster with userame "bob":
$ sudo chown bob.www-data /var/www
To set up a vhost with the domain name “example.com”, you need to change DNS for this domain to point to your web server. Set up DNS for aliases as well (e.g. “www.example.com”).
Then, on your web server, create a webroot for the domain.
$ mkdir -p /var/www/example.com/web
If necessary, change ownership and group for this directory to allow the development team to have write access to it.
If this is the first vhost on this web server, navigate
to /etc/apache2/sites-available
and copy the file
named 000-default.conf
to example.com.conf
.
The copy will look like this (with the comments removed):
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Change the “ServerAdmin” directive to an email-address that the real site administrator can receive emails through.
After this, you need to add two directives. The first, called “ServerName”, establishes the base domain that should match for this vhost definition. This will most likely be your domain. The second, called “ServerAlias”, defines further names that should match as if they were the base name. This is useful for matching host aliases you defined, like “www”.
The only other thing we need to change for a basic vhost file is
the location of the document root for this domain by setting
the DocumentRoot
directive to the correct path.
<VirtualHost *:80> ServerAdmin admin@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/web ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
So far, we have a basic vhost file that can be used for a basic website.
For Drupal, we also need to add a directory block and allow overrides. To not block any IP addresses use the directive “Require all granted”. (See Apache access control.)
Then, we need to protect some sensitive files in the
Drupal or Grav root that may exist from being viewed by a web client. For
instance, the file CHANGELOG.txt
or CHANGELOG.md
that is installed along
with Drupal or Grav will reveal what version of the WCMS the site is running.
An attacker will want to look at this file just to see if the version
is vulnerable to certain exploits. A backup file is often saved when
a file is edited. Some text editors (e.g. emacs make backup
copies automatically, appending a ~
(tilde) to the end of
the file name. Unless these files are protected, an attacker may
probe for settings.php~
and learn your database
credentials.
The modified vhost configuration file for Drupal should now look like this:
<VirtualHost *:80> ServerAdmin admin@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/web ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined <Directory /var/www/example.com/html> Options FollowSymLinks AllowOverride All Require all granted </Directory> <Files ~ "CHANGELOG\.txt"> Require all denied </Files> <Files ~ "~"> Require all denied </Files> </VirtualHost>
Enable the vhost configuration file:
$ sudo a2ensite example.com.conf
Check that there are no errors in the newly enabled vhost configuration file:
$ sudo apache2ctl configtest
If there were no errors, you may reload the web server to make the new vhost visible on the web:
$ sudo systemctl reload apache2
Now that you have your first vhost configuration file established, you can create more by copying that file and adjusting it as needed.
Set up HSTS for a virtual host
HTTP Strict Transport Security (HSTS) is a security feature that lets a website tell browsers that it should only be communicated with using HTTPS, instead of using HTTP.
Note that if a certificate fails for a domain or sub-domain, the website will no longer be viewable.
To set up, first make sure that mod_headers
is
enabled. If it is not symlinked
in /etc/apache2/mods-enabled
, do:
$ sudo a2enmod headers
Then put the following three lines in the le-sll.conf
-file for the virtual host:
<VirtualHost *:443> Header always set Strict-Transport-Security \ max-age="63072000; includeSubdomains; preload" </VirtualHost>
Finally, test and reaload Apache:
$ sudo apache2ctl configtest $ sudo systemctl reload apache2
Install MySQL
Now that the web server up and running, it is time to install MySQL. It is a free database management system. Basically, it will organize and provide access to databases where our site can store information.
$ sudo apt update $ sudo apt install mysql-server
During the installation, you may be asked to select and confirm a password for the MySQL root user. This is an administrative account in MySQL that has increased privileges. Make sure you pick a strong one.
After installing you should always use the following CLI command:
$ sudo mysql_secure_installation
With
Ububtu 22.04 LTS, an error will occur when you run the
mysql_secure_installation
script.
See setup instructions
on DigitalOcean
for the steps to get around this.
This will let you set up a password validator, change the root passeword, also give you the option of removing the test database and the anonymous database user (created by default).
After setting up, check that your are able to login to the MySQL monitor as “root”:
$ sudo mysql -e "SELECT CURRENT_USER" +----------------+ | CURRENT_USER | +----------------+ | root@localhost | +----------------+
If
you are denied access a get the following error
(ERROR 1698 (28000): Access denied for user 'root'@'localhost'
),
you either typed the wrong password, or you forgot “sudo”.
The configuration file is usully located
at /etc/my.cnf
or /etc/mysql/my.cnf
.
To run Drupal, it is recommented that you alter the MySQL transaction isolation level:
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;Source DO: Setting the MySQL transaction isolation level.
There is no need to restart MySQL after having installed it, but remember that for any changes made to the configuration to have effect you need to restart MySQL.
Some commands for the mysql service:
$ service mysql status $ sudo /etc/init.d/mysql restart $ sudo systemctl restart mysql
Install PHP
PHP is the component of our setup that will process code to display dynamic content. It can run scripts, connect to the database to get information, and hand the processed content over to the web server to display.
Follow instructions from DigitalOcean.
Ubuntu 22.04 LTS:
$ sudo apt install php $ sudo apt install libapache2-mod-php $ sudo apt install php-mysql $ sudo apt install php-xml $ sudo apt install php-gd $ sudo apt install php-mbstring $ php -v PHP 8.1.7-1ubuntu3.1 (cli) (built: Nov 2 2022 13:39:03) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.7, Copyright (c) Zend Technologies with Zend OPcache v8.1.7-1ubuntu3.1, Copyright (c), by Zend Technologies
Ubuntu 20.04 LTS:
$ sudo apt install php $ php -v PHP 7.4.3 (cli) (built: Mar 26 2020 20:24:23) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
As for
PHP extensions needed
by Drupal core, they are defined in the core's composer.json
-file
–see for example
the file
for Drupal 8.8.x. Look at the “require” section and the keys starting
with “ext-”. If Druapl is installed with composer they will be installed as well.
PHP APCu
Since PHP version 5.5, a data caching module named “APCu” has been available. Unlike its predecessor (named “APC”) it is designed to be used together with “OpCache” (opcode cache).
The following sequence of commands installs and enables it:
$ sudo apt install php-apcu $ sudo phpenmod apcu $ sudo systemctl restart apache2
PHP curl
You may get the following warning:
"Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled."
To fix it install PHP curl:
$ sudo apt install php-curl
No restart is necessary.
PHP library for uploadprogress
The Drupal status page will display this notice:
“Upload progress Not enabled
Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.”
As of June 2021, there is still an active core issue @ Drupal.org discussing the merits of the above warning. My take on this that there is no trivial way to install this library, and it is not really needed. Don't waste time trying to install this library (at least not until clear documentation about how to install it exists).
Managing PHP modules
The configuration files for all installed PHP modules are available
under the /etc/php/PHP_VERSION/mods-available
directory. You can see the number of files with
extension .ini
. The php-common package provides
followings commands to manage PHP modules: phpenmod, phpdismod,
phpquery.
You can define version using -v
to enable/disable
module for that version only.
To locate the PHP initialisation file, either examine the output
from phpinfo()
in a browser. This tells you the version
loaded by the web server. In the CLI, you can use:
$ php -i | fgrep 'Loaded Configuration' Loaded Configuration File => /etc/php/8.2/cli/php.ini
The name of the directory after the PHP version number indicates
the SAPI (Server API) . Several types of SAPI exist. Those available
are in the directory /etc/php/PHP_VERSION
.
Those that comes with Ububtu 18.04 LTS and 20.04 LTS by default are:
apache2, cli. You can use the CLI-option -s
to
enable/disable a module for that SAPI only.
To disable the module mbstring:
$ sudo phpdismod mbstring
To enable the module mbstring for PHP version 8.2 and SAPI apache2:
$ sudo phpenmod -v 8.2 -s apache2 mbstring
You need to restart apache2 to make enabling or disabling effective:
$ sudo systemctl restart apache2
To view status of the module mbstring for PHP 8.2 and the SAPI apache2:
$ phpquery -v 8.2 -s apache2 -m mbstring mbstring (Enabled for apache2 by the maintainer script)
Note that both version and SAPI are required arguments to phpquery.
Set up Apache to prefer PHP files
By default Apache will look first for a file
named index.html
in a requested directory. To
tell our web server to prefer index.php
,
modify /etc/apache2/mods-available/dir.conf
as follows:
<IfModule mod_dir.c> DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm </IfModule>
Restart apache2 to make the change effective:
$ sudo systemctl restart apache2
Changing the PHP version
The following instructions are for changing from PHP 8.1 to PHP 8.2 on Ubuntu version 22.04 LTS + Apache2:
$ sudo a2dismod php8.1 $ sudo a2enmod php8.2 $ sudo service apache2 restart
Note that only one PHP version can be set up for Apache2 on a single vhost. The recipe above is based on: ioecapsule.com: How To Switch Between PHP Version In Ubuntu. The best practice for being able to switch between different PHP version is to set up a Docker based development environment. See: DO: Docker-based solutions overview.
Using ppa:ondrej/php
Before you start, make sure ensure all packages are updated:
$ sudo apt update […] $ sudo apt upgrade […] $ sudo shutdown -r nowTo determine the current version of the default PHP package, do:
$ ls -l /etc/php total 12 drwxr-xr-x 5 root root 4096 Jun 18 2020 7.4 drwxr-xr-x 6 root root 4096 Aug 28 2022 8.1 drwxr-xr-x 6 root root 4096 Jan 5 2023 8.2
Ubuntu 22.04 LTS ships with PHP versions 7.4, 8.1, 8.2 (with version 8.1 being the default). There is no longer a need to use a PPA to install one of these.
If version you want is not yet available, install the ondrej PPA. This archive, maintaned by Ondřej Surý, provides access to all recent versions of PHP.
$ sudo add-apt-repository ppa:ondrej/php […] $ sudo apt update […]
Installing additional PHP modules
After changing version, some PHP-modules may be missing from the default configuration. Check if any of the following are missing and install them if they are.
$ sudo apt install php8.1-xml … $ sudo apt install php8.1-gd … $ sudo apt install php8.1-mysql … $ sudo apt install php8.1-mysqli … $ sudo apt install php8.1-mbstring … $ sudo service apache2 restart
You may even have to enable them for Apache2:
$ sudo phpenmod -v 8.1 -s apache2 xml $ sudo phpenmod -v 8.1 -s apache2 gd $ sudo phpenmod -v 8.1 -s apache2 mysql $ sudo phpenmod -v 8.1 -s apache2 mysqli $ sudo phpenmod -v 8.1 -s apache2 mbstring
Install and Configure PHP-FPM
We now have PHP 8 as the default PHP package for the CLI. To make it work with Apache2, we need install and Configure PHP-FPM
The PHP FastCGI Process Manager (FPM) package enhances web server performance. It accelerates page generation, reduces memory consumption, and increases web server capacity. A special Apache module for FastCGI is required to use FPM.
Install the php-fpm package:
$ sudo apt install php-fpm
Install the associated Apache module.
$ sudo apt install libapache2-mod-fcgid
Confirm the php8.1-fpm service is running.
$ sudo systemctl status php8.1-fpm php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php8.1-fpm.service; enabled; … Active: active (running) since Sun 2022-08-28 15:32:37 UTC; 1min 30s ago Docs: man:php-fpm8.1(8) Main PID: 739 (php-fpm8.1) […]
Enable all the Apache modules required by FPM.
$ sudo a2enmod actions fcgid alias proxy_fcgi
If you have configured a virtual host for your domain, add an FPM
handler to the site's .conf
file. Otherwise, add the
handler to the default 000-default.conf
file. If the site is using
TLS, remember to do this to the prt 433 .conf
as
well.
<VirtualHost *:80> […] <FilesMatch \.php$>: SetHandler proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost" </FilesMatch> […] </VirtualHost>
You need to add an FPM handler for every virtual host before restaring Apache. If you for get this step Apache will no longer work for the site.
Finally, restart the Apache service:
$ sudo systemctl restart apache2
Check that all websites are operational.
Source Linode: How to Install PHP 8 for Apache and NGINX on Ubuntu.
See also DigitalOcean: How To Install PHP 8.1 and Set Up a Local Development Environment on Ubuntu 22.04.
Install phpMyAdmin
See if there is a version already installed:
The PHP program phpMyAdmin is an open source tool that lets a database administrator interact with a MySQL or MariaDB database using of a standard web browser. It supports a wide range of SQL operations, including data base management, inspecting and altering tables, fields, relations, indexes, users, permissions, etc. It also lets you directly execute any SQL statement.
$ dpkg -l phpmyadmin … ii phpmyadmin 4:4.9.5+dfsg1-2 all MySQL web administration tool
To install phpMyAdmin, do the following:
$ sudo apt update $ sudo apt install phpmyadmin
When the install script requests a server for phpmyadmin, select apache2.
When
the prompt appears, apache2 is highlighted, but
not selected. If you do not hit <Space>
to
select Apache2, the installer will not move the necessary files during
installation. Hit <Space>
, <Tab>
,
and then <Enter>
to select Apache2.
Select yes when asked whether to
use dbconfig-common
to set up the phpmyadmin
database (its dbuser is also phpmyadmin). Make sure you pick
a secure password. The credentials for this user is in
config-db.php
in /etc/phpmyadmin
(the phpMyAdmin configuration
directory). The code is in /usr/share/phpmyadmin
.
You should also make sure that the following extensions to Apache are enabled if available:
php-mcrypt
php-mbstring
php-gettext
They live in the
directory /etc/php/X.Y/mods_available
,
where X.Y
is the PHP version number
(7.0
for Ubuntu 16.04 LTS,
7.2
for Ubuntu 18.04 LTS,
7.4
for Ubuntu 20.04 LTS),
8.1
for Ubuntu 22.04 LTS).
To see if it is enabled for the web server, inspect the output
of phpinfo()
that is linked from the Drupal status
report, or use phpquery from the CLI.
Install those that are are available, but not enabled.
See Managing PHP modules above to learn how to use phpquery aend phpenmod.
Since phpMyAdmin provides direct access to the database, along with powerful commands to manipulate its content, it may also be a security risk. An out of date phpMyAdmin installation may contain well-known security vulnerabilities. As with all management software that can be accessed from the web, it is important to keep the installation current with all security releases. You should not install phpMyAdmin on a production site, and you should restrict access to the IP-addresses belonging to PCes in your organization on a staging site.
You also need to add the configuration file for phpMyAdmin
to your Apache
configuration. Edit /etc/apache2/apache2.conf
and add the
following line to the end of the file:
Include /etc/phpmyadmin/apache.conf
You need to restart apache2 to make enabling or disabling effective:
After restarting Apache, you should be able to access
the phpMyAdmin by visiting the
URL /phpmyadmin
.
It is not good idea to use this URL. Since it is the default, it is heavily targeted by bots and hackers.
This URL is set up in /etc/phpmyadmin/apache.conf
, where there by
default there is a line that looks like this:
Alias /phpmyadmin /usr/share/phpmyadmin
This line sets up an alias that says that phpMyAdmin is
found by typing our site's domain name (or IP address), followed
by /phpmyadmin
. to change it to a more obscure alias,
remove or comment out the existing alias assignment and add your
own. For example:
# Alias /phpmyadmin /usr/share/phpmyadmin Alias /nothingtoseehere /usr/share/phpMyAdmin
The alias should be easy to remember, but not easy to guess. It
shouldn't indicate the purpose of the URL location. In the example,
above
/nothingtoseehere
is used.
Save the edited file, and restart Apache.
For defence in depth, you may also want to implement access control to
the phpMyAdmin-directory. In order to do this, you need to enable overrides:
Edit the cofiguration file, and add the
directive in bold within the
<Directory /usr/share/phpmyadmin>
-section of the configuration
file:
<Directory /usr/share/phpmyadmin> Options FollowSymLinks DirectoryIndex index.php AllowOverride All …Afterwards, you'll need to restart Apache for your changes to be recognized:
$ sudo systemctl restart apache2
In the directory /usr/share/phpmyadmin
, create a file
named .htaccess
:
$ touch .htaccess
The .htaccess
-file should contain one or more lines
the one below. It require anyone that access the directory to have at
least one of IPs listed. The IP-address used is just an example. You
must use the actual IP-addresses of the PCs that you and other
developers use to access the web server.
Require ip 192.0.2.0.12
To learn the public IP-adress of the PC your browser runs on, visit WhatIsMyIPAddress.com.
The default configuration (dbconfig-common
)
gives phpMyAdmin access to the database server running
on localhost
. You may add additional database servers to
the server section of config.inc.php
to access remote
database servers using phpMyAdmin. E.g.:
$i++; $cfg['Servers'][$i]['host'] = 'example.com'; $i++; $cfg['Servers'][$i]['host'] = '192.0.2.0.12';
You can now access the web interface of phpMyAdminby by
visiting your server's domain name or public IP address followed by
/phpmyadmin
(e.g. https://example.org/phpmyadmin
).
You will see a log in prompt (unless you are using a PC
whose IP is blocked by .htaccess
).
To autheticate users and to grant access to the database, phpMyAdmin allows four different authentication methods:
- cookie – Prompts for MySQL credentials using its own authentication scheme (default if using
dbconfig-common
). - http – Prompts for MySQL credentials using HTTP basic authentication.
- signon – Uses an external (SSO) application for authentication via a prepared PHP script.
- config – MySQL username and password stored in clear text in the configuration file.
The config method should only be used if the if the server running phpMyAdmin is placed behind a firewall in a secure environment, or some other secure authentication is used to limit access. Otherwise, it is not only dangerous because the MySQL username and password stored in clear text, but also because it does not password-protect phpMyAdmin or the database. Anyone who can access the correct URL is logged directly in and can manipulate the database.
For newer distributions, the default security nodel requires sudo for dbuser root to log in (i.e. phpMyAdmin will not be able to log in as root). Workarounds are discussed on StackOverflow, but it is safer to keep the default security model.
On
Ubuntu 16.04, phpMyAdmin outputs a lot of “Deprecation Notices”.
The cure is described in this answer on AskUbuntu.
On Ubuntu 18.04, phpMyAdmin complains about an error in sql.lib.php
.
The cure is described in this answer on StackOverflow.
Both patches are trivial, and should not have any side-effects.
If the library is automatically upgraded (without the bug fixed), the library must be patched again.
For information about using phpMyadmin, see the chapter about tools for developers.
For more information about phpMyAdmin, including official documentation, user maintained wiki pages and third party tutorials, see phpMyAdmin.net. This site also functions as a portal to various support channels, such as the help forum and mailing lists. Click on the “Support” tab to see an overview of support channels.
Login cookie validity
On Ubuntu. the default login cookie validity for phpMyAdmin is annoyingly short 1440 seconds (24 minutes).
According to several support forums, this should be fixed by having
something like this in /etc/phpmyadmin/config.inc.php
:
$sessionValidity = 3600 * 4; // 4 hours $cfg['LoginCookieValidity'] = $sessionValidity; ini_set('session.gc_maxlifetime', $sessionValidity);
Did this on 2020-08-15. Don't know if it helps.
Some support forum links:
- StackOverflow.com: How to manually set phpMyAdmin login cookie validity time.
- e2enetworks.com (less helpful?)
There used to be a way to set this for the current session through the GUI. This feature was removed in version 4.8.0.
Install miscellaneous package managers
The package mangers listed below are not essential, and you may delay installing them until you need a library they manange.
Check whether npm, a package manager for JavaScript (in particular Node.js) libraries is already installed:
$ type npm -bash: type: npm: not found
If it is not installed, then install it (otherwise, skip this step):
To install npm, use apt, the Ubuntu package manager:
$ sudo apt install npm
The Ubunti package manager provides a slightly dated version, and
for some reason, reinstallations often fails: It looks like it
installs, but the command is not found. An altermative is to first install
nvm
, and then use that to install the latest version of node
:
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash # Fire up a new terminal window to get it on the $PATH. $ nvm install node
This will install it under your home directory.
Source linuxize.com: How to Install Node.js and npm on Ubuntu 20.04.
Check version, and update. The commands are:
$ npm -v 7.17.1 $ sudo npm update $ sudo npm install -g npm@latest $ sudo npm install -g npm
The commands npx and node is also installed:
$ npx -v 6.14.4 $ node -v v10.19.0
In addition to npm, there is n, which users of npm is encouraged to install. It also let you update node. To install latest stable version of npm.
$ sudo npm cache clean -f $ sudo npm install -g n $ sudo n stable
Yet another package manager is bower. Check if it is already installed:
$ type bower -bash: type: bower: not found
If it is not installed, then install it (otherwise, skip this step):
To install bower, use npm:
$ sudo npm install -g bower $ bower -v 1.8.0 $ bower update
Pip is a software tool that helps you install various Python packages on your system.
Before you start, make sure that apt is up to date and upgrade if it is not:
$ sudo apt update … $ sudo apt upgrade …
To install it, you must have universe repository enabled.
Otherwise the installation commands will throw the following error:
“E: Unable to locate package python-pip”. To examine what repositoroes
are enabled you can search the
file: /etc/apt/sources.list
. Example:
$ grep ^deb.*universe$ /etc/apt/sources.list deb http://mirrors.digitalocean.com/ubuntu/ focal universe deb http://mirrors.digitalocean.com/ubuntu/ focal-updates universe deb http://security.ubuntu.com/ubuntu focal-security universe
It it is missing, add it with following command:
$ sudo add-apt-repository universe
To install pip or pip3 do the following:
$ sudo apt install python-pip # Python 2 (Ububtu 18.04 LTS only) $ sudo apt install python3-pip # Python 3
Note that pip for Python 2 is not included in the Ubuntu 20.04 LTS repositories.
Check version:
$ pip3 --version pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
Install additional software globally
You don't need to install all the packages listed below when you first set up a web server. Most of these are development requirements and you may defer installation until you need the package. They are simply put together in this section for easy reference.
Some of the tools described in this section may already be installed as part of the standard distribution you're using. Always check if the software is already installed before trying to install.
Install browser-sync
Browser-Sync is an automation tool that is typically used to make tweaking and testing faster by synchronizing file changes and interactions across many devices.
$ sudo npm install -g browser-sync … $ browser-sync --version 2.26.12
However, if you run browser-sync on a typical web server (i.e. a headless environment) it never completes, but hangs there. Please see: this Drupal.org issue and this question on AskUbuntu.com for a possible solution (not yet).
Install gcc
To install the Gnu c-compiler, install a metapackage called
build-essential
. This installs the compiler and some
related/necessary packages.
$ sudo apt install build-essential
Install git
Git is a distributed version control system that comes pre-installed with Ubuntu 22.04 LTS. Do this check if git is already installed, do this:
$ git --version git version 2.37.2
If it is not installed, then install it by means of apt, the default Ubuntu package manager:
$ sudo apt install git
Install gulp
Gulp is a build tool similar to Unix make. It is used for automation of time-consuming and repetitive tasks involved in web development like CSS pre-processing, minification, concatenation, unit testing, linting, optimization, etc. It is built on node and is written in Javascript.
It requires two files: package.json
(lists the various
plugins for gulp), and gulpfile.js
(script with
the logic to run the tasks).
To install gulp using npm, do:
$ sudo npm install --global gulp-cli … $ gulp --version CLI version: 2.3.0 Local version: 4.0.2
It can also be installed using Ubuntu's standard package manager:
$ sudo apt install gulp … $ gulp --version CLI version: 2.3.0 Local version: 4.0.2
Install CSS pre-processors
If you plan to do any theming, you will probably need a CSS pre-processor.
A pre-processor brings nested rules, variables, mixins, selector inheritance, and more to CSS. Compiling stylesheets written in either less (not an acronym) or sass (Syntactically Awesome StyleSheets) generates standard CSS and makes stylesheets easier to organize and maintain.
A common tools for working with less are lessc. It is a compiler (written in JavaScript) for compiling less stylesheets.
The latest stable version can be installed by means of the npm (a package manager for Node.js libraries):
$ sudo npm install -g less … $ sudo lessc --version lessc 2.7.2 (Less Compiler) [JavaScript]
If you already have less installed using npm, but want to update to the latest version, do this:
$ sudo npm update -g less $ sudo lessc --version lessc 4.2.0 (Less Compiler) [JavaScript]
Examples of how to use it:
$ lessc example.less > compiled_example.css
Another useful tool for working with stylesheets is yui-compressor. It is a stylesheet optimizer and compressor,
$ sudo apt install yui-compressor
Examples of how to use it:
$ yui-compressor -o small_and_compiled_example.css compiled_example.css
To work with the theme, you need to install sass.
If you plan to do theme development using the Bootstrap5 theme, you will need sass, a Ruby-based CSS preprocessor. To install Ruby Sass globally , do this:
$ sudo apt install ruby-sass … $ sass --version Ruby Sass 3.7.4
There exists many other SASS preprocessors that can be used as alternatives.
Install ExifTool
$ type exiftool -bash: type: exiftool: not found
If it is not installed, then install it (otherwise, skip this step):
$ sudo apt install libimage-exiftool-perl
Links: ExifTool home, ExifTool notes.
Install Unison
Unison is a file-synchronization tool developend by Benjamin C. Pierce that exists for OS/X, Unix, and Windows. It allows two replicas of a collection of files and directories to be stored on different hosts (or different directories on the same host), modified separately, and then brought up to date by propagating the changes in each replica to the other.
To install Unison on Ububtu up to, and including Ubuntu 18.04 LTS:
$ sudo apt install unison-all $ unison -version unison version 2.48.4
The above works on all supported versions of Ubuntu except Ubuntu 20.04 LTS and later. However Unison is extremely picky, not only about the version number of the tool itself, but also the OCaml compiler used to compile it. It looks like the team that put together the binaries recompiled with a newer version of the OCaml compiler than what was previously used, without thinking about backwards and cross-platform compatibility is the main feature of syncing tool. IMHO, that's a major goof-up.
Until this is fixed on Ubuntu 20.04 LTS (and later), you need to
first purge Unison via apt (if you've installed
it). Then reinstall it “by hand” by using the static file
unison-2.48.4-linux-i386-text-static.tar.gz
that can be downloaded
from: Urs Müller's repo
(looks like the dynamic version works as well). If you already have the binary 2.48.4 somewhere, you can copy that instead.
This is Ubuntu bug #1568459 and Ubuntu bug #1875475. For more information, see AskUbuntu, GitHub and LaunchPad 1568459, LaunchPad 1875475.
Install Webmin/Virtualmin
Webmin with Virtualmin based free replacement for cPanel/Plesk. I have not tested it yet, just recorded some helpful links:
- Linuxize.com: How to Install Webmin on Ubuntu 18.04.
- DigitalOcean.com: How To Install Virtualmin with Webmin, LAMP, BIND, and PostFix on Ubuntu 16.04.
Install xterm
$ sudo apt install xterm
Install zip
$ sudo apt install zip
Install composer
To use composer, zip and unzip must be installed, so make sure it is:
$ unzip -v UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP. …
The dependecy manager composer can be used to download Drupal, Drupal contributed projects (modules, themes, etc.), and all of their respective dependencies. Before installing it, check if it is already installed:
$ type composer -bash: type: composer: not found
If it is not installed, then install it (otherwise, skip this step).
On Ubuntu 18.04 LTS and later, composer can be installed from the official repo with the apt tool. For example, on Ubuntu 22.04 LTS:
$ sudo apt install composer … $ composer -V Composer 2.4.1 2022-08-20 11:33:50 $ type composer composer is hashed (/usr/bin/composer) $ ls -l /usr/bin/composer -rwxr-xr-x 1 root root 2393 Aug 21 07:54 /usr/bin/composer
Installing from the Ubuntu 18.04 LTS repo resulted in a too old version of composer (version 1.6.3, from 2018) being installed.
On Ubuntu 22.04 LTS, using apt to install from the Ubuntu repo installs version 2.4.1 (2022-08-20). This is more current, and may still be usable. However, this version lacks the selfupdate command. The latest version (with selfupdate) is – at the time of writing – version 2.6.3 (2023-09-19).
To install the most recent version of composer (recommended for Ubuntu 20.04 LTS and earlier), use curl to download and run the installer as follows:
$ curl -sS https://getcomposer.org/installer | php … # Use it: php composer.phar $ sudo mv composer.phar /usr/local/bin/composer
DO: Setting Up Composer for Dependency Management.
Provided the selfupdate command is available, the following forces install of the most recent version of the ver. 1 branch and ver. 2 branch respictively:
$ composer selfupdate --1 $ composer selfupdate --2
Read more at Drupal.org: Using composer with Drupal, Getcomposer.org: Composer: Getting started, Getcomposer.org: Is it safe to run Composer as root? and SO.com: How to downgrade or install a specific version of Composer?.
Install webpack
Webpack is a static module bundler that is part of the Node.js ecosystem. It is not recommended to install it globally.
Installation is described in a separate chapter.
Test your configuration
After setting up, you should run some simple tests to verify that everything works as it should. Here are some suggestions.
To test that the Apache HTTP server is operating correctly, just point your browser to the domain you've created.
If Apache is working, and you've not yet created any content, you'll get some default page (exactly how it looks like depends on how the web server is configured).
Creating a file /var/www/html/index.php
with the following content will let you test PHP:
<html> <head><title>PHP test</title></head> <body> <h1>Hello, world!</h1> <?php phpinfo(); ?> </body> </html>
If you again point your browser to the domain you've been allocated after creating and installing this file in the webroot, and the browser shows a page with a long table with detailed information about the PHP configuration, both Apache and PHP works.
User administration
In Ubuntu, there are two command-line tools that you can use to
create a new user account: useradd
and adduser
.
The command useradd
is a low-level utility for adding
users. It will create the user and corresponding group. It will not
set a password and not create the user' home directory.
Here is an example of the latter:
$ sudo adduser username Adding user `username' ... Adding new group `username' (1002) ... Adding new user `username' (1002) with group `username' ... Creating home directory `/home/username' ... Copying files from `/etc/skel' ...
You will then be asked a series of questions. The password is required, and all other fields are optional.
New password: Retype new password: passwd: password updated successfully Changing the user information for username Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n]
This command will create the new user's home directory, and copy
the relevant files from /etc/skel
directory to the user's
home directory, and set permissions to let user write, edit, and
delete files and directories in the home directory.
To delete the user, without removing the user files, run:
$ sudo deluser username
If you want to delete the user and its home directory and mail spool, use the --remove-home
option:
$ sudo deluser --remove-home username
To add a user to an existing group:
$ sudo usermod -a -G groupname username
On Ubuntu, members of the group sudo are granted sudo access. To do this to a new user:
$ sudo usermod -a -G sudo username
The -a
(append) option is essential. Otherwise, the user will be removed from any groups, not in the list.
The -G
option takes a (comma-separated) list of additional groups to assign the user to.
To delete a user from a group:
$ sudo deluser username groupname
There are alternatives, but this is the safe way to do it.
You
may also edit the system file group
file manually, but if
you make a typo your system might become inaccessible.
Troubleshooting
Below the most common problems that may show up on a clean install are listed, whit some suggestions for how to resolve them.
WSOD
The first place to look, if you get the “white screen of death”, is the watchdog logs:
$ drush watchdog-show $ drush ws
To truncate the log, use the following:
$ drush wd-del all -y
The next place to lok is in the Apache error logs.
The location of the Apache logs for Ubuntu is set
by ${APACHE_LOG_DIR}
(defined
in /etc/apache2/envvars
), but the default location is the
directory /var/log/apache2/
.
The following will display Apache errors as they appear:
$ sudo tail -f /var/log/apache2/error.log
Cannot allocate memory
Sometimes, when a PHP operation fails because it is unable to allocate more memory, you may also experience that trivial CLI-commands results in a “Cannot allocate memory” error. Example:
$ whoami -bash: fork: Cannot allocate memory $ free -bash: fork: Cannot allocate memory
This happens when the computer runs out of memory. This can be for a number of reasons, but basically, some process is eating up all the memory and not leaving any left for even basic command usage.
The quick fix is to reboot, and the log on and then run top or htop. Keep an eye on the memory usage and see what process is using up all the memory.
Source: AskUbuntu.
Too many open files
The default number og allowed file descriptors in Ubuntu 20.04 is small:
$ ulimit -n 1024
While different limits may be configured for the web-server or database server, if the preset limit is exceeded, it throws the following exception:
PDOException: SQLSTATE[HY000]: General error: 1016 Can't open file: './database/semaphore.frm' (errno: 24 - Too many open files): SELECT expire, value FROM {semaphore} WHERE name = :name; Array ( [:name] => variable_init ) in lock_may_be_available() (line 167 of /var/www/example.org/html/includes/lock.inc).
The limit for the number of open file descriptors for a process can be set explicitly using the builtin bash ulimit -n
command. Note that this only effects the current shell and any subshells.
The maximum number of file descriptors for the web server process is controlled in two ways:
- By setting the the value of
APACHE_ULIMIT_MAX_FILES
in/etc/apache2/envvars
. - By setting hard and soft limits for the web-server in
/etc/security/limits.conf
.
Both of these requires a reboot to take effect.
By setting the value of the environment variable APACHE_ULIMIT_MAX_FILES
in /etc/apache2/envvars
, you can set the limit to use when the web server process starts. For example, uncomment the following line to increase this from 8192 (the default) to 65536.
APACHE_ULIMIT_MAX_FILES='ulimit -n 65536'
To see the current soft and hard limits for the user www-data
, run this as root:
$ su - www-data -c 'ulimit -Sn' -s '/bin/bash' 65536 $ su - www-data -c 'ulimit -Hn' -s '/bin/bash' 65536
Hard and soft limits for the databse (mysql
) and the
web-server (www-data
) may be set
in /etc/security/limits.conf
:
# <domain> <type> <item> </value> mysql hard nofile 8192 mysql soft nofile 8192 www-data hard nofile 65536 www-data soft nofile 65536
To check the limits for open processes:
$ ps aux | fgrep www-data www-data 12345 … $ cat /proc/12345/limits | egrep "Max open files|Limit" Limit Soft limit Hard limit Units Max open files 65536 65536 files $ ps aux | fgrep mysql mysql 23456 … $ cat /proc/23456/limits | egrep "Max open files|Limit" Limit Soft limit Hard limit Units Max open files 8192 8192 files
To change the limit for mysql
, you also need to create a new override using this command:
$ systemctl edit mysql
This fires up your default editor and let you enter the following data:
[Service] LimitNOFILE=8192
Edit /etc/mysql/my.cnf
and add the following section:
[mysqld] open_files_limit=50000
Now, reload the services:
$ systemctl daemon-reload $ service mysql restart
Source: Werk.21.de.
The following two commands let you look at some data from the kernel.
$ cat /proc/sys/fs/file-nr 2272 0 65535 $ sudo lsof | wc -l 39946
The first command shows three integers. The first is supposed to be the number of the file handles allocated during the current session. The second is allocated but unused file handles. The last number shows the maximum number of files handles per process.
The second command shows the total number of file handles currently open for all processes.
The following commands may be used to identify the culprit
(packaged as a script named lsoftop.sh
@ bar):
$ sudo lsof > lsof.log $ cat lsof.log | awk '{ print $1; }' | sort -rn | uniq -c | sort -rn | head -10 35315 mysqld 1952 apache2 308 lxcfs 224 sshd 221 gmain 171 systemd 128 master 95 gdbus 67 unattende 64 systemd-j
Source: Ask Ubuntu.
I am not yet sure what is required, but so far I've tried the following:
- Set a higher value in
/etc/apache2/envvars
. - Increased soft and hard limits for
www-data
in/etc/security/limits.conf
. - Added the following line to
/etc/pam.d/common-session
:
session required pam_limits.so
. - Added the following line to
/etc/sysctl.conf
:
fs.file-max = 65535
. - Run
sysctl -p
. It repeats the previous. - Changed the
systemd
configuration to haveLimitNOFILE=8192
. - Increased
open_files_limit
formysqld
from 5000 to 50000 inmy.cnf
.
However, steps 1-5 did not fix the problem. The jury is out on the last two.
Background:
- Apache.org: File descriptor limits
- easyengine.io: Increase open file limits.
Full root-partition
First, check the situation and identify what uses the space under /var
:
$ sudo df -h Filesystem Size Used Avail Use% Mounted on … /dev/vda1 49G 49G 0K 100% / … $ sudo du -sh /var/* | sort -hr | head 18G /var/lib 5.9G /var/www 2.9G /var/log 110M /var/cache 96M /var/backups 1M /var/spool 972K /var/private 152K /var/mail 28K /var/tmp
Here is the steps I currently take (expanded below):
- Clean out
/var/cache/apt
. - Trim down MySQL binary logs.
- Delete mailbox contents.
- Check for websites for spam.
This list should be expanded.
To clean out /var/cache/apt
, do:
$ sudo apt clean
To trim down MySQL binary logs do:
$ sudo mysql mysql> SHOW BINARY LOGS; mysql> PURGE BINARY LOGS TO 'binlog.000142';
To delete mailbox contents, start mutt and
then Shift+D, followed by ~s .*
. Press q to quit, qnd reply "Yes" to prompt about deleting.
If a website allows spammer to post, the database can become very big. You can find an outsized database by using the following set of commands:
$ sudo -i # du -sh /var/lib/mysql | sort -hr | head 178G db_spamsink 986M db_bigone 298M db_medium 233M db_alpha 179M db_beta 177M db_gamma
The huge size of db_spamsink
indicates that there is a loophole allowing spammers to post.
Sources:
- AU: Root drive is running out of disk space
- AU: var/cache/apt/archives occupying huge space
- AU: Separate /var partition is full due to apt archives and snaps
- AU: Big /var/log/journal
- AU: Big /var/lib/mysql
- LinuxQuestions.org: System partition full
If you cannot get enough free space by using the above steps, you may need to add disk space and/or block storage. How to this on DigitalOcean is described here.
Final word
[TBA]
Last update: 2022-12-10 [gh].