Installation on Linux

Version Date Notes By
1.6 2025-06-16 Updated environment variables for the backend BRB
1.5 2025-05-06 Updated PHP version to PHP 8.4 BRB
1.4 2025-02-05 Updated VirtualHost configuration and added WKHTMLTOPDF download instructions to REDHAT systems BRB
1.3 2024-02-15 Added instructions to open port for Laravel Echo Server in cases of multiple instances servers BRB
1.2 2024-02-06 Updated apache, php, composer and wkhtmltopdf/wkhtmltoimage installation instructions BRB
1.1 2023-09-21 Updated versions BRB
1.0 2023-02-07 Updated apache configuration in regards to php8.1-fpm extension and re-formatted some content BRB
0.9 2022-03-11 Updated extension list and commands for php8.1 BRB
0.8 2021-09-06 Added bcmath to required php extension list FPA
0.7 2020-09-09 Added wkhtmltopdf instructions FPA
0.6 2020-08-11 Added charset and collation to create database. Minor fix's JFM
0.5 2019-12-10 Added notes and added some extra warnings/information JFM
0.4 2019-12-10 Added new php extensions, added https configuration, added some extra steps for laravel-echo-server, some fixes and cleanup JFM
0.3 2017-10-30 added laravel-echo-server and laravel queues configuration JFM
0.2 2017-10-17 Fixes to the documentation JFM & ROB
0.1 2017-07-21 Initial release JFM

Notes

As an example, we are using sgi.domain.com and sgi-back.domain.com as the domains. This should be changed to the real subdomains

Debian base installation (Ubuntu 22.04 LTS)

Make sure the system is up-to-date by running sudo apt-get update && sudo apt-get upgrade

Backend

  1. First install Apache + PHP

sudo add-apt-repository ppa:ondrej/php -y

sudo apt-get install apache2 php8.4 libapache2-mod-php8.4

Make sure apache and php are running OK by creating a phpinfo.php file on the web folder, usually in /var/www/ or /var/www/html

  1. Next install all dependencies and extensions needed

Current PHP extensions: sudo apt install php8.4-fpm php8.4-cli php8.4-curl php8.4-dev php8.4-mysql php8.4-ldap php8.4-xml php8.4-curl php8.4-gd php8.4-zip php8.4-mbstring php8.4-soap php8.4-fileinfo php8.4-sqlite3 php8.4-intl php8.4-bcmath php8.4-redis php8.4-imagick

To enable PHP 8.4 FPM in Apache2 do:

a2enmod proxy_fcgi setenvif
a2enconf php8.4-fpm

Check PHP version being used: php -v If the PHP version is wrong (e.g. PHP8.3), change the default PHP version used: sudo update-alternatives --config php.

By this time you should check phpinfo again to see if every extension is loaded

  1. Next install redis: sudo apt-get install redis-server

  2. Next install composer

sudo apt-get install curl
curl -sS https://getcomposer.org/installer -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
sudo composer self-update
composer -v
  1. Check out the backend to a web folder, usually put the folder in the /var/www folder, and name give it the name do the subdomain when possible, something like /var/www/sgi-back.client.com

git clone https://gitlab.wemake.pt/wemake/sgi/backend/core.git /var/www/sgi-back.client.com

If asked, don't save the authentication account.

cd /var/www/sgi-back.client.com
git config core.fileMode false
  1. Create a configuration file
cd /var/www/sgi-back.client.com
sudo cp .env.example .env
  1. Run composer install: sudo composer install

If you are not going to use SQL Server you may get the following error

[Symfony\Component\Debug\Exception\FatalThrowableError]

Undefined class constant 'SQLSRV_ATTR_FETCHES_NUMERIC_TYPE'

In this case just edit the config/database.php file and comment the lines

PDO::ATTR_STRINGIFY_FETCHES => false,

PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true

  1. Configure the .env file (Always check the current configuration file as this may be already obsolete)
Directive Description
APP_BACKEND_URL Backend URL
APP_FRONTEND_URL Frontend URL
DB_CONNECTION SGBD Driver (mysql, sqlsrv, etc...)
DB_HOST Name or IP of the database host
DB_PORT Port number of the database host
DB_DATABASE Name of the database
DB_USERNAME Username of the database
DB_PASSWORD Password of the user of the database
BROADCAST_CONNECTION Driver for the broadcast (usually redis)
CACHE_STORE Driver for the cache
SESSION_DRIVER Driver for the session
QUEUE_DRIVER Driver for the queue
SENTRY_PRIVATE_DSN Sentry private DNS (speak with JFM / FPA for sentry key information)
SENTRY_PUBLIC_DSN Sentry public DNS (speak with JFM / FPA for sentry key information)
LICENSES_NUMBER Number of licenses
  1. Generate the application key: php artisan key:generate and the JWT secret: php artisan jwt:secret

  2. Set the correct permissions

