Oc
E-commerce Azure

OroCommerce Community Edition on Ubuntu 24.04 on Azure User Guide

| Product: OroCommerce Community Edition on Ubuntu 24.04 LTS on Azure

Overview

OroCommerce Community Edition is the open source commerce platform from Oro, Inc. built for business to business selling. It pairs a customer facing storefront with a full back office for the product catalog, master catalog categories, price lists, inventory statuses, customers and customer users, shopping lists, requests for quote, orders and landing pages, and it includes the OroCRM customer relationship tools. The cloudimg image delivers the official OroCommerce 7.0 LTS release fully installed on Ubuntu 24.04, with the production front end assets already built and every background worker running, so a working B2B store and back office are serving within minutes of launch. Backed by 24/7 cloudimg support.

OroCommerce Community Edition is open source software: the application is licensed under the Open Software License 3.0 (OSL 3.0) and the OroPlatform framework under the MIT License. The optional Oro Conversation add on, which Oro, Inc. licenses only to its SaaS customers under a proprietary licence, is not included in this image. OroCommerce and Oro are trademarks of Oro, Inc.; cloudimg is not affiliated with or endorsed by Oro, Inc. This image packages the upstream open source release with cloudimg's provisioning, hardening and support.

What is included:

  • OroCommerce Community Edition 7.0.4, served from /var/www/orocommerce
  • PHP 8.5 (php8.5-fpm) behind nginx, with the storefront at https://<vm-ip>/ and the back office at https://<vm-ip>/admin/, both over HTTPS; port 80 only redirects to HTTPS
  • A local PostgreSQL 17 database, bound to localhost only
  • The message queue consumer (orocommerce-consumer), the websocket server (orocommerce-websocket, localhost only, proxied at /ws) and scheduled tasks (orocommerce-cron.timer, every minute), all supervised by systemd
  • Oro's built in database search engine and database message queue (no Elasticsearch, RabbitMQ or Redis to run)
  • A per-VM back office administrator password, application secret, database password, OAuth 2.0 signing keypair and HTTPS certificate, all generated on first boot and written to a root-only file, so no default or shared credentials ship in the image
  • No sample data: you start with an empty catalog
  • 24/7 cloudimg support

The OroCommerce back office sign-in page

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended starting size: with the storefront and back office under concurrent load and a full search reindex running, the stack used about 1.6 GiB of memory, and the extra headroom keeps PostgreSQL and PHP caches warm and leaves room for upgrades, which rebuild the front end assets. Scale up to a larger size for big catalogs or heavy traffic. NSG inbound: allow 22/tcp from your management network and 443/tcp (HTTPS) from wherever your buyers and staff will browse; 80/tcp is optional and only redirects to HTTPS.

Step 1: Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OroCommerce Community Edition by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2ms or larger); under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTPS (443). Then Review + create and Create.

Step 2: Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name orocommerce \
  --image <marketplace-image-urn> \
  --size Standard_B2ms \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open HTTPS to reach the store:

az vm open-port --resource-group <your-rg> --name orocommerce --port 443 --priority 900

Step 3: Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4: Confirm the OroCommerce stack is running

On the very first boot, a one shot service generates this VM's secrets and administrator password, rebuilds the application cache with the new secret and only then starts the web server and workers. Allow two to four minutes after launch before the site answers. Then check the services:

for u in postgresql@17-main php8.5-fpm nginx orocommerce-consumer orocommerce-websocket orocommerce-cron.timer; do
  printf '%-24s %s\n' "$u:" "$(systemctl is-active $u)"
done

Every unit reports active:

postgresql@17-main:      active
php8.5-fpm:              active
nginx:                   active
orocommerce-consumer:    active
orocommerce-websocket:   active
orocommerce-cron.timer:  active

Only nginx (ports 80 and 443) and SSH listen on public interfaces; PostgreSQL and the websocket server are bound to localhost:

sudo ss -tlnp | awk 'NR>1 {split($6, p, "\""); print $4, p[2]}' | sort -u
0.0.0.0:22 sshd
0.0.0.0:443 nginx
0.0.0.0:80 nginx
127.0.0.1:5432 postgres
127.0.0.1:8080 php
127.0.0.53%lo:53 systemd-resolve
127.0.0.54:53 systemd-resolve
[::]:22 sshd
[::]:443 nginx
[::]:80 nginx

OroCommerce services and listening sockets

Why the site may not answer straight away. nginx and php8.5-fpm are deliberately held back until orocommerce-firstboot.service has generated this VM's secrets. That is a security control, not a fault: if first boot ever failed, the VM stays unreachable rather than serving a half configured store. If nginx reports inactive right after launch, wait a minute and check again.

Step 5: Retrieve the first-boot credentials

sudo cat /root/orocommerce-credentials.txt

The file lists the store URLs, the back office administrator (admin) and its password, and the application's PostgreSQL credentials, all unique to this VM:

