How to install Amazon Linux 2023 for WordPress
When I do a terminal shell login, I type:
$ sudo su
# set -o vi
When I refer to “vi” you may have another preferred editor. Do not cut and paste my comments in square brackets. Replace “Australia/Brisbane” with your own country/city. If a few things are not working, not only look at error messages, make use of forums, but reboot the instance.
[log in as root: sudo su, then set -o vi for the vi editor] [for a fresh/new instance:] echo "vm.swappiness=10" >> /etc/sysctl.conf echo "vm.vfs_cache_pressure=200" >> /etc/sysctl.conf sysctl -w vm.swappiness=10 sysctl -w vm.vfs_cache_pressure=200 dd if=/dev/zero of=/swapfile bs=1024 count=1048576 mkswap /swapfile chmod 600 /swapfile swapon /swapfile echo "/swapfile swap swap defaults 0 0" >> /etc/fstab free -m dnf update dnf upgrade dnf check-release-update [repeat these steps till no upgrades are left. Do the update before adding the packages below. e.g. dnf update --releasever=2022.0.20221019] sync;sync;reboot [log back in as root] dnf install -y httpd httpd-tools mod_ssl dnf install -y php php-common php-pear wget php-mysqli php-devel php-mbstring dnf install -y php-cli php-pdo php-fpm php-json php-mysqlnd php-opcache dnf install -y gd libzip-devel httpd-devel kernel-devel php-gd postfix [ Notes: - If using shell scripts acessing ImageMagick: dnf install -y ImageMagick ImageMagick-devel There is no php-ImageMagick at time of writing. I think it is possible to hunt around on how to isntall it for php. I no longer use memcached, php-memcached or php-apcu as there are no packages in Linux 2022/2023. This reduces some configuration hassle. If there were, you would update the inbound rules of the EC2 instance security group for memecached and then dnf install memcached php-memcached and configure the last line of /etc/sysconfig/memcached. I have older notes on this. - We need to install ZipArchive (php-zip) for various apps that may be used in WordPress that require zip. We will install this here as well... ] dnf -y install pcre-devel gcc zlib zlib-devel pecl install zip pecl channel-update pecl.php.net [Now edit /etc/php.ini and after the Dynamic section (as shown below) add zip.so. Note that in Linux2 we coud simply do yum install php-zip and that was all we had to do. If we had put zip.so into php.ini there would be an error in /etc/httpd/log/error_log:] vi /etc/php.ini ;;;;;;;;;;;;;;;;;;;;;; ; Dynamic Extensions ; ;;;;;;;;;;;;;;;;;;;;;; extension=zip.so; [Save and exit the editor, then restart httpd.] [ In an earlier version of linux I had to get crontab from fedora, but not so now. wget -O epel.rpm –nv \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm rpm -ihv --nodeps ./epel-release-latest-8.noarch.rpm Note: The script advises to execute /usr/bin/crb enable but I am not sure why as crontab is working without that. You could do it anyway. /usr/bin/crb enable Enabling CRB repo CRB repo is disabled ] dnf install -y cronie cronie-anacron [use your country/city:] a="Australia/Brisbane";export a;echo $a ln -sf /usr/share/zoneinfo/$a /etc/localtime date [ Change /etc/bashrc to your preferred method of PS1. I use this: (comment out the existing line - exit the shell a little further below.) # [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ " [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@mydomain.au: \w]\\$ " ] usermod -a -G apache ec2-user [exit and log back in as root] chown -R ec2-user:apache /var/www chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \; find /var/www -type f -exec sudo chmod 0664 {} \; cd /var/www chown apache html chgrp apache html chmod 2775 html dnf -y install mariadb105 dnf -y install mariadb105-server [for certbot/let'sencrypt and PIP (rather than snapd!):] [do not install these if using a paid certifcate] dnf install python3 dnf install python3-devel dnf install augeas-libs python3 -m venv /opt/certbot/ /opt/certbot/bin/pip install --upgrade pip /opt/certbot/bin/pip install certbot certbot-apache ln -s /opt/certbot/bin/certbot /usr/bin/certbot vi /etc/php.ini date.timezone = Australia/Brisbane max_execution_time = 300 max_input_time = 600 max_input_vars = 2500 post_max_size = 50M upload_max_filesize = 50M max_file_uploads = 20 memory_limit = 256M [save and exit - you may have other values for country/city and sizes, but I'd keep 256M. Input vars value is so larger WordPress menu lists will display.] vi /etc/php.d/10-opcache.ini opcache.enable_cli=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=4000 [save and exit] vi /etc/selinux/config # SELINUX=permissive SELINUX=disabled [save and exit] cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.o vi /etc/php-fpm.d/www.conf cp -p www.conf www.conf.bak ; pm = dynamic pm = ondemand pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.process_idle_timeout = 10s; pm.max_requests = 500 php_admin_value[memory_limit] = 256M [save and exit - there is a semicolon at the end of one of the above lines] vi /etc/httpd/conf/httpd.conf [after Listen 80 add:] KeepAlive On MaxKeepAliveRequests 50 KeepAliveTimeout 5 [in the <Directory "/var/www/html"> section:] AllowOverride All [in the <IfModule dir_module> section after it:] DirectoryIndex index.php index.html [fix the ServerName to your domain:] #ServerName www.example.com:80 ServerName mydomain.au [If intending to add IP2Location for country blocking, add these lines at the end of the file:] <IfModule mod_ip2location.c> IP2LocationEnable On IP2LocationDetectProxy On IP2LocationSetmode ALL IP2LocationDBFile /home/ec2-user/ip2location/IP2LOCATION-LITE-DB1.BIN </IfModule> [save and exit] vi /etc/httpd/conf.modules.d/00-mpm.conf [we do not use http/2 on small instances] LoadModule mpm_prefork_module modules/mod_mpm_prefork.so #LoadModule mpm_worker_module modules/mod_mpm_worker.so [append these for performance: - remember, these square brackets do not go into the edited file - they are my way of adding notes to explain things.] <IfModule mpm_prefork_module> StartServers 2 MinSpareServers 2 MaxSpareServers 5 MaxRequestWorkers 125 ServerLimit 125 MaxConnectionsPerChild 0 </IfModule> [save and exit] vi /etc/httpd/conf.modules.d/00-proxy.conf [typicall heartbeat has caused continuous error log messages] # LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so [save and exit] [ Add a new file, /etc/httpd/conf.d/phpMyAdmin.conf Use your own static IP address (otherwise edit it every time you use phpMyAdmin for your dynamic address). Replace xxx.xxx.xxx.xxx with your IP address. This lets you access the phpMyAdmin database GUI. Note: we are not configuring anything complex with httpd. ] vi /etc/httpd/conf.d/phpMyAdmin.conf Alias /phpMyAdmin /usr/share/phpMyAdmin Alias /phpmyadmin /usr/share/phpMyAdmin <Directory /usr/share/phpMyAdmin/> AddDefaultCharset UTF-8 <IfModule mod_authz_core.c> # Apache 2.4 <RequireAny> Require ip xxx.xxx.xxx.xxx Require ip ::1 </RequireAny> </IfModule> <IfModule !mod_authz_core.c> # Apache 2.2 Order Deny,Allow Deny from All Allow from xxx.xxx.xxx.xxx Allow from ::1 </IfModule> </Directory> <Directory /usr/share/phpMyAdmin/setup/> <IfModule mod_authz_core.c> # Apache 2.4 <RequireAny> Require ip xxx.xxx.xxx.xxx Require ip ::1 </RequireAny> </IfModule> <IfModule !mod_authz_core.c> # Apache 2.2 Order Deny,Allow Deny from All Allow from xxx.xxx.xxx.xxx Allow from ::1 </IfModule> </Directory> <Directory /usr/share/phpMyAdmin/setup/frames/> Order Deny,Allow Deny from All Allow from None </Directory> [save and exit] [ Configure /etc/httpd/conf.d/ssl.conf Note, until we are ready to install SSL and restart httpd, I move the file to ssl.conf.o. When I am ready I move it to ssl.conf. If using certbot, you create the basic entries in the file and comment out the certificate lines, rename the file and start httpd so that ssl is not running. Then rename the file back to ssl.conf so that when certbot tries to install the certificate, ssl.conf is present. Then when you run the certbot -w command for the domain.au and www.domain.au names it will work. After that command, you run certbot --apache, and then edit the ssl.conf file to fix the entries at the bottom of the file, to replace the -001 entries back to what they should be, and add an alias for www. Then you can go to /etc/letsencrypt and remove the -001 directories. My certbot scripts show how you can renew every 30 days and verify the certificates. You should do your first -w command appended wtih --dry-run. You should not log into phpMyAdmin to create a WordPress database and user until SSL is configured. If using a paid certificate, you have to learn about how it works, and then reference the .cert and .key files in ssl.conf. ] [below, at the top of the file, use your own domain name. I will already have a CNAME record in the DNS configs for www.mydomain.au pointing to mydomain.au.] vi /etc/httpd/conf.d/ssl.conf <VirtualHost *:80> ServerName mydomain.au Redirect permanent / https://mydomain.au/ RewriteEngine on RewriteCond %{SERVER_NAME} =mydomain.au RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost> #ServerName www.example.com:443 ServerName mydomain.au:443 SSLEngine on #SSLProtocol all -SSLv3 #SSLProxyProtocol all -SSLv3 SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2 SSLProxyProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2 # note: the next two long lines must have no carriage return line feeds. Please check to make sure. SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLProxyCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA SSLHonorCipherOrder on SSLCipherSuite PROFILE=SYSTEM SSLProxyCipherSuite PROFILE=SYSTEM SSLCompression off SSLInsecureRenegotiation Off SSLSessionTickets Off SSLOpenSSLConfCmd ECDHParameters secp384r1 SSLOpenSSLConfCmd Curves secp384r1 # we comment out the following lines only if using certbot, otherwise we change them to our own certificates from Comodo/Sectigo or whoever. The .key file can be used every year, and the .crt is the original .crt appeneded with other "bundled" entires except the root certificate. It is easy to create these files with an editor. Sometimes the provider gives a bundled file but it may or may not have the root certificate in it. You want to remvoe references to the root. A test on ssllabs.com shows if you have an issue. # SSLCertificateKeyFile /etc/pki/tls/private/localhost.key <-------- USE YOUR OWN, e.g. mydomain_au.key and uncomment the lines if you have Comodo/Sectigo and not certbot. # SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt <-------- USE YOUR OWN, e.g. mydomain_au.crt # just before the last line of </VirtualHost>, certbot should add these lines during its configurations, and if not you can manually add and check the .pem files exist. It is no magic as you can tar file the letsencrypt directory and re-install on another instance without problems if you upgrade your EC2 instance using the ame domain name. # only have these following lines if using certbot from Let's Encrypt ServerAlias mydomain.au ServerAlias www.mydomain.au SSLCertificateFile /etc/letsencrypt/live/mydomain.au/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.au/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf [save and exit]
Configuring Postfix – we use this to send internal emails.
cd /etc/postfix
Add the following lines to a new file sasl_passwd, using the square brackets as shown and the e-mail region. I use Oregon. There is no e-mail region in Australia.
You will have previously created SMTP credentials from the SES console. Use these where it says SMTPUSERNAME:SMTPPASSWORD below.
cd /etc/postfix vi sasl_passwd [email-smtp.us-west-2.amazonaws.com]:587 SMTPUSERNAME:SMTPPASSWORD [save and exit - use the square brackets as shown above] systemctl stop postfix;systemctl disable postfix;ps -ef|grep postfix postconf -e "relayhost = [email-smtp.us-west-2.amazonaws.com]:587" \ "smtp_sasl_auth_enable = yes" \ "smtp_sasl_security_options = noanonymous" \ "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \ "smtp_use_tls = yes" \ "smtp_tls_security_level = encrypt" \ "smtp_tls_note_starttls_offer = yes" [Enter the above lines with the \ then press RETURN KEY to execute them. Remember, these lines show Oregon as the region. If you use North Virginia you would need that region.] postmap hash:/etc/postfix/sasl_passwd chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db postfix start; sudo postfix reload; postfix flush mailq [Now do a test e-mail, then disable postfix for security reasons and only call it from shell scripts] sendmail -f admin@mydomain.au admin@mydomain.au From: admin <admin@mydomain.au> Subject: Postfix Test This is a test message from AWS Postfix and SES . mailq [It should have sent without errors. If not, clean up the /var/log and fix the error. If you are in sandbox mode, use the verified email address you created in SES, and check your DNS records. It could also be you see errors in Cloudwatch logs in Oregon region if you perhaps made mistakes in your Lambda or SES setups. These details are as per a spearate article.] systemctl disable postfix postfix stop [We stop postfix for security. We can use it in our shell scripts to send alerts.] [Configure mariadb:] systemctl start mariadb mysql_secure_installation [ Enter current password for root (enter for none): OK, successfully used password, moving on... Switch to unix_socket authentication [Y/n] n Change the root password? [Y/n] Y (nominate your database password) Y for the remaining questions ] systemctl stop mariadb systemctl start mariadb systemctl enable mariadb systemctl enable httpd systemctl enable php-fpm php -v [This will show version 8.1 or above] [You can check the version of Mariadb with: dnf list|grep mariadb] [Configuring phpMyAdmin…] cd /usr/share wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz ls tar xvf ..... [where ..... is the downloaded file. Then delete the tar.gz file, then use the Unix command to move the directory to phpMyAdmin, e.g.: mv yourfile phpMyAdmin] cd phpMyAdmin mkdir tmp chmod 777 tmp cp -p config.sample.inc.php config.inc.php vi config.inc.php [ Search for the blowfish line. Do a Google search on blowfish phpmyadmin generator. I use: https://phpsolved.com/phpmyadmin-blowfish-secret-generator/?g=[insert_php]echo%20$code;[/insert_php] from https://phpsolved.com. Paste the generated value into the blowfish value. Then after SaveDir as shown below, add TEMPDir... ] $cfg['SaveDir'] = ''; $cfg['TEMPDir'] = '/tmp'; [ Restart httpd - recall we may not have SSL running, so you should not really log into phpMyAdmin at this stage. You can check the interface is ready with http://mydomain.au/phpMyAdmin. As a note, you can view your PHP settings with http://mydomain.au/phpinfo.php. I have a separate article on using phpMyAdmin. ] [Please see my separate articles on IP2location and S3FS (NFS), CDN if you wish to use those capabilities.] dnf update [I like to reboot:] sync;sync;reboot
For more on SSL installations, please see my article at:
photographybyshaw.au/aws/install-postfix-apache-php-mysql-ssl/
You may now reboot the system and verify SSL is working, then as per my other articles, create a database and user in phpMyAdmin, use FileZilla (or Putty) to upload WordPress, unzip it and move the files to /var/www/html.
Then begin installation with https://mydomain.au and enter the values you want which creates the wp-config.php file.
You can upload your themes to /var/www/html/wp-content/themes.
NOTE:
Once WordPress files are uploaded, you must change their ownership before installing WordPress.
Use the following shell script…
cd /var/www/html vi chdir.sh #!/bin/sh chown -R apache * chgrp -R apache * find . -type d -exec chmod 2775 {} \; find . -type f -exec chmod 0664 {} \; if [ -f "./.htaccess" ] ; then chown apache .htaccess chgrp apache .htaccess chmod 664 .htaccess fi chmod 777 *.sh chown root chdir.sh chgrp root chdir.sh chmod 770 chdir.sh exit [save and exit the editor, then run the script] chmod 775 chdir.sh ./chdir.sh ls -la
If you have connected your domain to MS Exchange, then the above postfix configurations need modifications.
sasl_passwd uses something like this, if your domain was domain.au:
[domain-au.mail.protection.outlook.com]:25 me@domain.au:PASSWORD
Then hash the file as above with postmap.
Then modify /etc/postfix/main.cf and restart the service.
smtp_tls_security_level = may [make sure you have your certificates listed, e.g. smtpd_tls_cert_file = /etc/pki/tls/certs/domain_au.crt smtpd_tls_key_file = /etc/pki/tls/private/domain_au.key if using Comodo type certificates for domain.au] relayhost = [domain-au.mail.protection.outlook.com]:25 [where this is a copy of your DNS entry in Route53 (or wherever) and we use port 25 only.] [Then test like this after systemctl stop postfix; systemctl start postfix; where me@domainau is your primary or alias in MS Exchange.] sendmail -f me@doman.au me@domain.au From: me@domain.au Subject: postfix test This is a postfix test . [then check:] mailq cat /var/log/mail.log [you may need to view it a few times if timeouts are involved etc.]
You can now send emails from shell scripts. This does no effect the WordPress contact form setups that use the SMTP Mail Plugin’s “Other SMPT”
settings going through the AWS SES relay without MS Exchange involved.