sudo chown -R www-data storage/ bootstrap/cache/ && sudo chmod -R 775 storage/ bootstrap/cache/

9.5. ☺ Create the database, user and grant the user privileges over the database

mysql
CREATE DATABASE <database_name> CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci;
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON <database_name>.* TO 'user'@'localhost';
  1. Run migrations: php artisan migrate

  2. Create a new apache configuration file under the folder /etc/apache2/sites-available/. Name it something like sgi-back.domain.com.conf

Without HTTPS

<Directory /var/www/html/sgi-back.domain.com/public>
    AllowOverride All
    Require all granted
</Directory>

<VirtualHost sgi-back.domain.com:80>
    ServerName sgi-back.domain.com
    DocumentRoot /var/www/html/sgi-back.domain.com/public

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost"
    </FilesMatch>

    ErrorLog /var/log/apache2/sgi-back.domain.com/apache-logs/error.log
    CustomLog /var/log/apache2/sgi-back.domain.com/apache-logs/access.log combined
</VirtualHost>

With HTTPS

<Directory /var/www/html/sgi-back.domain.com/public>
    AllowOverride All
    Require all granted
</Directory>
<VirtualHost sgi-back.domain.com:443>
    ServerName sgi-back.domain.com
    DocumentRoot /var/www/html/sgi-back.domain.com/public

    SSLEngine on
    SSLCertificateFile <path_to_cert_file>
    SSLCertificateKeyFile <path_to_key_file>

    ErrorLog /var/log/apache2/sgi-back.domain.com/apache-logs/error.log
    CustomLog /var/log/apache2/sgi-back.domain.com/apache-logs/access.log combined
</VirtualHost>
  1. Enable the new configuration: sudo a2ensite sgi-back.domain.com.conf

  2. Because of the php-fpm configuration: sudo a2enmod actions proxy_fcgi rewrite

  3. Reload apache: sudo systemctl reload apache2

  4. Test that the backend is online: http://sgi-back.domain.com/ you should get an NotFoundHttpException error, which is normal because there's no route for root

Laravel Echo Server

  1. Install laravel-echo-server: sudo npm install -g laravel-echo-server

  2. Copy the laravel-echo-server.example.json to laravel-echo-server.json: cp laravel-echo-server.example.json laravel-echo-server.json

  3. Configure the configuration file laravel-echo-server.json

Without HTTPS

{
  "appKey": "47r1i66li4cn9anb4pocpb9h6eb5fc7d35f5lhs363gho1kmqcqf2tred6p2",
  "authHost": "https://sgi-back.domain.com",
  "authEndpoint": "/broadcasting/auth",
  "database": "redis",
  "databaseConfig": {
    "redis": {
      "port": "6379",
      "host": "127.0.0.1",
      "options": {
        "db": 1
      }
    },
    "sqlite": {
      "databasePath": "/database/laravel-echo-server.sqlite"
    }
  },
  "devMode": false,
  "host": "sgi-back.domain.com",
  "port": "6001",
  "referrers": [
    {
      "host": "*",
      "apiKey": "nrhmk8ic64lgnqbs6t794gpj6per33ho5q34j2mrgia61j8hf238rf0c014b"
    }
  ],
  "socketio": {
    "cookie": "false"
  },
  "protocol": "http",
  "sslCertPath": "",
  "sslKeyPath": "",
  "verifyAuthPath": true,
  "verifyAuthServer": false
}

With HTTPS

{
  "appKey": "47r1i66li4cn9anb4pocpb9h6eb5fc7d35f5lhs363gho1kmqcqf2tred6p2",
  "authHost": "https://sgi-back.domain.com",
  "authEndpoint": "/broadcasting/auth",
  "database": "redis",
  "databaseConfig": {
    "redis": {
      "port": "6379",
      "host": "127.0.0.1",
      "options": {
        "db": 1
      }
    },
    "sqlite": {
      "databasePath": "/database/laravel-echo-server.sqlite"
    }
  },
  "devMode": false,
  "host": "sgi-back.domain.com",
  "port": "6002",
  "referrers": [
    {
      "host": "*",
      "apiKey": "nrhmk8ic64lgnqbs6t794gpj6per33ho5q34j2mrgia61j8hf238rf0c014b"
    }
  ],
  "socketio": {
    "cookie": "false"
  },
  "protocol": "https",
  "sslCertPath": "<path_to_cert_file>",
  "sslKeyPath": "<path_to_key_file>",
  "verifyAuthPath": true,
  "verifyAuthServer": false
}
  1. Run laravel-echo-server start on the backend folder and check if it works. If it is working, stop it by doing Ctrl+c and go to next step

  2. Use supervidord to configure the service, create a new file /etc/supervisor/conf.d/sgi-back.domain.com.conf and use the following configuration (change as needed)

