Installing Orocommerce Community 5.0 on Ubuntu 20.04 LTS

In this how-to I will do all steps of a “fresh install” of Orocommerce 5.0 LTS on Ubuntu 20.04 LTS. You need to be able to administer an Unbutu or other Linux server and be able to use the text editors (vi, nano or what ever you like). If you can’t: STOP HERE and find somebody who can.


Orocommerce is quite a bit resource consuming so I created a “test server” on my VMWare machine with the following settings:

  • 4 Virtual CPUs
  • 4 GB of memory
  • SSD Disks (hardware mirrored)

Installing Ubuntu 20.04 will not be described here. I installed my server “straight forward” with only OpenSSH as extra package.

Create DNS record for your server

First step is to create a DNS record for your server and make sure that the DNS changes are synced to all DNS servers.

Update the Ubuntu server

sudo apt-get update
sudo apt-get -y dist-upgrade --fix-missing
sudo apt-get -y upgrade --fix-missing
sudo apt-get -y autoremove
sudo apt-get clean
sudo shutdown -r now

Set password for root:

sudo passwd

Install Chrony NTP Deamon

Whenever you do e-commerce it is a good idea to keep the time of your server as close as possible to the real time. Chrony is a NTP (Network Time Protocol) deamon which does that. Facebook uses Chrony for their servers, so why should you not? 🙂

sudo apt -y install chrony

Check wether the chrony deamon is syncing with other NTP servers. After a couple of minutes you want to see a server with a * or ^* in front of it:

chronyc sources

Install nodejs

Orocommerce needs nodejs 16.

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs

Verify that you’ve installed the new version by running node with the -v version flag:

node -v

You need to see at least version 16

Now install some programms we need later:

sudo apt -y install zip wget curl gcc g++ make jpegoptim pngquant dirmngr apt-transport-https lsb-release ca-certificates yarn

Install MySQL server

To install the MySQL server issue the following command:

sudo apt -y install mysql-server

Configure the MySQL Server

To store supplementary characters (such as 4-byte emojis), configure the options file to use the utf8mb4 character

Add the following code under [client] to /etc/mysql/debian.cnf

[client]
default-character-set = utf8mb4

Add the following code to /etc/mysql/mysql.conf.d/mysql.cnf

[mysql]
default-character-set = utf8mb4

Add the following code to /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
optimizer_search_depth = 0
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-authentication-plugin=mysql_native_password

It is recommended to use SSD’s to store the application data in the MySQL 8.X database. However, if you run your server on HDD and not SSD’s you need to also add the following to this file under [mysqld]:

[mysqld]
innodb_file_per_table = 0
wait_timeout = 28800

For the changes to take effect, restart MySQL server by running:

sudo systemctl enable mysql
sudo systemctl restart mysql

MySQL has a bug you might run into when securing your MySQL server.

mysql -u root

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.29-0ubuntu0.20.04.3 (Ubuntu)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password by ‘mynewpassword’;
Query OK, 0 rows affected (0.03 sec)

It is always a good idea to secure the mysql server:

sudo mysql_secure_installation

The MySQL deamon can valuate password strength.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No:

If you know what your doing and trust the other sysadmins you work with you can safely answer N here.

Now set the MySQL root password and write it down in a secure place or store it in a password manager.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : 

Answer: Y

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : 

Answer: Y

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 

Answer: Y

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : 

Answer: Y

Restart the mysql server:

sudo systemctl restart mysql

Login the MySQL server as root:

sudo mysql -u root -p

Create the MySQL user which will access the database from the website:

mysql> CREATE USER orocomm@localhost IDENTIFIED BY 's0m€$€cretP@$$w0rD';
Query OK, 0 rows affected (0.02 sec)

Store the password in a secured location, for instance a password manager.

Create the database:

mysql> CREATE DATABASE orocomm;
Query OK, 1 row affected, 1 warning (0.02 sec)

Grant access on the database by the user:

mysql> GRANT ALL ON orocomm.* TO orocomm@localhost;

You want to see a response like this:

Query OK, 0 rows affected (0.03 sec)

Enable start of the MySQL server at server boot and restart the MySQL server

sudo systemctl enable mysql
sudo systemctl restart mysql

Install Apache Webserver, Certbot and PHP

Install the software:

sudo apt -y install software-properties-common
sudo add-apt-repository -y ppa:ondrej/php
sudo add-apt-repository -y ppa:ondrej/apache2
sudo apt update
sudo apt -y upgrade
sudo apt -y install apache2 certbot python3-certbot-apache php8.1 php8.1-fpm php8.1-cli php8.1-pdo php8.1-mysqlnd php8.1-xml php8.1-soap php8.1-gd php8.1-zip php8.1-intl php8.1-mbstring php8.1-opcache php8.1-curl php8.1-bcmath php8.1-ldap php8.1-dev php8.1-imap php8.1-tidy php8.1-mongodb

