Drupal Commerce
Overview
Drupal Commerce is the open source e-commerce framework built on Drupal. It models commerce natively: products and variations, carts and orders, a configurable checkout flow, pricing and promotions, tax and currency handling, and pluggable payment gateways are all first-class Drupal entities. Every commerce object is fieldable, referenceable and viewable with the same tools as the rest of the site, so catalog data and editorial content live together.
This SecureAnyCloud image delivers Drupal Commerce fully installed on Ubuntu 24.04: Drupal core 11.4.4 with Drupal Commerce 3.3.8, served by Apache 2.4 with PHP 8.3 and backed by MySQL 8.0. Everything comes from the Ubuntu 24.04 main and universe repositories, with no third-party APT repositories.
The site installs onto your VM at first boot with the Commerce modules enabled and a default store created. You land on a working storefront and Commerce admin, not an installer.
What you get:
- Drupal core 11.4.4 (GPL-2.0-or-later) at
/var/www/html/drupal, installed from the official ftp.drupal.org tarball and verified against the publisher's own checksum at build time - Drupal Commerce 3.3.8 (Commerce Core, GPL-2.0-or-later) installed via Composer, with nine Commerce modules enabled:
commerce,commerce_price,commerce_store,commerce_product,commerce_order,commerce_cart,commerce_checkout,commerce_paymentandcommerce_tax - Apache 2.4 with
mod_rewrite, MySQL 8.0, and PHP 8.3 with themysql,gd,mbstring,xml,curl,zip,intlandbcmathextensions - Drush 13 at
/usr/local/bin/drushfor command-line administration - A default store created at first boot, so products are immediately sellable
- Per-VM administrator, application database and MySQL root passwords, all generated on first boot and written to a root-only file; no shared or default credential ships in the image
- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key, and a VNet with a subnet.
Standard_B2s (2 vCPU, 4 GB RAM) is the recommended size and is sufficient for a low to medium traffic store. Move to a D2s or D4s size for larger catalogs, heavy concurrent checkout traffic or many contributed modules.
Allow inbound TCP 80 from the addresses that should reach the storefront, and TCP 22 for administration.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure portal, choose Create a resource, search for Drupal Commerce on Ubuntu 24.04 LTS by SecureAnyCloud, and select Create.
Pick your subscription, resource group and region, and choose the Standard_B2s size. Supply your SSH public key for the azureuser account, and allow inbound ports 22 and 80.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:drupal-commerce-ubuntu-24-04:default:latest
az vm create \
--resource-group my-resource-group \
--name my-drupal-commerce \
--image sac1647283583153:drupal-commerce-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardStep 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Run the check below. Both services that back Drupal Commerce should report active. The first-boot service should report inactive, because it is a one-shot that has already completed. The storefront should answer HTTP 200.
systemctl is-active apache2 mysql drupal-commerce-firstboot ss -tlnH | awk '{print $1, $4}' | grep -E ':80$|:3306$' curl -s -o /dev/null -w 'storefront -> %{http_code}\n' http://127.0.0.1/Expected: active, active, then inactive for the completed one-shot, the two listening sockets, and storefront -> 200.
MySQL listens on 127.0.0.1:3306 only, so the database is not exposed to the network.
Step 5 - Retrieve your administrator credentials
On the first boot of every VM, a one-shot service (drupal-commerce-firstboot.service) generates credentials that are unique to that VM. These are a fresh MySQL root password, a fresh application database password and a fresh Drupal administrator password.
The service then installs the site, enables the Commerce modules and creates the default store. No shared or default credential ships in the image. Read the credentials file and check its permissions:
sudo cat /stage/scripts/drupal-commerce-credentials.log
sudo stat -c '%a %U:%G %n' /stage/scripts/drupal-commerce-credentials.logThe file is mode 0600 and owned by root, so only root can read it. It contains the storefront and admin URLs, the administrator username (SecureAnyCloud) and password, and the database credentials.
To confirm that the database credentials authenticate, and that a wrong password is rejected, run the following in the VM's shell:
DB_USER=$(sudo awk -F= '$1=="DRUPAL_DB_USER"{print $2}' /stage/scripts/drupal-commerce-credentials.log)
DB_PASS=$(sudo awk -F= '$1=="DRUPAL_DB_PASSWORD"{print $2}' /stage/scripts/drupal-commerce-credentials.log)
OK=$(mysql -u "$DB_USER" -p"$DB_PASS" -D drupalcommerce -N -B -e 'SELECT 1' 2>/dev/null || true)
BAD=$(mysql -u "$DB_USER" -p'wrong-password' -D drupalcommerce -N -B -e 'SELECT 1' 2>/dev/null || true)
echo "correct password -> ${OK:-rejected}"
echo "wrong password -> ${BAD:-rejected}"Expected: correct password -> 1 and wrong password -> rejected.
Step 6 - Visit the storefront
Browse to http://<vm-public-ip>/. The storefront uses the Olivero front-end theme and is ready for your own content and products.
The image does not bake an address into the site configuration. Drupal derives the base URL from the incoming request. The storefront therefore answers correctly on the VM's public address, its private address, or a custom domain you point at it later, with no reconfiguration. To see this for yourself, run:
PRIVATE_IP=$(hostname -I | awk '{print $1}')
curl -s -o /dev/null -w 'public request -> %{http_code}\n' -H "Host: shop.example.com" http://127.0.0.1/user/login
curl -s -o /dev/null -w 'private address -> %{http_code}\n' "http://${PRIVATE_IP}/user/login"Expected: 200 for both.
Step 7 - Sign in as the administrator
Browse to http://<vm-public-ip>/user/login. Sign in with the username SecureAnyCloud and the password from the credentials file.
Step 8 - Open the Commerce dashboard
After signing in, choose Commerce in the administration menu. The dashboard gives you Orders, Products and Configuration. It also shows store performance panels for carts, placed orders, gross sales and best-selling products.
Step 9 - Review your store
First boot creates a default store, SecureAnyCloud Demo Store, because Commerce requires a store before anything can be sold. Products are therefore sellable immediately.
Open Commerce -> Configuration -> Stores and select Edit. Set your own store name, email address, postal address, default currency and billing countries.
Step 10 - Create your first product
Choose Commerce -> Products -> Add product. Give the product a title and description, then select Save and add variations.
Create the purchasable variations, each with its own SKU and price. Customers add variations to the cart, so a single product can carry several sizes, colors or editions.
Step 11 - Confirm the versions
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush status --field=drupal-version php -r '$l=json_decode(file_get_contents("/var/www/html/drupal/composer.lock"),true); foreach($l["packages"] as $p){ if($p["name"]==="drupal/commerce") printf("drupal/commerce %s\n",$p["version"]); }' php -v | head -1Expected: 11.4.4, drupal/commerce 3.3.8, and PHP 8.3.
Step 12 - Confirm Commerce is installed
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush pm:list --status=enabled --filter=commerce --field=name
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush php:eval 'printf("stores configured: %d\n", count(\Drupal::entityTypeManager()->getStorage("commerce_store")->loadMultiple()));'Expected: the enabled Commerce modules, then stores configured: 1.
First-boot service and security model
drupal-commerce-firstboot.service is a one-shot unit ordered After=mysql.service apache2.service. On the first boot of each VM it generates the per-VM secrets, provisions the application database, installs the site, enables the Commerce modules and creates the default store. It then writes the credentials file at mode 0600 and drops a sentinel at /var/lib/sac/data/drupal-commerce-firstboot.done, so it runs exactly once.
systemctl status drupal-commerce-firstboot.service --no-pager | head -5 sudo test -f /var/lib/sac/data/drupal-commerce-firstboot.done && echo "sentinel present — first boot completed"Every secret is generated on your own VM. No two SecureAnyCloud deployments of this image share a credential, and nothing sensitive exists in the published image.
Administration from the command line
Drush is installed for routine administration. Run it as shown:
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush status | head -12To reset the administrator password, or to add another administrator:
cd /var/www/html/drupal
sudo -u www-data /usr/local/bin/drush user:password sac 'your-new-password'
sudo -u www-data /usr/local/bin/drush user:create alice --mail=alice@example.com --password='her-password' sudo -u www-data /usr/local/bin/drush user:role:add administrator aliceUsing your own domain and HTTPS
The image serves plain HTTP on port 80, so it works immediately on any address. For a production storefront, point your domain at the VM and terminate TLS. The quickest route is Certbot with the Apache plugin:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d shop.example.comNo address is baked into the site configuration, so the storefront answers on your domain as soon as DNS resolves. There is nothing to reconfigure in Drupal.
For production, also tighten the trusted host pattern. The image ships a permissive pattern so the storefront works on any address out of the box. Once you have settled on your domain, edit /var/www/html/drupal/sites/default/settings.php and replace it:
$settings['trusted_host_patterns'] = ['^shop\.example\.com$'];Keeping Drupal and Commerce up to date
Drupal core and Drupal Commerce are pinned to the versions verified at build time, so the image you certified is the image that runs. Apply upstream updates with Composer when you are ready:
cd /var/www/html/drupal
sudo -u www-data composer update drupal/core-recommended --with-all-dependencies sudo -u www-data composer update drupal/commerce --with-all-dependencies sudo -u www-data /usr/local/bin/drush updatedb -y sudo -u www-data /usr/local/bin/drush cache:rebuildAlways take a backup first (see below), and test updates outside production.
Two advisory notices appear on Drupal's status report on this platform. Neither is a fault.
- HTML5 validation: the image explicitly sets
enable_html5_validationtoTRUEto preserve current form behavior. Drupal removes this setting in Drupal 13, so the notice is a forward-compatibility advisory, not an error. - GD library / AVIF: the PHP GD build shipped by Ubuntu 24.04 supports GIF, JPEG, PNG and WebP but not AVIF, because the distribution package is built without that codec. All common web image formats are supported.
Backup and maintenance
Back up the database and the site files:
cd /var/www/html/drupal
sudo -u www-data /usr/local/bin/drush sql:dump --result-file=/var/backups/drupalcommerce-$(date +%F).sql
sudo tar czf /var/backups/drupal-files-$(date +%F).tar.gz /var/www/html/drupal/sites/default/filesThe operating system receives unattended security upgrades. Check for pending updates with:
apt-get -s -o APT::Get::Always-Include-Phased-Updates=true dist-upgrade | grep -c '^Inst ' || trueLicensing
Drupal core and Drupal Commerce are both distributed under the GNU General Public License, version 2 or later (GPL-2.0-or-later). The license text ships in the image at /var/www/html/drupal/LICENSE.txt and /var/www/html/drupal/modules/contrib/commerce/LICENSE.txt.
SecureAnyCloud charges only for the packaging, maintenance and support of the image. The software itself remains under its open source license.
Support
Every SecureAnyCloud image includes 24/7 support. Contact sales@secureanycloud.com with your Azure subscription ID and the VM name.
Deploy on Azure
Launch Drupal Commerce on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Drupal Commerce is the open source e-commerce framework built on Drupal. It models commerce natively: products and variations, carts and orders, a configurable checkout flow, pricing and promotions, tax and currency handling, and pluggable payment gateways are all first-class Drupal entities. Every commerce object is fieldable, referenceable and viewable with the same tools as the rest of the site, so catalog data and editorial content live together.
This SecureAnyCloud image delivers Drupal Commerce on a LAMP stack: Drupal core 11.4.4 with Drupal Commerce 3.3.8, served by Apache 2.4 with PHP 8.3 and backed by MySQL 8.0. Everything comes from the Ubuntu main and universe repositories, with no third-party APT repositories.
The site installs onto your instance at first boot with the Commerce modules enabled and a default store created. You land on a working storefront and Commerce admin, not an installer.
What you get:
- Drupal core 11.4.4 (GPL-2.0-or-later) at
/var/www/html/drupal, installed from the official ftp.drupal.org tarball and verified against the publisher's own checksum at build time - Drupal Commerce 3.3.8 (Commerce Core, GPL-2.0-or-later) installed via Composer, with nine Commerce modules enabled:
commerce,commerce_price,commerce_store,commerce_product,commerce_order,commerce_cart,commerce_checkout,commerce_paymentandcommerce_tax - Apache 2.4 with
mod_rewrite, MySQL 8.0, and PHP 8.3 with themysql,gd,mbstring,xml,curl,zip,intlandbcmathextensions - Drush 13 at
/usr/local/bin/drushfor command-line administration - A default store created at first boot, so products are immediately sellable
- Two dedicated EBS data volumes: the MySQL datadir at
/var/lib/mysqland the Drupal application tier at/var/www, each independently resizable - Per-instance administrator, application database and MySQL root passwords, all generated on first boot and written to a root-only file, plus a Drupal site installed fresh per instance with a unique admin and a unique security hash salt; no shared or default credential ships in the image
- 24/7 SecureAnyCloud support
Connecting to your instance
Connect over SSH on port 22 with the private key for the key pair you selected at launch. The login user depends on the operating system variant you launched.
For the Ubuntu 24.04 variant, the SSH login user is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<instance-public-ip>Prerequisites
You need an AWS account, an EC2 key pair and a VPC subnet.
m5.large (2 vCPU, 8 GB RAM) is the recommended instance type and is sufficient for a low to medium traffic store. Move to an m5.xlarge or larger for large catalogs, heavy concurrent checkout traffic or many contributed modules.
In the instance's security group, allow inbound TCP 80 from the addresses that should reach the storefront, and TCP 22 for administration. To serve HTTPS later, also allow TCP 443.
Step 1 - Launch from AWS Marketplace
In the AWS Marketplace console, find Drupal Commerce by SecureAnyCloud. Choose Continue to Subscribe, then Continue to Configuration and Continue to Launch.
Pick your region, the m5.large instance type, your VPC subnet and your key pair. Select a security group that allows inbound 22 and 80.
Step 2 - Launch from the EC2 CLI
aws ec2 run-instances \
--image-id <ami-id-from-the-listing> \
--instance-type m5.large \
--key-name your-key \
--security-group-ids sg-xxxxxxxx \
--subnet-id subnet-xxxxxxxx \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=drupal-commerce}]'Step 3 - Confirm the services are running
Run the check below. Both services that back Drupal Commerce should report active, and the storefront should answer HTTP 200. MySQL listens on 127.0.0.1:3306 only, so the database is never exposed to the network.
for s in apache2 mysql; do echo "$s -> $(systemctl is-active "$s")"; done ss -tlnH | awk '{print $4}' | grep -E ':80$|:3306$' curl -s -o /dev/null -w 'storefront -> HTTP %{http_code}\n' http://127.0.0.1/Expected: apache2 -> active, mysql -> active, the two listening sockets, and storefront -> HTTP 200.
Step 4 - Retrieve your administrator credentials
On the first boot of every instance, a one-shot service (drupal-commerce-firstboot.service) generates credentials that are unique to that instance. These are a fresh MySQL root password, a fresh application database password and a fresh Drupal administrator password.
The service then installs the site, so the security hash salt and the administrator account are unique too. It enables the Commerce modules and creates the default store. No shared or default credential ships in the image.
sudo stat -c '%a %U:%G %n' /stage/scripts/drupal-commerce-credentials.log
sudo awk -F= '/^DRUPAL_ADMIN_USER=/{print} /^DRUPAL_COMMERCE_URL=/{print} /^DRUPAL_COMMERCE_ADMIN_URL=/{print}' /stage/scripts/drupal-commerce-credentials.logThe file is mode 0600 and owned by root, so only root can read it. It contains the storefront and admin URLs, the administrator username (SecureAnyCloud) and password, and the database credentials. Read the administrator password itself with sudo cat /stage/scripts/drupal-commerce-credentials.log.
To confirm that the database credentials authenticate, and that a wrong password is rejected, run the following in the instance's shell. It prints no secret.
DB_USER=$(sudo awk -F= '$1=="DRUPAL_DB_USER"{print $2}' /stage/scripts/drupal-commerce-credentials.log)
DB_PASS=$(sudo awk -F= '$1=="DRUPAL_DB_PASSWORD"{print $2}' /stage/scripts/drupal-commerce-credentials.log)
OK=$(mysql -u "$DB_USER" -p"$DB_PASS" -D drupalcommerce -N -B -e 'SELECT 1' 2>/dev/null || true)
BAD=$(mysql -u "$DB_USER" -p'wrong-password' -D drupalcommerce -N -B -e 'SELECT 1' 2>/dev/null || true)
echo "correct password -> ${OK:-rejected}"
echo "wrong password -> ${BAD:-rejected}"Expected: correct password -> 1 and wrong password -> rejected.
Step 5 - Visit the storefront
Browse to http://<instance-public-ip>/product/1, or open any product. The storefront uses the Olivero front-end theme and shows a price and an add-to-cart action. The store is ready for your own products and content.
The image does not bake an address into the site configuration. Drupal derives the base URL from the incoming request. The storefront therefore answers correctly on the instance's public address, its private address, or a custom domain you point at it later, with no reconfiguration and no "host not trusted" error. To see this for yourself, run:
PRIVATE_IP=$(hostname -I | awk '{print $1}')
curl -s -o /dev/null -w 'custom host -> HTTP %{http_code}\n' -H "Host: shop.example.com" http://127.0.0.1/user/login
curl -s -o /dev/null -w 'private addr -> HTTP %{http_code}\n' "http://${PRIVATE_IP}/user/login"Expected: 200 for both.
Step 6 - Try the shopping cart
Add a product to the cart. The customer can adjust quantities in the cart before checking out.
Step 7 - Try checkout
Start checkout. The default flow offers a returning-customer login and a guest checkout, then collects order information and payment.
To take live payments, add a payment gateway under Commerce -> Configuration -> Payment gateways.
Step 8 - Sign in as the administrator
Browse to http://<instance-public-ip>/user/login. Sign in with the username SecureAnyCloud and the password from the credentials file.
Choose Commerce in the administration menu. The dashboard gives you Orders, Products and Configuration, alongside store performance panels for carts, placed orders, gross sales and best-selling products.
To confirm the administrator account from the command line, run:
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush user:information sac --field=nameStep 9 - Add your first product
Choose Commerce -> Products -> Add product. Give the product a title and description, then select Save and add variations.
Create the purchasable variations, each with its own SKU and price. Customers add variations to the cart, so a single product can carry several sizes, colors or editions.
Step 10 - Confirm the versions
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush status --field=drupal-version php -r '$l=json_decode(file_get_contents("/var/www/html/drupal/composer.lock"),true); foreach($l["packages"] as $p){ if($p["name"]==="drupal/commerce") printf("drupal/commerce %s\n",$p["version"]); }' php -v | head -1Expected: 11.4.4, drupal/commerce 3.3.8, and PHP 8.3.
Step 11 - Confirm Commerce is installed
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush pm:list --status=enabled --filter=commerce --field=name
cd /var/www/html/drupal && sudo -u www-data /usr/local/bin/drush php:eval 'printf("stores configured: %d\n", count(\Drupal::entityTypeManager()->getStorage("commerce_store")->loadMultiple()));'Expected: the enabled Commerce modules, then stores configured: 1.
First-boot service and security model
drupal-commerce-firstboot.service is a one-shot unit ordered After=mysql.service apache2.service. On the first boot of each instance it generates the per-instance secrets, provisions the application database, installs the site, enables the Commerce modules and creates the default store. It then writes the credentials file at mode 0600 and drops a sentinel at /var/lib/sac/data/drupal-commerce-firstboot.done, so it runs exactly once.
It resolves the instance's public address via EC2 IMDSv2 for the credentials-file URL, falling back to the private address.
sudo test -f /var/lib/sac/data/drupal-commerce-firstboot.done && echo "sentinel present - first boot completed"Every secret and the whole site are generated on your own instance. No two SecureAnyCloud deployments of this image share a credential or a hash salt, and nothing sensitive exists in the published image.
Administration from the command line
Drush is installed for routine administration. To reset the administrator password or add another administrator, run:
cd /var/www/html/drupal
sudo -u www-data /usr/local/bin/drush user:password sac 'your-new-password'
sudo -u www-data /usr/local/bin/drush user:create alice --mail=alice@example.com --password='her-password' sudo -u www-data /usr/local/bin/drush user:role:add administrator aliceUsing your own domain and HTTPS
The image serves plain HTTP on port 80, so it works immediately on any address. For a production storefront, point your domain at the instance and terminate TLS. The quickest route is Certbot with the Apache plugin:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d shop.example.comNo address is baked into the site configuration, so the storefront answers on your domain as soon as DNS resolves. There is nothing to reconfigure in Drupal. Alternatively, place an Application Load Balancer with an AWS Certificate Manager certificate in front of the instance.
For production, also tighten the trusted host pattern. The image ships a permissive pattern so the storefront works on any address out of the box. Once you have settled on your domain, edit /var/www/html/drupal/sites/default/settings.php and replace it:
$settings['trusted_host_patterns'] = ['^shop\.example\.com$'];Keeping Drupal and Commerce up to date
Drupal core and Drupal Commerce are pinned to the versions verified at build time, so the image you launched is the image that runs. Apply upstream updates with Composer when you are ready:
cd /var/www/html/drupal
sudo -u www-data composer update drupal/core-recommended --with-all-dependencies sudo -u www-data composer update drupal/commerce --with-all-dependencies sudo -u www-data /usr/local/bin/drush updatedb -y sudo -u www-data /usr/local/bin/drush cache:rebuildAlways take a backup first (see below), and test updates outside production.
Backup and maintenance
Back up the database and the site files:
cd /var/www/html/drupal
sudo -u www-data /usr/local/bin/drush sql:dump --result-file=/var/backups/drupalcommerce-$(date +%F).sql
sudo tar czf /var/backups/drupal-files-$(date +%F).tar.gz /var/www/html/drupal/sites/default/filesThe operating system receives unattended security upgrades. Check for pending updates with:
apt-get -s -o APT::Get::Always-Include-Phased-Updates=true dist-upgrade 2>/dev/null | grep -c '^Inst ' || trueLicensing
Drupal core and Drupal Commerce are both distributed under the GNU General Public License, version 2 or later (GPL-2.0-or-later). The license text ships in the image at /var/www/html/drupal/LICENSE.txt and /var/www/html/drupal/modules/contrib/commerce/LICENSE.txt.
SecureAnyCloud charges only for the packaging, maintenance and support of the image. The software itself remains under its open source license.
Support
Every SecureAnyCloud image includes 24/7 support. Contact sales@secureanycloud.com with your AWS account ID and the instance ID.
Deploy on AWS
Launch Drupal Commerce with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com