Deployment guide

Easy Digital Downloads

Overview

Easy Digital Downloads is an open source ecommerce platform for selling digital products such as ebooks, software, plugins, themes, music, photography, design assets and documents. It provides a shopping cart and checkout, secure file delivery with access control, discount codes, customer records and purchase histories, and sales and earnings reporting. It runs on WordPress, so you keep the familiar admin, the theme ecosystem and the REST API alongside the commerce features.

This SecureAnyCloud image installs WordPress 7.0.4 and Easy Digital Downloads 3.7.0 on a LAMP stack drawn entirely from Ubuntu 24.04 noble universe, with no third-party APT repositories. Easy Digital Downloads is already activated, so the Checkout, Receipt, Order History, Confirmation and Products pages exist the moment the instance boots.

What you get:

  • Easy Digital Downloads 3.7.0, activated, at /var/www/html/wordpress/wp-content/plugins/easy-digital-downloads
  • WordPress 7.0.4 from the official wordpress.org release at /var/www/html/wordpress, with WordPress's automatic updates left on so it keeps receiving security releases
  • WordPress and Easy Digital Downloads both verified at build time against the checksums wordpress.org publishes
  • Apache 2.4.58 with mod_rewrite enabled, virtual host at /etc/apache2/sites-available/easy-digital-downloads.conf
  • MySQL 8.0.46 with an edd database and an edduser account, both given a unique password on first boot
  • PHP 8.3.6 with the curl, gd, mbstring, xml, zip, intl, bcmath and mysqli extensions (images are processed with PHP's GD library)
  • WP-CLI 2.12.0 at /usr/local/bin/wp
  • easy-digital-downloads-firstboot.service, which generates every credential uniquely for each instance
  • Apache and MySQL enabled and starting automatically on boot
  • 24/7 SecureAnyCloud support

Key facts:

  • Platform: Ubuntu 24.04 LTS, Azure Gen2
  • Default SSH user: azureuser
  • Store administrator: SecureAnyCloud
  • Web root: /var/www/html/wordpress
  • Credentials file: /stage/scripts/easy-digital-downloads-credentials.log (mode 0600, root only)
  • HTTP port: 80

Prerequisites

Before you deploy, make sure you have:

  • An active Azure subscription
  • An active Azure Marketplace subscription for this offer
  • An SSH key pair for the azureuser account
  • A virtual network and subnet in your target region
  • A network security group allowing inbound TCP 22 and TCP 80

Recommended VM size: Standard_B2s (2 vCPU, 4 GB RAM) is sufficient for a small to medium catalog. Move to a D2s_v3 or larger for high-traffic stores or large download libraries.

1

Deploy the virtual machine

Option A: Azure Portal

  • Choose Create a resource and search the Marketplace for this SecureAnyCloud offer
  • Select the plan and choose Create
  • Pick your subscription, resource group and region
  • Set the VM size to Standard_B2s
  • Set the authentication type to SSH public key and the username to azureuser
  • On the Networking tab, allow inbound SSH (22) and HTTP (80)
  • Select Review + create, then Create

Option B: Azure CLI

az vm image terms accept --urn sac1647283583153:easy-digital-downloads-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name my-edd-vm \
  --image sac1647283583153:easy-digital-downloads-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard \
  --location eastus
2

Connect via SSH

From your own workstation, look up the instance's public IP address and connect to it:

az vm show --resource-group my-resource-group --name my-edd-vm \
  --show-details --query publicIps --output tsv ssh azureuser@<vm-ip>
3

Verify the stack

Confirm that both services are running and listening:

sudo systemctl is-active apache2 mysql
sudo ss -tln | grep -E ':80 |:3306 '

Check the version of each component:

apache2 -v | head -1 php -v | head -1 mysql --version

Confirm WordPress and Easy Digital Downloads are installed and the plugin is active:

sudo -u www-data wp core version --path=/var/www/html/wordpress sudo -u www-data wp plugin list --path=/var/www/html/wordpress --fields=name,status,version

The image ships WordPress 7.0.4. WordPress's own automatic updates are left at their defaults, so WordPress installs new releases by itself. On an instance that has been running for a while, wp core version may report a newer release.

Easy Digital Downloads, other plugins and themes are updated when you choose (see Security Recommendations).

4

Retrieve your store credentials

Every credential on this instance is generated on first boot and written to a file that only root can read. Nothing is shared between instances, and nothing is baked into the image.

sudo cat /stage/scripts/easy-digital-downloads-credentials.log

The file contains these keys:

  • EDD_URL: the public storefront address
  • EDD_ADMIN_URL: the WordPress admin sign-in address
  • EDD_DOWNLOADS_URL: a direct link to your digital products list
  • WP_ADMIN_USER: the store administrator username (SecureAnyCloud)
  • WP_ADMIN_PASSWORD: the store administrator password, unique to this instance
  • WP_DB_NAME, WP_DB_USER, WP_DB_PASSWORD: the WordPress database and its account
  • MYSQL_ROOT_PASSWORD: the MySQL root password, unique to this instance

Confirm that the first-boot service completed and that the file is protected:

sudo systemctl is-active easy-digital-downloads-firstboot.service
sudo ls -l /stage/scripts/easy-digital-downloads-credentials.log
sudo ls -l /var/lib/sac/data/easy-digital-downloads-firstboot.done
5

Sign in to your store

Browse to http://<vm-ip>/wp-admin/ and sign in as SecureAnyCloud with the WP_ADMIN_PASSWORD from Step 4.

You land on the WordPress dashboard. Easy Digital Downloads adds the Downloads and Store Reports entries to the left menu.

The image derives its site address from the host you browse it on. The storefront therefore works on the public IP straight away, and it keeps working unchanged if you later point a domain name at the instance.

6

Review your digital products

Choose Downloads in the left menu. This is your product catalog. A newly deployed store is empty. Every product you add appears here with its price, categories, net sales and net revenue.

Easy Digital Downloads creates its store pages when it activates, which happens on first boot. Confirm that they exist:

sudo -u www-data wp post list --post_type=page --path=/var/www/html/wordpress --fields=post_title,post_name --format=table
7

Create your first digital product

In the admin, choose Downloads, then Add Download. Give the product a name and set a price in the Download Prices panel. Attach the file the customer receives in the Download Files panel, and publish the product when you are ready to sell.

You can also create a product from the command line, which is useful for bulk imports and automation:

sudo -u www-data wp post create --post_type=download \
  --post_title='Starter Icon Pack' --post_status=publish \
  --path=/var/www/html/wordpress sudo -u www-data wp post list --post_type=download --path=/var/www/html/wordpress --fields=ID,post_title,post_status

Files attached to a product are delivered through Easy Digital Downloads rather than served directly, so a customer cannot share a working download URL with someone who has not paid.

8

Configure payments and store settings

Choose Downloads, then Settings. Set your store country, your currency and the payment gateways you want to accept.

The core plugin supports Stripe and PayPal. Test mode lets you place an order end to end before you take real money.

Choose Downloads, then Reports, to track sales, earnings, average order value, refunds, taxes and file downloads over any date range.

9

View the public storefront

Browse to http://<vm-ip>/ to see the storefront your customers will use.

Confirm that both the storefront and the sign-in page answer:

curl -sf -o /dev/null -w 'storefront: HTTP %{http_code}\n' http://127.0.0.1/
curl -sf -o /dev/null -w 'sign in: HTTP %{http_code}\n' http://127.0.0.1/wp-login.php

Server components

The image contains these components:

  • Easy Digital Downloads 3.7.0: /var/www/html/wordpress/wp-content/plugins/easy-digital-downloads
  • WordPress 7.0.4 (updates itself): /var/www/html/wordpress
  • Apache HTTP Server 2.4.58: /etc/apache2
  • MySQL 8.0.46: /var/lib/mysql
  • PHP 8.3.6: /etc/php/8.3
  • WP-CLI 2.12.0: /usr/local/bin/wp

Filesystem layout

The VM has these mount points:

  • / (29 GB): root filesystem, including the web root and the MySQL data directory
  • /boot (881 MB): operating system kernel files
  • /boot/efi (105 MB): UEFI boot partition (Gen2 Hyper-V)
  • /mnt (7.8 GB): Azure temporary resource disk, cleared on deallocation

Key directories:

  • /var/www/html/wordpress: WordPress and Easy Digital Downloads
  • /var/www/html/wordpress/wp-content/uploads: media library and product files
  • /var/www/html/wordpress/wp-config.php: database credentials and site configuration
  • /etc/apache2/sites-available/easy-digital-downloads.conf: Apache virtual host
  • /var/log/apache2/edd-access.log, edd-error.log: Apache logs for the store
  • /var/lib/mysql: MySQL data directory

Scripts and log files

These files drive and record first boot:

  • /usr/local/sbin/easy-digital-downloads-firstboot.sh: generates every per-instance credential on first boot
  • /etc/systemd/system/easy-digital-downloads-firstboot.service: the systemd unit that runs it once
  • /stage/scripts/easy-digital-downloads-credentials.log: the generated credentials, mode 0600, root only
  • /var/lib/sac/data/easy-digital-downloads-firstboot.done: sentinel proving first boot completed
  • /var/log/easy-digital-downloads-firstboot.log: first-boot log

On startup

The first time the instance boots, easy-digital-downloads-firstboot.service runs once and does the following:

  • Generates a MySQL root password, a WordPress database password and a store administrator password, each unique to this instance
  • Creates the edd database and the edduser account
  • Writes wp-config.php with those credentials
  • Installs WordPress and creates the SecureAnyCloud administrator
  • Activates Easy Digital Downloads, which creates the store pages
  • Writes the credentials file with mode 0600 owned by root
  • Writes its sentinel file so it never runs again

The image ships with no database and no configuration file. There is no default password to change and no credential shared between customers.

Manage the services

sudo systemctl status apache2 --no-pager sudo systemctl restart apache2
sudo systemctl restart mysql

To follow the store's web logs, run:

sudo tail -n 20 /var/log/apache2/edd-error.log

Backups

Back up both the database and the uploaded product files. The database holds your products, orders and customers. The uploads directory holds the files your customers download.

sudo mysqldump -uroot -p"$(sudo grep '^MYSQL_ROOT_PASSWORD=' /stage/scripts/easy-digital-downloads-credentials.log | cut -d= -f2-)" edd > /var/backups/edd-$(date +%F).sql
sudo tar czf /var/backups/edd-uploads-$(date +%F).tar.gz -C /var/www/html/wordpress/wp-content uploads

Troubleshooting

The storefront does not load. Check that Apache is running and listening, then read the error log:

sudo systemctl is-active apache2
sudo tail -n 20 /var/log/apache2/edd-error.log

You cannot sign in. Re-read the password from the credentials file, which is authoritative for this instance. If the password was changed and lost, reset it with WP-CLI:

sudo -u www-data wp user update sac --user_pass='<new-password>' --path=/var/www/html/wordpress

The credentials file contains only a comment. First boot has not finished yet. Wait a few moments, then check the service:

sudo systemctl status easy-digital-downloads-firstboot.service --no-pager sudo tail -n 20 /var/log/easy-digital-downloads-firstboot.log

Product pages return 404. The pretty permalink rules live in /var/www/html/wordpress/.htaccess, which first boot writes. If it has been removed, open Settings, then Permalinks, in the admin and select Save Changes.

You can also regenerate it from the command line. A plain wp rewrite flush --hard cannot write .htaccess, because WP-CLI cannot detect Apache's rewrite module:

sudo -u www-data wp eval 'add_filter("got_rewrite", "__return_true"); flush_rewrite_rules(true);' --path=/var/www/html/wordpress

Database connection errors. Confirm MySQL is running and that WordPress can reach it:

sudo systemctl is-active mysql
sudo -u www-data wp db check --path=/var/www/html/wordpress

Security Recommendations

  • Enable HTTPS before you take payments. Point a domain at the instance, then install a certificate. The site address follows the host you browse it on, so no reconfiguration is needed after the certificate is issued: bash sudo apt-get install -y certbot python3-certbot-apache sudo certbot --apache -d <your-domain>
  • Restrict the network security group so port 22 is reachable only from your management network. Ports 80 and 443 stay open to your customers.
  • Keep Easy Digital Downloads and your theme updated from the admin, or with wp plugin update --all and wp theme update --all. WordPress core installs its own updates through WordPress's automatic updates. Leave them on so security releases arrive without delay.
  • Apply operating system updates regularly, for example sudo apt-get update && sudo apt-get upgrade.
  • Store the credentials file contents in your own secret manager, then keep the file readable only by root.
  • Turn on two-factor authentication for administrator accounts with a WordPress plugin before the store goes live.

Licensing

Easy Digital Downloads and WordPress are both licensed under the GNU General Public License version 2 or later. Both are free to use commercially.

SecureAnyCloud provides the packaged image and commercial support separately from the upstream projects.

Support

For assistance, contact SecureAnyCloud support:

  • Email: sales@secureanycloud.com
  • Response time: 24/7 with a guaranteed 24-hour response SLA
  • Website: https://secureanycloud.com

Deploy on Azure

Launch Easy Digital Downloads 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

Deploy on Azure