Enable the some Apache modules:

sudo a2enmod rewrite headers proxy_fcgi setenvif

Enable http2

sudo a2enmod http2

Enable the PHP FPM module:

sudo a2enconf php8.1-fpm

Enable the automatic start of both the PHP FPM and Apache webserver:

sudo systemctl enable php8.1-fpm
sudo systemctl enable apache2

Restart PHP and the Apache Webserver:

sudo systemctl restart php8.1-fpm
sudo systemctl restart apache2

Configure PHP

In /etc/php/8.1/fpm/pool.d/www.conf change or uncomment the following parameters:

user = www-data
group = www-data
catch_workers_output = yes

In /etc/php/8.1/fpm/php.ini change or uncomment the following parameters:

memory_limit = 1024M
realpath_cache_size=4096K 
realpath_cache_ttl=600
opcache.enable=1 
opcache.enable_cli=0 
opcache.memory_consumption=512 
opcache.interned_strings_buffer=32 
opcache.max_accelerated_files=32531 
opcache.save_comments=1 

For the changes to take effect, restart PHP-FPM by running:

sudo systemctl restart php8.1-fpm

Install Composer v2

Install composer:

cd ~
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/bin/composer

Install Docker and Docker Compose

Install docker:

sudo apt -y install docker.io docker-compose
sudo usermod -aG docker $(whoami)
sudo systemctl enable --now docker
sudo systemctl start docker

Install Symfony Server and enable TLS

cd ~
sudo apt -y install libnss3-tools
wget https://get.symfony.com/cli/installer -O - | bash
sudo mv ~/.symfony/bin/symfony /usr/local/bin/symfony
sudo symfony server:ca:install

Install Orocommerce Community using Composer

cd /var/www
sudo mkdir oroshop
sudo chown yourusername. oroshop

Create a project and download the necessary files:

composer create-project oro/commerce-crm-application oroshop

Some important choices have to be made here: You can change the admin URL for example so it is much harder to guess for hackers.