[program:laravel-echo-server]
directory=/var/www/sgi-back.domain.com
command=laravel-echo-server start
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/var/www/sgi-back.domain.com/storage/logs/laravel-echo-server.log
  1. Start the service supervisorctl start laravel-echo-server

If the same server has different installations give a more specific name to the program, ex: [client:prod-laravel-echo-server]

  1. (OPTIONAL) If, after installation, you see that the server is not working, it might be that the port is not open (e.g. when you have multiple installations on the same server machine), do the following:
    sudo iptables -A INPUT -p tcp --match multiport --dports x11-1:<port-number> -j ACCEPT

    Replace <port-number> to with the associated port (e.g. 6050).

To show the new rule: sudo iptables -L

It should show something like this:

ACCEPT   tcp  --  anywhere     anywhere   multiport dports x11-1:<port-number>

Laravel Queue

  1. Use supervidord to configure the service, create (or edit) a file /etc/supervisor/conf.d/sgi-back.domain.com.conf and use the following configuration (change as needed)
[program:laravel-queue-work]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/sgi-back.client.com/artisan queue:work --sleep=3
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/sgi-back.domain.com/storage/logs/laravel-queue-work.log
  1. Start the service supervisorctl start laravel-queue-work

If the same server has different instalations give a more specific name to the program, ex: [program:test-laravel-queue-work]

Scheduler

  1. To configure the scheduler to run the scheduled jobs (every minute jobs, daily jobs, etc.), we need to use crontab.

    crontab -e
  2. Add the following line at the end:

    * * * * * php /var/www/sgi-back.client.com/artisan schedule:run >> /dev/null 2>&1

You may have to specify the PHP version (e.g. php8.4) if you're installing in a server that has other clients installed that use previous PHP versions.

WKHTMLTOPDF

  1. Install required packages if they aren’t already installed: sudo apt-get install libxrender1 wget xfonts-75dpi fontconfig xfonts-base

  2. Download the appropriated binaries for the latest stable release. Example for version 0.12.6 and Ubuntu 22.04:

#UBUNTU
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo dpkg -i wkhtmltox_0.12.6.1-3.jammy_amd64.deb

#REDHAT
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox-0.12.6.1-3.almalinux8.aarch64.rpm
sudo dnf install ./wkhtmltox-0.12.6.1-3.almalinux8.aarch64.rpm
  1. After installing, you can verify that they’re installed by running the commands below:
wkhtmltopdf --version

That should output similar line as shown below:

wkhtmltopdf 0.12.6 (with patched qt)

Run the next command below:

wkhtmltoimage --version

Will output similar line as shown below:

wkhtmltoimage 0.12.6 (with patched qt)
  1. Open the .env file, and update the paths to the binaries. Example:
WKHTML_PDF_BINARY="/usr/local/bin/wkhtmltopdf"
WKHTML_IMG_BINARY="/usr/local/bin/wkhtmltoimage"

In order to locate both binaries, run the following commands:

which wkhtmltopdf
which wkhtmltoimage

Frontend

  1. Use and existing development machine and export the frontend files by running gulp export

  2. Create a folder for the frontend, something like /var/www/sgi.domain.com

Note: different distros of linux may use different permissions (eg www-data)

  1. Set the permissions of the newly created folder sudo chown -R www-data.devel /var/www/sgi.domain.com and chmod -R 775 /var/www/sgi.domain.com

  2. Copy the results of the gulp export and change the env.js file accordingly

  3. Create a new apache configuration file under the folder /etc/apache2/sites-available/. Name it something like sgi.domain.com.conf

Without HTTPS

<Directory /var/www/html/sgi.domain.com>
        AllowOverride All
        Require all granted
</Directory>
<VirtualHost sgi.domain.com:80>
        ServerName sgi.domain.com
        DocumentRoot /var/www/html/sgi.domain.com

        ErrorLog /var/log/sgi.domain.com/apache-logs/error.log
        CustomLog /var/log/sgi.domain.com/apache-logs/access.log combined
</VirtualHost>

With HTTPS

<Directory /var/www/html/sgi.domain.com>
        AllowOverride All
        Require all granted
</Directory>
<VirtualHost sgi.domain.com:443>
        ServerName sgi.domain.com
        DocumentRoot /var/www/html/sgi.domain.com

        SSLEngine on
        SSLCertificateFile <path_to_cert_file>
        SSLCertificateKeyFile <path_to_key_file>

        ErrorLog /var/log/sgi.domain.com/apache-logs/error.log
        CustomLog /var/log/sgi.domain.com/apache-logs/access.log combined
</VirtualHost>
  1. Enable the new configuration: sudo a2ensite sgi.domain.com.conf

  2. Reload apache: sudo systemctl reload apache2

  3. Test it: http://sgi.domain.com/

Extra documentation

Supervisord - http://supervisord.org/