This article presents how to install a Web server with application back-end PHP and database back-end MySQL using MariaDB. All the software installed throughout this article is from the CentOS Stream 9 official repositories including the EPEL repository. The machine is installed with a minimal installation of CentOS Stream 9 and there is a how-to here – Network installation of CentOS Stream 9 (20220606.0) – minimal server installation.
Here are the steps to perform:
- Install, configure and start the database MariaDB.
- Install, configure and start the PHP-FPM and PHP cli.
- Install, configure and start the Web server Nginx.
- Configure the system – firewall and SELinux.
- Test the installation with a phpMyAdmin installation.
- Bonus – Nginx HTTPS with SSL certificate – self-signed and letsencrypt.
STEP 1) Install, configure and start the database MariaDB.
First, install the MariaDB server by:
dnf install -y mariadb-server
To configure the MariaDB server, the main file is /etc/my.cnf, which just includes all files under the folder /etc/my.cnf.d/
[root@srv ~]# cat /etc/my.cnf # # This group is read both both by the client and the server # use it for options that affect everything # [client-server] # # include all files from the config directory # !includedir /etc/my.cnf.d [root@srv ~]# ls -altr /etc/my.cnf.d/ total 32 -rw-r--r--. 1 root root 295 Mar 25 2022 client.cnf -rw-r--r--. 1 root root 120 May 18 07:55 spider.cnf -rw-r--r--. 1 root root 232 May 18 07:55 mysql-clients.cnf -rw-r--r--. 1 root root 763 May 18 07:55 enable_encryption.preset -rw-r--r--. 1 root root 1458 Jun 13 13:24 mariadb-server.cnf -rw-r--r--. 1 root root 42 Jun 13 13:29 auth_gssapi.cnf drwxr-xr-x. 2 root root 4096 Oct 6 06:34 . drwxr-xr-x. 81 root root 4096 Oct 6 06:34 ..
The most important file for the MariaDB server is /etc/my.cnf.d/mariadb-server.cnf, where all the server options are included. Under section “[mysqld]” add options to tune the MariaDB server. Supported options could be found here: https://mariadb.com/kb/en/mysqld-options/
Add the following options under “[mysqld]” in /etc/my.cnf.d/mariadb-server.cnf
# Generic skip-external-locking skip-character-set-client-handshake skip-name-resolve key_buffer_size = 1024M sort_buffer_size = 200K net_buffer_length = 64K read_buffer_size = 256K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 256M thread_cache_size = 100 max_connections = 1000 max_heap_table_size = 512M open_files_limit = 30000 max_allowed_packet = 16M myisam-recover-options = BACKUP sync_binlog=0 sql_mode="NO_ENGINE_SUBSTITUTION" # InnoDB innodb_buffer_pool_size = 4G innodb_log_buffer_size = 24M innodb_log_file_size = 128M innodb_flush_method = O_DIRECT innodb_file_per_table innodb_flush_log_at_trx_commit = 0 innodb_lock_wait_timeout = 150 innodb_thread_concurrency = 0
The most important options is innodb_buffer_pool_size, which should be 70% of available RAM (for machines with low amount of RAM, those above the 32G the percentage should be higher) or the size of the database.
It’s worth noting that no additional configuration is required to start the MariaDB server, but it’s good to make some optimization even for a test/staging/dev environment.
Second, start the services and enable it to start on boot. Check if the services has started successfully:
[root@srv ~]# systemctl enable mariadb Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service. [root@srv ~]# systemctl start mariadb [root@srv ~]# systemctl status mariadb ● mariadb.service - MariaDB 10.5 database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2022-10-06 07:04:00 UTC; 5s ago Docs: man:mariadbd(8) https://mariadb.com/kb/en/library/systemd/ Process: 3810 ExecStartPre=/usr/libexec/mariadb-check-socket (code=exited, status=0/SUCCESS) Process: 3832 ExecStartPre=/usr/libexec/mariadb-prepare-db-dir mariadb.service (code=exited, s> Process: 3937 ExecStartPost=/usr/libexec/mariadb-check-upgrade (code=exited, status=0/SUCCESS) Main PID: 3921 (mariadbd) Status: "Taking your SQL requests now..." Tasks: 15 (limit: 23072) Memory: 369.3M CPU: 1.291s CGroup: /system.slice/mariadb.service └─3921 /usr/libexec/mariadbd --basedir=/usr Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: you need to be the system 'mysql' user to connec> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: After connecting you can set the password, if yo> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: able to connect as any of these users with a pas> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: See the MariaDB Knowledgebase at https://mariadb> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: Please report any problems at https://mariadb.or> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: The latest information about MariaDB is availabl> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: Consider joining MariaDB's strong and vibrant co> Oct 06 07:04:00 srv mariadb-prepare-db-dir[3871]: https://mariadb.org/get-involved/ Oct 06 07:04:00 srv mariadbd[3921]: 2022-10-06 7:04:00 0 [Note] /usr/libexec/mariadbd (mysqld 10.> [root@srv ~]# pstree systemd─┬─NetworkManager───2*[{NetworkManager}] ├─agetty ├─anacron ├─auditd───{auditd} ├─chronyd ├─crond ├─dbus-broker-lau───dbus-broker ├─firewalld───{firewalld} ├─irqbalance───{irqbalance} ├─mariadbd───7*[{mariadbd}] ├─mdadm ├─polkitd───5*[{polkitd}] ├─rsyslogd───2*[{rsyslogd}] ├─sshd───sshd───sshd───bash───pstree ├─systemd───(sd-pam) ├─systemd-journal ├─systemd-logind └─systemd-udevd
MariaDB server will accept connections through the Unix socket file: /var/lib/mysql/mysql.sock. If the user wants to accept network connections to the MariaDB server, the following options should be enabled (uncomment it or add it) in /etc/my.cnf.d/mariadb-server.cnf:
bind-address=0.0.0.0
It will accept connections on all network interfaces, if only on a specific one is desired, just add the IP instead of 0.0.0.0.
Secure the installation with the MariaDB tool: mysql_secure_installation. This build-in tool presents several questions, which are considered to make the current installation of MariaDB more secure. By default, the MariaDB root password (the user with all privileges) has no password, so this tool sets root password and more.
[root@srv ~]# mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and haven't set the root password yet, you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have your root account protected, so you can safely answer 'n'. Switch to unix_socket authentication [Y/n] Y Enabled successfully! Reloading privilege tables.. ... Success! You already have your root account protected, so you can safely answer 'n'. Change the root password? [Y/n] Y New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] Y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] Y ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] Y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] Y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
For user convinience, add the root password in /root/.my.cnf as follow and the system root user will enter the MariaDB console without entering a password.
root@srv ~]# cat /root/.my.cnf [client] password="Thiu6je1ba:u4AhNgo0E" [root@srv ~]# chmod 400 /root/.my.cnf [root@srv ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 13 Server version: 10.5.16-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> ^DBye root@srv ~]#
STEP 2) Install, configure and start the application part – PHP-FPM and PHP cli.
FPM is FastCGI Process Manager, it starts a daemon, which runs a predefined number of PHP-FPM processes and it waits for Unix or TCP/IP connections to process them with PHP processor.
First, install PHP-FPM and PHP cli.
dnf install -y php-fpm php-cli php-pdo php-mbstring php-mysqlnd php-gd php-intl
There are two parts of PHP configuration:
- PHP configuration – the application, which processes the PHP files. The configuration is in /etc/php.ini and the custom modules configurations are in the directory /etc/php.d/
- PHP FPM configuration – the process, which controls the execution of the PHP daemon, which process the PHP files. The configuration is in /etc/php-fpm.conf and custom daemons’ configurations (there may be multiple instances of the daemon, each of which will start its own tree of processes) are under /etc/php-fpm.d/. By default, there is only one pool of PHP-FPM processes with configuration file /etc/php-fpm.d/www.conf
PHP configuration
The configuration is in file /etc/php.ini and in general, there are 3 important options:
..... date.timezone = UTC ..... memory_limit = 256M ..... max_execution_time = 60 .....
The file is around 1660 lines with options and comments, but in most cases, the first limits to hit are the above ones. By default, date.timezone is not set and is commented, so comment it out and set a value, the time zone, which used by the date functions – http://php.net/date.timezone. The second memory_limit is how much memory is allowed for each process and the third max_execution_time is how much time is allowed a process to take before being killed by the PHP.
PHP FPM Configuration
/etc/php-fpm.conf – defines global configuration for all pools and includes the files for each pool in /etc/php-fpm.d/. So the first pool, which will start one PHP process tree is in /etc/php-fpm.d/www.conf
Here are the important options, which should be uncommented or modified as follows:
..... user = nginx group = nginx ..... listen.backlog = 1024 ..... pm.max_requests = 20000 .....
Set the user to be nginx, because this Web server will be used. The backlog means how many connections to queue when there are connections to the process, which cannot be processed immediately.
Interesting options to manage the process counts of the PHP processes are: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers, pm.process_idle_timeout, pm.max_requests (always set a limit to how many requests a process can accept, memory leaks do exists, so restarting a PHP process is a good thing! Be careful, with low values on a busy server.)
The default configuration will accept connections only through the Unix socket file: /run/php-fpm/www.sock. To accept network connections modify the listen and listen.allowed_clients options:
..... listen="10.10.10.10:9000" ..... ;listen.allowed_clients= .....
The PHP-FPM will accept network connections from IP 10.10.10.10 on port 9000.
In the configuration file there are many comments, which the user should read, because they may help him to find interesting options like access logging, slow logging, error logging, status and ping pages and more.
Start and enable on boot the PHP-FPM service:
[root@srv ~]# systemctl enable php-fpm Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service. [root@srv ~]# systemctl start php-fpm [root@srv ~]# systemctl status php-fpm ● php-fpm.service - The PHP FastCGI Process Manager Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2022-10-06 08:06:42 UTC; 3s ago Main PID: 4817 (php-fpm) Status: "Ready to handle connections" Tasks: 6 (limit: 23072) Memory: 10.4M CPU: 83ms CGroup: /system.slice/php-fpm.service ├─4817 "php-fpm: master process (/etc/php-fpm.conf)" ├─4818 "php-fpm: pool www" ├─4819 "php-fpm: pool www" ├─4820 "php-fpm: pool www" ├─4821 "php-fpm: pool www" └─4822 "php-fpm: pool www" Oct 06 08:06:42 srv systemd[1]: Starting The PHP FastCGI Process Manager... Oct 06 08:06:42 srv systemd[1]: Started The PHP FastCGI Process Manager.
There is a master PHP-FPM process, which ran 5 process to accept connections.
Fix the PHP session write permissions with:
[root@srv ~]# ls -altrZ /var/lib/php/ total 24 drwxrwx---. 2 root apache system_u:object_r:httpd_var_run_t:s0 4096 Aug 1 09:42 wsdlcache drwxrwx---. 2 root apache system_u:object_r:httpd_var_run_t:s0 4096 Aug 1 09:42 session drwxr-xr-x. 2 root root system_u:object_r:httpd_var_lib_t:s0 4096 Aug 1 09:42 peclxml drwxrwx---. 2 root apache system_u:object_r:httpd_var_lib_t:s0 4096 Aug 1 09:42 opcache drwxr-xr-x. 6 root root system_u:object_r:httpd_var_lib_t:s0 4096 Oct 6 07:32 . drwxr-xr-x. 27 root root system_u:object_r:var_lib_t:s0 4096 Oct 6 08:15 .. [root@srv ~]# chown root:nginx /var/lib/php/wsdlcache/ [root@srv ~]# chown root:nginx /var/lib/php/session/ [root@srv ~]# chown root:nginx /var/lib/php/opcache/ [root@srv ~]# ls -altrZ /var/lib/php/ total 24 drwxrwx---. 2 root nginx system_u:object_r:httpd_var_run_t:s0 4096 Aug 1 09:42 wsdlcache drwxr-xr-x. 2 root root system_u:object_r:httpd_var_lib_t:s0 4096 Aug 1 09:42 peclxml drwxrwx---. 2 root nginx system_u:object_r:httpd_var_lib_t:s0 4096 Aug 1 09:42 opcache drwxr-xr-x. 6 root root system_u:object_r:httpd_var_lib_t:s0 4096 Oct 6 07:32 . drwxr-xr-x. 27 root root system_u:object_r:var_lib_t:s0 4096 Oct 6 08:15 .. drwxrwx---. 2 root nginx system_u:object_r:httpd_var_run_t:s0 4096 Oct 6 09:34 session
The directories’ groups are apache, but nginx is used, that’s why the user should be change. A blank page may be displayed if the PHP-FPM could not write to these directories.
The SELinux permission are fine.
STEP 3) Install, configure and start the Web server Nginx.
First, install the Nginx server.
dnf install -y nginx
The main configuration file is in /etc/nginx/nginx.conf, where are defined the virtual hosts (server sections) for this server. By default, only the HTTP (without SSL certificate) is defined, the SSL one is commented.
By default, Nginx defines default domain “_”, which accepts all no other sector is defined. So if the user wants to have a custom server block, the best it to copy the whole default block and modify the following options: server_name, root, include at least.
] ..... server { listen 80; listen [::]:80; server_name example.mydomain.com; root /var/www/html/example.mydomain.com; # Load configuration files for the example.mydomain.com server block. include /etc/nginx/sites.d/example.mydomain.com.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } .....
Make sure to create the /etc/nginx/sites.d/example.mydomain.com.conf. It is a good idea always to split different server blocks in different configuration files or at least, the specific options. It should be noted that to process a PHP-FPM requests, the above block must defines a similar location directive (mentioned below), so just copying the /etc/nginx/default.d/php.conf to /etc/nginx/sites.d/example.mydomain.com.conf is enough to begin with.
Installing the Nginx at the last step will ensure the existence of two important files for the PHP-FPM.
There are two more important directories:
- modular configuration files – /etc/nginx/conf.d/ all files with extension .conf. Configuration file for multiple server sectors (i.e. for multiple virtual hosts). The options in these files will tune and be visible for all domains. At present, there is only one file – /etc/nginx/conf.d/php-fpm.conf :
# PHP-FPM FastCGI server # network or unix domain socket configuration upstream php-fpm { server unix:/run/php-fpm/www.sock; }
It defines an upstream group of servers for the application back-end, i.e. PHP-FPM, which accept connections through Unix socket file /run/php-fpm/www.sock. The socket file is the same as in the configuration section of PHP-FPM.
- default server block configuration files – /etc/nginx/default.d/. Configuration options only for one server block, i.e. virtual host (domain) – the default one, which accepts all requests if no other server section for the requested domain is defined. There is only one file /etc/nginx/default.d/php.conf, which define a section instructing Nginx to open a connection through the defined upstream to the PHP-FPM process:
# pass the PHP scripts to FastCGI server # # See conf.d/php-fpm.conf for socket configuration # index index.php index.html index.htm; location ~ \.(php|phar)(/.*)?$ { fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$; fastcgi_intercept_errors on; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_pass php-fpm; }
So if a request to a file with extension “.php” in the server including this location, the request will be handled to the upstream server and the PHP-FPM process will process the request.
For completeness, this article should show how to add a configuration for the domain and not to use the default domain (and server block section). Even the PHP-FPM should be removed from the default, because the default should serve only static content. So here is the final configuration with a fake domain:
- /etc/nginx/nginx.conf configuration:
..... server { listen 80; listen [::]:80; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } server { listen 80; listen [::]:80; server_name example.mydomain.com; root /var/www/html/example.mydomain.com; # Load configuration files for the default server block. include /etc/nginx/sites.d/example.mydomain.com.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } .....
- Remove the PHP-FPM location configuration for the default server block and add it to the example.mydomain.com.
mv /etc/nginx/default.d/php.conf /etc/nginx/sites.d/example.mydomain.com.conf
Finally, test the configuration and start the service. Enable it to start on boot.
[root@srv ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@srv ~]# systemctl start nginx [root@srv ~]# systemctl enable nginx Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service. [root@srv ~]# systemctl status nginx ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/nginx.service.d └─php-fpm.conf Active: active (running) since Thu 2022-10-06 09:20:03 UTC; 9s ago Main PID: 5106 (nginx) Tasks: 3 (limit: 23072) Memory: 2.9M CPU: 68ms CGroup: /system.slice/nginx.service ├─5106 "nginx: master process /usr/sbin/nginx" ├─5107 "nginx: worker process" └─5108 "nginx: worker process" Oct 06 09:20:03 srv systemd[1]: Starting The nginx HTTP and reverse proxy server... Oct 06 09:20:03 srv nginx[5104]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Oct 06 09:20:03 srv nginx[5104]: nginx: configuration file /etc/nginx/nginx.conf test is successful Oct 06 09:20:03 srv systemd[1]: Started The nginx HTTP and reverse proxy server.
STEP 4) Configure the system – firewall and SELinux
By default, CentOS Stream 9 uses firewalld service and firewall-cmd cli to control it. Allow HTTP trafffic to the server:
[root@srv ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: enp0s3 sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: [root@srv ~]# firewall-cmd --permanent --add-service=http success [root@srv ~]# firewall-cmd --reload success [root@srv ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: enp0s3 sources: services: cockpit dhcpv6-client http ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
If the web root directories is under /var/www there is no need to tune the SELinux. If the user want to change to another location not under /var/www, the SELinux label httpd_sys_content_t must be added to the parent directory.
For example, if the web root directories are under /mnt/storage/www, the following commands should be issued:
[root@srv ~]# semanage fcontext -a -t httpd_sys_rw_content_t '/mnt/storage/www(/.*)?' [root@srv ~]# restorecon -Rv /mnt/storage/www Relabeled /mnt/storage/www from unconfined_u:object_r:mnt_t:s0 to unconfined_u:object_r:httpd_sys_rw_content_t:s0
Otherwise, the SELinux will block any web request to the /mnt/storage/www.
STEP 5) Test all the three components – Nginx, PHP-FPM and MariaDB.
First test is Nginx+PHP-FPM and it purpose is to show phpinfo() page. Create a file /var/www/html/example.mydomain.com/test.php with the content as shown below and then set the owner to “nginx:nginx”.
[root@srv ~]# cat /var/www/html/example.mydomain.com/test.php <?php phpinfo(); [root@srv ~]# chown -R nginx:nginx /var/www/html/example.mydomain.com
Second, test the Nginx+PHP-FPM + MariaDB, i.e. the connectivity to the database from the application layer PHP-FPM.
Just download the phpMyAdmin package from https://files.phpmyadmin.net/phpMyAdmin/5.2.0/phpMyAdmin-5.2.0-all-languages.zip or the latest version. Unpack, add default config and load it in the browser:
[root@srv ~]# cd /var/www/html/example.mydomain.com [root@srv example.mydomain.com]# wget https://files.phpmyadmin.net/phpMyAdmin/5.2.0/phpMyAdmin-5.2.0-all-languages.zip --2022-10-06 09:28:27-- https://files.phpmyadmin.net/phpMyAdmin/5.2.0/phpMyAdmin-5.2.0-all-languages.zip Resolving files.phpmyadmin.net (files.phpmyadmin.net)... 185.76.8.4, 2a02:6ea0:d900::3 Connecting to files.phpmyadmin.net (files.phpmyadmin.net)|185.76.8.4|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 14112668 (13M) [application/zip] Saving to: ‘phpMyAdmin-5.2.0-all-languages.zip’ phpMyAdmin-5.2.0-all-lan 100%[=================================>] 13.46M 6.30MB/s in 2.1s 2022-10-06 09:28:30 (6.30 MB/s) - ‘phpMyAdmin-5.2.0-all-languages.zip’ saved [14112668/14112668] [root@srv example.mydomain.com]# unzip phpMyAdmin-5.2.0-all-languages.zip Archive: phpMyAdmin-5.2.0-all-languages.zip creating: phpMyAdmin-5.2.0-all-languages/ extracting: phpMyAdmin-5.2.0-all-languages/.rtlcssrc.json ..... ..... inflating: phpMyAdmin-5.2.0-all-languages/yarn.lock [root@srv example.mydomain.com]# mv phpMyAdmin-5.2.0-all-languages phpmyadmin [root@srv example.mydomain.com]# cd phpmyadmin [root@srv example.mydomain.com]# cp config.sample.inc.php config.inc.php
Then open the browser and login with MariaDB root account and the password set in the (STEP 1). The phpMyAdmin should be located in http://example.mydomain.com/phpmyadmin/.
Bonus) Nginx HTTPS with SSL certificate – self-signed and letsencrypt.
Two types of certificate generations for the HTTPS server block will be presented in this section:
- Self-signed certificate. The browsers will report it is unsafe and the user should accept the certificate before viewing the site. It is convinient for development stage.
- Letsencrypt certificate – the software needed and how to generate. A free and valid certificate. More info – https://letsencrypt.org/
Generate self-signed certificate
Generate the self-signed certificate and configure the firewall to accept HTTPS connections.
[root@srv ~]# openssl genrsa -out /etc/ssl/nginx/example.mydomain.com.key 4096 [root@srv ~]# openssl req -new -key /etc/ssl/nginx/example.mydomain.com.key -out /etc/ssl/nginx/example.mydomain.com.csr -subj '/C=us/ST=newyork/L=newyork/O=mygroup/OU=servicing/CN=example.mydomain.com/emailAddress=admin@mydomain.com' [root@srv ~]# openssl x509 -req -days 365 -in /etc/ssl/nginx/example.mydomain.com.csr -signkey /etc/ssl/nginx/example.mydomain.com.key -out /etc/ssl/nginx/example.mydomain.com.crt [root@srv ~]# chmod 400 /etc/ssl/nginx/* [root@srv ~]# ls -altr /etc/ssl/nginx/ total 20 drwxr-xr-x. 3 root root 4096 Oct 6 11:10 .. -r--------. 1 root root 3268 Oct 6 11:11 example.mydomain.com.key -r--------. 1 root root 1765 Oct 6 11:12 example.mydomain.com.csr drwxr-xr-x. 2 root root 4096 Oct 6 11:13 . -r--------. 1 root root 2049 Oct 6 11:13 example.mydomain.com.crt [root@srv ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@srv ~]# systemctl restart nginx [root@srv ~]# firewall-cmd --permanent --add-service=https success [root@srv ~]# firewall-cmd --reload success
Here is the Nginx server block (in /etc/nginx.nginx.conf below the above two server blocks) for the HTTPS connections:
..... server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.mydomain.com; root /var/www/html/example.mydomain.com; ssl_certificate "/etc/ssl/nginx/example.mydomain.com.crt"; ssl_certificate_key "/etc/ssl/nginx/example.mydomain.com.key"; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_ciphers PROFILE=SYSTEM; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/sites.d/example.mydomain.com.conf; error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } .....
Test and restart the Nginx web server.
[root@srv ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@srv ~]# systemctl restart nginx
The phpMyAdmin should be located in https://example.mydomain.com/phpmyadmin/.
Letsencrypt certificate
Install the needed software. certbot is the command-line tool to generate, renewn and manage Let’s Encrypt SSL Certificates.
dnf install -y epel-release dnf install -y certbot
The domain example.mydomain.com must have an accessible Internet IP, which the servers behind the letsencrypt organization would access using HTTP/HTTPS.
[root@srv ~]# certbot certonly --webroot -w /var/www/html/example.mydomain.com -d example.mydomain.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for example.mydomain.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/example.mydomain.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/example.mydomain.com/privkey.pem This certificate expires on 2023-01-04. These files will be updated when the certificate renews. NEXT STEPS: - The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The Nginx configuration in /etc/nginx/nginx.conf looks like:
..... server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.mydomain.com; root /var/www/html/example.mydomain.com; ssl_certificate "/etc/letsencrypt/live/example.mydomain.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/example.mydomain.com/privkey.pem"; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_ciphers PROFILE=SYSTEM; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/sites.d/example.mydomain.com.conf; error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } .....
Essensially the same with the self-singed one, but with modified the path of ssl_certificate and ssl_certificate_key.
Test and restart the Nginx web server.
[root@srv ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@srv ~]# systemctl restart nginx
The phpMyAdmin should be located in https://example.mydomain.com/phpmyadmin/, but this time the SSL certificate will be valid for example.mydomain.com and no errors or crititcal warnings will receive the users of the site.