Application Server
This documentation can be used as a reference to create both your Production Application Server and/or Staging Application Server on a Enterprise Linux 8 virtual machine.
SSH into server and
sudo
to root:ssh [email protected] sudo -s
Change the SELINUX variable in
/etc/selinux/config
to permissive to prevent unforeseen and difficult to diagnose issues:SELINUX=permissive
Add the following lines to
/etc/hosts
file:127.0.0.1 elentra.med.university.edu 127.0.0.1 staging.med.university.edu
Edit the hostname of the virtual machine in the
/etc/hostname
file:elentra.med.university.edu
Install
screen
, update RHEL, and reboot:dnf install screen screen dnf update reboot
SSH back into server, and install the Inline with Upstream Stable (IUS Community) package.
ssh [email protected] sudo -s screen dnf -y install http://rpms.remirepo.net/enterprise/remi-release-8.rpm \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
Install Snapd and htmldoc:
dnf -y install snapd systemctl enable --now snapd.socket ln -s /var/lib/snapd/snap /snap snap install htmldoc
Note: You may have to wait a couple of minutes before running the snap install command, so that the snap database can initialize.
Install Apache, OpenSSL, PHP, Git, HTMLDoc, mariadb (client), ClamAV, and NTP packages:
dnf module install php:remi-8.1 -y dnf -y install git \ curl \ wget \ unzip \ openssl \ httpd \ mod_ssl \ php-cli \ php-gd \ php-devel \ php-pdo \ php-mysqlnd \ php-intl \ php-mbstring \ php-bcmath \ php-ldap \ php-imap \ php-soap \ php-xml \ php-xmlrpc \ php-tidy \ php-opcache \ php-json \ php-sodium \ php-pecl-redis \ php-pecl-zip \ mariadb \ clamav \ chrony \ supervisor
Install
wkhtmltopdf
from the binary package because the yum package provided by EPEL is broken:curl -SL https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz | tar -xJC /root && cp /root/wkhtmltox/bin/* /usr/bin dnf install xorg-x11-fonts-Type1 dnf install xorg-x11-fonts-75dpi wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox-0.12.6.1-2.almalinux8.x86_64.rpm rpm -Uvh wkhtmltox-0.12.6.1-2.almalinux8.x86_64.rpm
Start Apache and Supervisor, and set to start on system startup:
systemctl enable httpd systemctl start httpd systemctl enable supervisord systemctl start supervisord
Create a new file called
/etc/php.d/elentra.ini
and add the following:date.timezone = America/Toronto display_errors = Off error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT expose_php = Off memory_limit = 512M post_max_size = 512M session.cookie_secure = 1 session.cookie_httponly = 1 session.cookie_samesite = Strict upload_max_filesize = 512M
Create an Elentra system user called
production
, which is used for production deployments:useradd -m production passwd production usermod -G apache -a production usermod -G production -a apache
Create and permission the SSH
authorized_keys
file for theproduction
user.cd /home/production mkdir /home/production/.ssh touch /home/production/.ssh/authorized_keys chown -R production:production /home/production/.ssh chmod 700 /home/production/.ssh chmod 600 /home/production/.ssh/authorized_keys
Add all developers' SSH public keys (i.e.
cat ~/.ssh/id_rsa.pub
) that are allowed to deploy Elentra to your production environment to the newauthorized_keys
file.vim /home/production/.ssh/authorized_keys
Create an Elentra system user called
staging
, which is used for staging deployments:useradd -m staging passwd staging usermod -G apache -a staging usermod -G staging -a apache
Create and permission the SSH
authorized_keys
file for thestaging
user.cd /home/staging mkdir /home/staging/.ssh touch /home/staging/.ssh/authorized_keys chown -R staging:staging /home/staging/.ssh chmod 700 /home/staging/.ssh chmod 600 /home/staging/.ssh/authorized_keys
Add all developers' SSH public keys (i.e.
cat ~/.ssh/id_rsa.pub
) that are allowed to deploy Elentra to your staging environment to the newauthorized_keys
file.vim /home/staging/.ssh/authorized_keys
Create and appropriately permission the Apache document root and Elentra storage directories for production.
mkdir -p /var/www/vhosts/elentra.med.university.edu/storage/ mkdir /var/www/vhosts/elentra.med.university.edu/storage/annualreports mkdir /var/www/vhosts/elentra.med.university.edu/storage/app mkdir /var/www/vhosts/elentra.med.university.edu/storage/app/cbe-uploads mkdir /var/www/vhosts/elentra.med.university.edu/storage/app/cbe-uploads/learner-self-assessment-files mkdir /var/www/vhosts/elentra.med.university.edu/storage/app/public mkdir /var/www/vhosts/elentra.med.university.edu/storage/cache mkdir /var/www/vhosts/elentra.med.university.edu/storage/cbme-uploads mkdir /var/www/vhosts/elentra.med.university.edu/storage/cbme-uploads/advisor-files mkdir /var/www/vhosts/elentra.med.university.edu/storage/community-discussions mkdir /var/www/vhosts/elentra.med.university.edu/storage/community-galleries mkdir /var/www/vhosts/elentra.med.university.edu/storage/community-shares mkdir /var/www/vhosts/elentra.med.university.edu/storage/eportfolio mkdir /var/www/vhosts/elentra.med.university.edu/storage/event-files mkdir /var/www/vhosts/elentra.med.university.edu/storage/exam-files mkdir /var/www/vhosts/elentra.med.university.edu/storage/framework mkdir /var/www/vhosts/elentra.med.university.edu/storage/framework/cache mkdir /var/www/vhosts/elentra.med.university.edu/storage/framework/cache/data mkdir /var/www/vhosts/elentra.med.university.edu/storage/framework/sessions mkdir /var/www/vhosts/elentra.med.university.edu/storage/framework/views mkdir /var/www/vhosts/elentra.med.university.edu/storage/logs mkdir /var/www/vhosts/elentra.med.university.edu/storage/lor mkdir /var/www/vhosts/elentra.med.university.edu/storage/msprs mkdir /var/www/vhosts/elentra.med.university.edu/storage/resource-images mkdir /var/www/vhosts/elentra.med.university.edu/storage/secure-access mkdir /var/www/vhosts/elentra.med.university.edu/storage/syllabi mkdir /var/www/vhosts/elentra.med.university.edu/storage/tmp mkdir /var/www/vhosts/elentra.med.university.edu/storage/user-photos chown -R production:production /var/www/vhosts/elentra.med.university.edu chmod -R 777 /var/www/vhosts/elentra.med.university.edu/storage/*
Create and appropriately permission the Apache document root and Elentra storage directories for staging.
mkdir -p /var/www/vhosts/staging.med.university.edu/storage/ mkdir /var/www/vhosts/staging.med.university.edu/storage/annualreports mkdir /var/www/vhosts/staging.med.university.edu/storage/app mkdir /var/www/vhosts/staging.med.university.edu/storage/app/cbe-uploads mkdir /var/www/vhosts/staging.med.university.edu/storage/app/cbe-uploads/learner-self-assessment-files mkdir /var/www/vhosts/staging.med.university.edu/storage/app/public mkdir /var/www/vhosts/staging.med.university.edu/storage/cache mkdir /var/www/vhosts/staging.med.university.edu/storage/cbme-uploads mkdir /var/www/vhosts/staging.med.university.edu/storage/cbme-uploads/advisor-files mkdir /var/www/vhosts/staging.med.university.edu/storage/community-discussions mkdir /var/www/vhosts/staging.med.university.edu/storage/community-galleries mkdir /var/www/vhosts/staging.med.university.edu/storage/community-shares mkdir /var/www/vhosts/staging.med.university.edu/storage/eportfolio mkdir /var/www/vhosts/staging.med.university.edu/storage/event-files mkdir /var/www/vhosts/staging.med.university.edu/storage/exam-files mkdir /var/www/vhosts/staging.med.university.edu/storage/framework mkdir /var/www/vhosts/staging.med.university.edu/storage/framework/cache mkdir /var/www/vhosts/staging.med.university.edu/storage/framework/cache/data mkdir /var/www/vhosts/staging.med.university.edu/storage/framework/sessions mkdir /var/www/vhosts/staging.med.university.edu/storage/framework/views mkdir /var/www/vhosts/staging.med.university.edu/storage/logs mkdir /var/www/vhosts/staging.med.university.edu/storage/lor mkdir /var/www/vhosts/staging.med.university.edu/storage/msprs mkdir /var/www/vhosts/staging.med.university.edu/storage/resource-images mkdir /var/www/vhosts/staging.med.university.edu/storage/secure-access mkdir /var/www/vhosts/staging.med.university.edu/storage/syllabi mkdir /var/www/vhosts/staging.med.university.edu/storage/tmp mkdir /var/www/vhosts/staging.med.university.edu/storage/user-photos chown -R staging:staging /var/www/vhosts/staging.med.university.edu chmod -R 777 /var/www/vhosts/staging.med.university.edu/storage/*
Generate the SSL private keys required for each of your hostnames:
mkdir -p /root/certificates/2023 cd /root/certificates/2023 openssl genrsa -out elentra.med.university.edu.key 2048 openssl genrsa -out staging.med.university.edu.key 2048
Generate the SSL certificate signing requests (CSRs) for your certificate authority for each of your hostnames.
openssl req -new -key elentra.med.university.edu.key -out elentra.med.university.edu.csr openssl req -new -key staging.med.university.edu.key -out staging.med.university.edu.csr
You will be asked a number of questions, answer accordingly, but do not answer enter anything for "Email Address", "A challenge password", or "An optional company name:
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CA State or Province Name (full name) []:Ontario Locality Name (eg, city) [Default City]:Kingston Organization Name (eg, company) [Default Company Ltd]:Queen's University Organizational Unit Name (eg, section) []:Health Sciences Education Technology Unit Common Name (eg, your name or your server's hostname) []:elentra.med.university.edu Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
If you have a valid Certificate Authority certificate, you should create a .crt file foreach hostname and paste in the certificate text:
vim /root/certificates/2023/elentra.med.university.edu.crt vim /root/certificates/2023/staging.med.university.edu.crt
You will also likely have a certificate authority root chain certificate. Also paste this into a file called
ca-certificate.crt
If you are only creating self-signed certificates, you should do this for each hostname:
openssl x509 -req -days 365 -in elentra.med.university.edu.csr -signkey elentra.med.university.edu.key -out elentra.med.university.edu.crt openssl x509 -req -days 365 -in staging.med.university.edu.csr -signkey staging.med.university.edu.key -out staging.med.university.edu.crt
Install the certificates in the Apache virtual host directory:
mkdir /var/www/vhosts/elentra.med.university.edu/cert/ cp /root/certificates/2023/elentra.med.university.edu.crt /var/www/vhosts/elentra.med.university.edu/cert/ cp /root/certificates/2023/elentra.med.university.edu.key /var/www/vhosts/elentra.med.university.edu/cert/ mkdir /var/www/vhosts/staging.med.university.edu/cert/ cp /root/certificates/2023/staging.med.university.edu.crt /var/www/vhosts/staging.med.university.edu/cert/ cp /root/certificates/2023/staging.med.university.edu.key /var/www/vhosts/staging.med.university.edu/cert/
Create the Apache VirtualHosts by creating a file named
000-elentra.conf
and placing it/etc/httpd/conf.d/
.For configurations where the web server is directly accessible from the internet, the file should contain the following:
# This will limit what information Apache reveals about itself. ServerTokens Prod ServerSignature Off TraceEnable Off SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # Apache performance tuning options for more connections. #<IfModule mpm_prefork_module> # MaxRequestWorkers 512 # ServerLimit 512 #</IfModule> # Production <VirtualHost *:80> ServerName elentra.med.university.edu ServerAdmin [email protected] RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} </VirtualHost> <VirtualHost *:443> ServerName elentra.med.university.edu:443 ServerAdmin [email protected] SSLEngine on SSLProtocol -all +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLCertificateFile /var/www/vhosts/elentra.med.university.edu/cert/elentra.med.university.edu.crt SSLCertificateKeyFile /var/www/vhosts/elentra.med.university.edu/cert/elentra.med.university.edu.key #SSLCACertificateFile /var/www/vhosts/elentra.med.university.edu/cert/ca-certificate.crt SSLUseStapling on Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;" Header always set X-Frame-Options SAMEORIGIN DocumentRoot /var/www/vhosts/elentra.med.university.edu/current/www-root <Directory "/var/www/vhosts/elentra.med.university.edu/current/www-root"> Options FollowSymLinks Require all granted AllowOverride all </Directory> ProxyPass "/app/" "ws://localhost:6000/app/" ProxyPassReverse "/app/" "ws://localhost:6000/app/" ProxyPass "/apps/" "http://localhost:6000/apps/" ProxyPassReverse "/apps/" "http://localhost:6000/apps/" </VirtualHost> # Staging <VirtualHost *:80> ServerName staging.med.university.edu ServerAdmin [email protected] RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} </VirtualHost> <VirtualHost *:443> ServerName staging.med.university.edu:443 ServerAdmin [email protected] SSLEngine on SSLProtocol -all +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLCertificateFile /var/www/vhosts/staging.med.university.edu/cert/staging.med.university.edu.crt SSLCertificateKeyFile /var/www/vhosts/staging.med.university.edu/cert/staging.med.university.edu.key #SSLCACertificateFile /var/www/vhosts/staging.med.university.edu/cert/ca-certificate.crt SSLUseStapling on Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;" Header always set X-Frame-Options SAMEORIGIN DocumentRoot /var/www/vhosts/staging.med.university.edu/current/www-root <Directory "/var/www/vhosts/staging.med.university.edu/current/www-root"> Options FollowSymLinks Require all granted AllowOverride all </Directory> ProxyPass "/app/" "ws://localhost:6000/app/" ProxyPassReverse "/app/" "ws://localhost:6000/app/" ProxyPass "/apps/" "http://localhost:6000/apps/" ProxyPassReverse "/apps/" "http://localhost:6000/apps/" </VirtualHost>
For configurations where a load balancer sits in front of the web server and the load balancer communicates with the web server over http, the file should look like this:
# This will limit what information Apache reveals about itself. ServerTokens Prod ServerSignature Off TraceEnable Off SSLStaplingCache "shmcb:logs/stapling-cache(150000)" # Apache performance tuning options for more connections. #<IfModule mpm_prefork_module> # MaxRequestWorkers 512 # ServerLimit 512 #</IfModule> # Production <VirtualHost *:80> ServerName elentra.med.university.edu ServerAdmin [email protected] DocumentRoot /var/www/vhosts/elentra.med.university.edu/current/www-root <Directory "/var/www/vhosts/elentra.med.university.edu/current/www-root"> Options FollowSymLinks Require all granted AllowOverride all </Directory> ProxyPass "/app/" "ws://localhost:6000/app/" ProxyPassReverse "/app/" "ws://localhost:6000/app/" ProxyPass "/apps/" "http://localhost:6000/apps/" ProxyPassReverse "/apps/" "http://localhost:6000/apps/" </VirtualHost> # Staging <VirtualHost *:80> ServerName staging.med.university.edu ServerAdmin [email protected] DocumentRoot /var/www/vhosts/staging.med.university.edu/current/www-root <Directory "/var/www/vhosts/staging.med.university.edu/current/www-root"> Options FollowSymLinks Require all granted AllowOverride all </Directory> ProxyPass "/app/" "ws://localhost:6000/app/" ProxyPassReverse "/app/" "ws://localhost:6000/app/" ProxyPass "/apps/" "http://localhost:6000/apps/" ProxyPassReverse "/apps/" "http://localhost:6000/apps/" </VirtualHost>
Do a deployment to the new server.
Point the
app.json
in the storage folder to the corresponding file in the codeln -s /var/www/vhosts/host.name.edu/current/www-root/core/storage/app/modules/app.json /var/www/vhosts/host.name.edu/storage/app/modules/app.json
Create a new file in the
/etc/supervisord.d
directory calledelentra.ini
, and use the following template snippet as a reference to create your own file. Please make sure that you have the correct path incommand
andstdout_logfile
, and thatuser
is the correct system account that your existing cron jobs are run as.\[program:elentra-queue-staging] process_name=%(program_name)s_%(process_num)02d command=php /var/www/vhosts/staging.elentra.med.university.edu/current/www-root/core/library/vendor/elentrapackages/elentra-1x-api/artisan queue:work --queue=high,emails,default,low --env=staging autostart=true autorestart=true user=staging numprocs=1 redirect_stderr=true stdout_logfile=/var/www/vhosts/staging.elentra.med.university.edu/storage/logs/worker.log [program:elentra-queue-production] process_name=%(program_name)s_%(process_num)02d command=php /var/www/vhosts/elentra.med.university.edu/current/www-root/core/library/vendor/elentrapackages/elentra-1x-api/artisan queue:work --queue=high,emails,default,low --env=production autostart=true autorestart=true user=production numprocs=1 redirect_stderr=true stdout_logfile=/var/www/vhosts/elentra.med.university.edu/storage/logs/worker.log [program:elentra-websocket-staging] process_name=%(program_name)s_%(process_num)02d command=php /var/www/vhosts/staging.elentra.med.university.edu/current/www-root/core/library/vendor/elentrapackages/elentra-1x-api/artisan websockets:serve --port=6000 --env=staging autostart=true autorestart=true user=staging numprocs=1 redirect_stderr=true stdout_logfile=/var/www/vhosts/staging.elentra.med.university.edu/storage/logs/websocket.log [program:elentra-websocket-production] process_name=%(program_name)s_%(process_num)02d command=php /var/www/vhosts/elentra.med.university.edu/current/www-root/core/library/vendor/elentrapackages/elentra-1x-api/artisan websockets:serve --port=6000 --env=production autostart=true autorestart=true user=production numprocs=1 redirect_stderr=true stdout_logfile=/var/www/vhosts/elentra.med.university.edu/storage/logs/websocket.log [group:elentra] programs=elentra-queue-staging,elentra-queue-production,elentra-websocket-staging,elentra-websocket-production
Test your new Apache configuration, then restart Apache and Supervisor.
apachectl configtest systemctl restart httpd systemctl restart supervisord
Last updated