database_driver (pdo_mysql):
database_host ('%env(ORO_DB_HOST)%'): localhost
database_port ('%env(ORO_DB_PORT)%'): 3306
database_name ('%env(ORO_DB_NAME)%'): orocomm
database_user ('%env(ORO_DB_USER)%'): orocomm
database_password ('%env(ORO_DB_PASSWORD)%'): s0m€$€cretP@$$w0rD
database_server_version ('%env(ORO_DB_VERSION)%):
database_driver_options ({ }):
mailer_transport ('%env(ORO_MAILER_DRIVER)%'):
mailer_host ('%env(ORO_MAILER_HOST)%'):
mailer_port ('%env(ORO_MAILER_PORT)%'):
mailer_encryption ('%env(ORO_MAILER_ENCRYPTION)%'):
mailer_user ('%env(ORO_MAILER_USER)%'):
mailer_password ('%env(ORO_MAILER_PASSWORD)%'):
websocket_bind_address (0.0.0.0):
websocket_bind_port (8080):
websocket_frontend_host (''): 
websocket_frontend_port (8080): 
websocket_frontend_path (''): 
websocket_backend_host (''):
websocket_backend_port (8080):
websocket_backend_path (''):
websocket_backend_transport (tcp):
websocket_backend_ssl_context_options ({ }):
web_backend_prefix (/admin): /admin_blurp
session_handler (session.handler.native_file):
secret ('%env(ORO_SECRET)%'):
installed (null):
assets_version (null):
assets_version_strategy (time_hash):
message_queue_transport (dbal):
message_queue_transport_config (null):
enable_price_sharding ('%env(bool:ORO_ENABLE_PRICE_SHARDING)%'):
deployment_type (null):
liip_imagine.jpegoptim.binary (null):
liip_imagine.pngquant.binary (null):
env(ORO_DB_HOST) (127.0.0.1):
env(ORO_DB_PORT) (null): 3306
env(ORO_DB_NAME) (b2b_crm_dev): orocomm
env(ORO_DB_USER) (root): orocomm
env(ORO_DB_PASSWORD) (null): s0m€$€cretP@$$w0rD
env(ORO_DB_VERSION) (null):
env(ORO_MAILER_DRIVER) (sendmail):
env(ORO_MAILER_HOST) (127.0.0.1):
env(ORO_MAILER_PORT) (null):
env(ORO_MAILER_ENCRYPTION) (null):
env(ORO_MAILER_USER) (null):
env(ORO_MAILER_PASSWORD) (null):
env(ORO_SECRET) (ThisTokenIsNotSoSecretChangeIt):
env(ORO_ENABLE_PRICE_SHARDING) ('0'):

Change directory to the oro installation directory

cd oroshop

If your base currency is not USD, you need to add your currency to parameters.yml. NOW! Edit sudo nano ./config/parameters.yml

Add the following line at the end:

currency: 'EUR'

Run the installer

php bin/console oro:install --env=prod --timeout=2000

Make sure you type something usefull at the “Application URL” part: If you don’t, you can start all over again

Administration setup.
Application URL (http://localhost): https://shop.yourdomain.com
Organization name (ORO): ABC
Username (admin): thebestadminintheworld
Email: thebestadminintheworld@yourdomain.com
First name: your_firstname
Last name: your_lastname
Password:
Formatting Code (en): 
Language (en):
Load sample data (y/n): y

Warm the API cache

php bin/console oro:api:doc:cache:clear  --env=prod

Configure Apache 2.4

Create a virtual webserver configuration file for Apache:

sudo nano /etc/apache2/sites-available/shop.yourdomain.com.conf

Change the name of the “shop.yourdomain.com” to the domain name of your website

Add the following to this file:

<VirtualHost *:80>
    ServerName shop.yourdomain.com
    #ServerAlias www.<your-domain-name>

    DirectoryIndex index.php
    DocumentRoot /var/www/oroshop/public
    <Directory  /var/www/oroshop/public>
        # enable the .htaccess rewrites
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/apache2/shop.yourdomain.com_error.log
    CustomLog /var/log/apache2/shop.yourdomain.com_access.log combined
</VirtualHost>

Replace <application-root-folder> with the absolute path to the Oro application. Replace <your-domain-name> with the configured domain name that is used for the Oro application.

Disable the default site and enable shop.yourdomain.com:

sudo a2dissite 000-default
sudo a2ensite shop.yourdomain.com

Reload apache:

sudo systemctl reload apache2

Have a look at the log file to check wether there are any errors reloading apache2

tail /var/log/syslog

Get the SSL certificate

I use the free Let’s Encrypt SSL cetrificates for my servers.

sudo certbot --apache

Go through all the steps…

sudo systemctl restart apache2

Have a look at the syslog to double check that Apache starts normally:

 tail /var/log/syslog 

Change the permissions and ownership

Set the correct ownership and permissions:

sudo chown -R www-data. /var/www/oroshop

Set up cron

Orocommerce needs a cron job to be fired every minute. To schedule execution of the oro:cron command every-minute,

sudo crontab -u www-data -e

add the following line to crontab file:

*/1 * * * * php /var/www/oroshop/bin/console oro:cron --env=prod > /dev/null

If you installed orocommerce in an other locat replace with an absolute path to the installed Oro application.

Install Supervisord

Install supervisord:

sudo apt -y install supervisor

Create a configuration file:

sudo nano /etc/supervisor/conf.d/oroshop.conf

Add the following to this file:

[program:oro_web_socket]
command=php ./bin/console gos:websocket:server --env=prod
numprocs=1
autostart=true
autorestart=true
directory=/var/www/oroshop
user=www-data
redirect_stderr=true

[program:oro_message_consumer]
command=php ./bin/console oro:message-queue:consume --env=prod
process_name=%(program_name)s_%(process_num)02d
numprocs=5
autostart=true
autorestart=true
directory=/var/www/oroshop
user=www-data
redirect_stderr=true

Enable supervisord at boot and restart supervisord

sudo systemctl enable supervisor
sudo systemctl restart supervisor

Now watch supervisord for a couple of minutes by repeating:

sudo supervisorctl status

You need to see the supervisor running for at least 2 minutes without restarting itself. This is what you want to see after a couple of minutes:

$ sudo supervisorctl status
oro_message_consumer:oro_message_consumer_00 RUNNING pid 54342, uptime 0:03:31
oro_message_consumer:oro_message_consumer_01 RUNNING pid 54343, uptime 0:03:31
oro_message_consumer:oro_message_consumer_02 RUNNING pid 54344, uptime 0:03:31
oro_message_consumer:oro_message_consumer_03 RUNNING pid 54345, uptime 0:03:31
oro_message_consumer:oro_message_consumer_04 RUNNING pid 54346, uptime 0:03:31
oro_web_socket RUNNING pid 54347, uptime 0:03:31

Make the OroCommerce demo theme configurable

For a starter it is nice to make your theme a bit configurable so you can add your own logo and corlors. Thanks to Yevhen Shyshkin for his work: https://github.com/yshyshkin/DefaultThemeConfigurationBundle

$ cd /var/www/oroshop
$ composer require ys-tools/default-theme-configuration-bundle
$ rm -rf var/cache/prod
$ php bin/console cache:clear --env=prod
$ php bin/console oro:assets:install --env=prod