# OroCommerce credentials for this VM (generated at first boot, unique to this VM)
orocommerce.url=https://<vm-ip>/
orocommerce.backoffice_url=https://<vm-ip>/admin/
orocommerce.admin.user=admin
orocommerce.admin.pass=<generated-password>
postgresql.database=oro_db
postgresql.user=oro_app
postgresql.pass=<generated-password>

It is readable by root only:

sudo stat -c '%a %U:%G %n' /root/orocommerce-credentials.txt
600 root:root /root/orocommerce-credentials.txt

Per-VM OroCommerce credentials, root only, passwords masked

Step 6: Understand the store URL

OroCommerce stores the address it advertises (the application URL and the default website's URL) in its database, and the storefront redirects any other host name to that URL. First boot sets all three to this VM's public IP address:

sudo runuser -u www-data -- php /usr/local/lib/orocommerce/config-get.php oro_ui.application_url oro_website.url oro_website.secure_url
oro_ui.application_url=https://<vm-ip>
oro_website.url=https://<vm-ip>
oro_website.secure_url=https://<vm-ip>

You can confirm from the VM itself that the storefront and back office answer on that address over HTTPS, and that port 80 only redirects:

IP=$(sudo sed -n 's#^orocommerce.url=https://\([^/]*\)/$#\1#p' /root/orocommerce-credentials.txt)
curl -sk --resolve "$IP:443:127.0.0.1" -o /dev/null -w 'storefront   %{url_effective}  HTTP %{http_code}\n' "https://$IP/"
curl -sk --resolve "$IP:443:127.0.0.1" -o /dev/null -w 'back office  %{url_effective}  HTTP %{http_code}\n' "https://$IP/admin/user/login"
curl -s -o /dev/null -w 'port 80      %{url_effective}  HTTP %{http_code} -> %{redirect_url}\n' http://127.0.0.1/
storefront   https://<vm-ip>/  HTTP 200
back office  https://<vm-ip>/admin/user/login  HTTP 200
port 80      http://127.0.0.1/  HTTP 301 -> https://127.0.0.1/

When you point a domain name at the VM, update the stored URLs with the helper in Step 11, otherwise buyers browsing by name are redirected to the IP address.

Step 7: Sign in to the back office

Browse to https://<vm-public-ip>/admin/ and sign in as admin with the password from Step 5. The certificate is self signed and unique to this VM, so your browser shows a warning until you install your own certificate (Step 11). You can also prove the sign in from the VM:

IP=$(sudo sed -n 's#^orocommerce.url=https://\([^/]*\)/$#\1#p' /root/orocommerce-credentials.txt)
JAR=$(mktemp)
CSRF=$(curl -sk --resolve "$IP:443:127.0.0.1" -c "$JAR" -b "$JAR" "https://$IP/admin/user/login" | sed -n 's/.*name="_csrf_token" value="\([^"]*\)".*/\1/p' | head -n 1)
curl -sk --resolve "$IP:443:127.0.0.1" -c "$JAR" -b "$JAR" -o /dev/null -w 'login-check  HTTP %{http_code}\n' \
  --data-urlencode "_username=admin" --data-urlencode "_password=<OROCOMMERCE_ADMIN_PASSWORD>" \
  --data-urlencode "_csrf_token=$CSRF" "https://$IP/admin/user/login-check"
PAGE=$(curl -sk --resolve "$IP:443:127.0.0.1" -b "$JAR" "https://$IP/admin/")
rm -f "$JAR"
echo -n 'signed in as: '; grep -m1 -o 'Store Administrator' <<<"$PAGE"
login-check  HTTP 302
signed in as: Store Administrator

Store URLs, HTTPS front door and a back office sign in from the VM

After signing in you land on the back office dashboard:

The OroCommerce back office dashboard

Change the administrator password straight away: open the user menu in the top right (Store Administrator), choose My User, then Change password. Update the administrator's email address from the same page, because password reset links are sent there.

Step 8: Create your first product and see it on the storefront

  1. In the back office choose Products > Products, then Create Product.
  2. Keep the type Simple and the product family Default, then choose Continue.
  3. Enter a SKU and a Name, set Status to Enabled and Inventory Status to In Stock, and choose Save and Close.

A product created in the OroCommerce back office

The message queue consumer indexes the new product for the storefront within a few seconds. Open https://<vm-public-ip>/product/view/<id> (the id is in the back office URL), or browse the storefront catalog, as a guest:

The same product on the OroCommerce storefront

The storefront catalog listing products

To start selling, give products prices (on the product's Product Prices tab or in a price list), organise them into categories in the Master Catalog, and set up payment and shipping methods and their rules from the System menu. Customer accounts and their buyers are managed under Customers.

Step 9: Background workers

OroCommerce relies on three background services, all installed and running:

  • Message queue consumer (orocommerce-consumer.service): processes search indexing, price and visibility updates, imports and exports. systemd restarts it automatically.
  • Websocket server (orocommerce-websocket.service): pushes live notifications to the back office. It listens on 127.0.0.1:8080 and is published only through nginx at https://<vm-ip>/ws, which requires the browser's origin to match the store.
  • Scheduled tasks (orocommerce-cron.timer): runs oro:cron every minute.
echo "consumer:  $(systemctl is-active orocommerce-consumer)"
echo "websocket: $(systemctl is-active orocommerce-websocket)"
echo "cron:      $(systemctl show orocommerce-cron.service -p Result --value)"
echo "queued:    $(sudo -u postgres psql -d oro_db -tAc 'SELECT count(*) FROM oro_message_queue')"
consumer:  active
websocket: active
cron:      success
queued:    0

Background workers and component versions

Follow the consumer's log with sudo journalctl -u orocommerce-consumer -f, and the application log at /var/www/orocommerce/var/logs/prod.log.

Step 10: Configure outbound email

Outbound email is off until you configure it, so no password reset or order confirmation message leaves the VM by accident. In the back office open System > Configuration, then General Setup > Email Configuration, fill in SMTP Settings (host, port, encryption, user name and password for your mail provider), use Check Connection (New Settings), and save. OroCommerce sends through those SMTP settings as soon as they are saved; no file on the VM needs editing.

Step 11: Use a domain name and your own certificate

Point a DNS A record at the VM's public IP, then update the store URLs so the storefront stops redirecting to the IP address:

sudo orocommerce-set-url https://shop.example.com

Replace the self-signed certificate with one issued for your domain, keeping the same paths, and reload nginx:

sudo cp fullchain.pem /etc/ssl/orocommerce/orocommerce.crt
sudo cp privkey.pem  /etc/ssl/orocommerce/orocommerce.key
sudo chmod 600 /etc/ssl/orocommerce/orocommerce.key
sudo nginx -t && sudo systemctl reload nginx

If you use Let's Encrypt, open port 80 in the NSG for the HTTP challenge, obtain the certificate with your preferred ACME client, and point the two paths above at the issued files.

Step 12: Security model

  • No default credentials. The image contains no usable administrator password, database password, application secret, OAuth key or TLS key. First boot generates all of them for this VM, and passes the administrator and database passwords to the tools that set them on standard input, never on a command line, so they never appear in the process list or the system journal.
  • Fail closed. nginx and php8.5-fpm do not start until first boot has finished.
  • Minimal exposure. Only nginx (80, which only redirects, and 443) and SSH listen publicly. PostgreSQL, PHP-FPM and the websocket server are local only. nginx executes nothing but index.php: development front controllers, tracking scripts, configuration and source files return 404.
  • No customer accounts, no sample data. Storefront sign in with any default or blank credential is refused because no customer user exists until you create one.
  • Order PDFs are off. Oro renders order PDFs with Gotenberg, an optional external service that is not part of Community Edition, so the storefront PDF download and PDF generation at checkout are disabled. To enable them, run a Gotenberg service, add ORO_PDF_GENERATOR_GOTENBERG_API_URL=http://<gotenberg-host>:3000 to /var/www/orocommerce/.env-app.local, clear the cache (sudo runuser -u www-data -- php /var/www/orocommerce/bin/console cache:clear --env=prod), restart php8.5-fpm and orocommerce-consumer, and switch the two order PDF options back on in the back office system configuration for orders.

Step 13: Back up the store

Back up the database and the uploaded media together:

sudo -u postgres pg_dump -Fc oro_db > /var/backups/oro_db-$(date +%F).dump
sudo tar -czf /var/backups/orocommerce-files-$(date +%F).tar.gz -C /var/www/orocommerce var/data public/media

Copy the files off the VM (for example to Azure Blob Storage) and keep /var/www/orocommerce/.env-app.local somewhere safe as well, because it holds the application secret that encrypts stored integration credentials.

Step 14: Maintenance and upgrades

Ubuntu security updates install automatically through unattended-upgrades, including PHP 8.5 from the ondrej/php repository and PostgreSQL 17 from the PostgreSQL project repository. Apply everything else and reboot when convenient:

sudo apt-get update && sudo apt-get -y upgrade

OroCommerce itself is upgraded with Composer and Oro's oro:platform:update command, which also rebuilds the front end assets and therefore needs Node.js 24 and pnpm 10 (the image removed them after building its assets). Follow Oro's upgrade documentation for the target release, take a backup first, and put the store in maintenance mode while it runs.

Support

cloudimg provides 24/7 technical support for this image by email at support@cloudimg.co.uk and by live chat: deployment, credentials, back office and storefront configuration, products and price lists, SMTP, domains and certificates, the consumer, websocket and scheduled tasks, backups, performance tuning, patching and upgrades.