How to Install Magento 2 on Ubuntu 24.04 VPS: Enterprise-Grade Self-Hosted Ecommerce
Magento 2 (now officially Adobe Commerce Open Source) is the most feature-complete open-source ecommerce platform available. It powers stores with hundreds of thousands of SKUs, multi-store multi-language catalogs, complex B2B workflows, and billion-dollar annual revenues. Self-hosting it on your own VPS gives you total control over data, performance, and extensions — with none of the per-order fees that SaaS platforms charge. This guide takes you from a fresh Ubuntu 24.04 VPS to a production-ready Magento 2.4.7 storefront with PHP 8.3, MariaDB, OpenSearch, Redis, RabbitMQ, Nginx, and Varnish in front.
Skip the stack assembly? Deploy a Magento-ready VPS with all dependencies pre-tuned on our CloudCore Business plan. Start serving products in under an hour.
Table of Contents
What is Magento 2?
Magento 2 Open Source is Adobe's open-source ecommerce platform, the successor to Magento 1 that powered more than a quarter of the world's top 1 million ecommerce sites during its peak. Built on Laminas (formerly Zend Framework) and a highly modular service-contract architecture, it supports almost any retail use case you can imagine — from a single-brand boutique to a multi-tenant marketplace selling thousands of configurable products across dozens of country-specific storefronts.
At its core, Magento provides what is arguably the deepest catalog engine in open-source ecommerce. You can model simple, configurable, bundled, grouped, downloadable, and virtual products, attach unlimited custom attributes, build attribute sets per product category, manage inventory across multiple warehouses with Multi-Source Inventory (MSI), and run rule-based pricing with tiered quantity discounts, customer-group-specific prices, and cart price rules that chain multiple conditions. The multi-store, multi-website, multi-language architecture lets you run separate storefronts — different domains, different currencies, different catalogs, different tax rules — from a single admin panel and a single codebase. Large brands frequently run ten or more country storefronts off one Magento install.
On the B2B side, Magento supports company accounts with hierarchical buyers, purchase orders, quote negotiation, requisition lists, and shared catalogs out of the box (with the Commerce edition adding a few more features). Checkout is fully customizable with a one-page or multi-step flow, guest checkout, saved payment methods, and an extensive payment gateway library covering Stripe, PayPal, Braintree, Authorize.Net, Klarna, Afterpay, and virtually every regional processor. The admin panel includes order management, partial invoicing, credit memos, shipment tracking, return authorizations (RMAs), email templating with per-store-view translations, and a full CMS for blog-style content, landing pages, and banners.
Extensibility is the other half of the Magento story. The Magento Marketplace offers thousands of extensions, and the platform's dependency-injection architecture, event/observer system, and plugin (interceptor) pattern let developers change almost any behavior without forking core code. The REST and GraphQL APIs cover the entire admin and storefront surface, making Magento a natural fit for headless / composable commerce architectures using Next.js, Vue Storefront, or PWA Studio as the frontend.
Why Self-Host Magento on Your VPS?
Hosted ecommerce platforms like Shopify Plus, BigCommerce Enterprise, and Adobe Commerce Cloud charge either a flat fee that runs into the tens of thousands per year, a percentage of gross merchandise value (GMV) that scales brutally as you grow, or both. Self-hosting Magento 2 Open Source on a VPS you control flips the economics:
- Zero per-transaction fees -- No 0.15%-0.5% platform tax on every order. A store doing EUR 1M/year in GMV saves EUR 1,500-5,000 annually versus Shopify Plus-style pricing the moment it moves to self-hosted.
- Full database access -- Run any SQL you want for analytics, migrations, or data imports. Export the entire store to a backup at any time. No vendor can lock you out of your own catalog.
- Any extension, any customization -- Install paid marketplace modules, open-source community modules, or build your own. Modify checkout, rewrite pricing logic, add custom product types. Nothing is off-limits.
- Full control over performance tuning -- Choose your own PHP-FPM pool sizes, MariaDB buffer pools, OpenSearch heap, Varnish cache size. Scale vertically on a bigger VPS or horizontally with a dedicated database server when you outgrow a single box.
- GDPR and data-residency compliance -- Host in any EU datacenter, keep all customer PII on infrastructure you control, run your own backup policy. No data crosses the Atlantic unless you explicitly route it that way.
- Headless and omnichannel-ready -- The GraphQL API is first-class; pair Magento with a Next.js or Hydrogen-style frontend, a native app, and a POS all hitting the same backend.
- No surprise platform changes -- Your store's UI, checkout flow, and admin don't change overnight because a SaaS vendor shipped a release. You upgrade Magento when you choose to.
Cost Comparison: Self-Hosted vs. Hosted Ecommerce Platforms
| Scenario | Shopify Plus | Adobe Commerce Cloud | BigCommerce Enterprise | Self-Hosted Magento 2 (VPS) |
|---|---|---|---|---|
| Platform fee | ~$2,300/mo minimum | $22,000+/yr | ~$1,000/mo minimum | EUR 29.99/mo (CloudCore Business) |
| % of GMV | Up to 0.25% | Revenue-share | Capped tiers | 0% |
| Database access | No | Partial | No | Full root |
| Custom code | Liquid/apps only | Limited | Stencil only | Unrestricted |
| Typical annual cost at EUR 1M GMV | ~$30k+ | ~$30-50k | ~$15k+ | EUR 360 + extensions |
| Data residency control | Limited | Limited | Limited | Full (any region) |
Prerequisites
Before you begin, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- SSH access to your server
- At least 8 GB of RAM (Magento, OpenSearch, MariaDB, Redis, and PHP-FPM together are memory-hungry; 12-16 GB is comfortable for production)
- At least 100 GB of disk space (the codebase is ~2 GB; media, logs, backups, and database grow quickly)
- A registered domain name pointing to the VPS IP (required for TLS and for absolute URLs)
- A free account at magento.com to generate Composer access keys
Recommended Plan: CloudCore Business>
Magento is the most resource-intensive stack in mainstream open source. For a comfortable production install with room for traffic spikes and a growing catalog, we recommend the CloudCore Business plan:>
- 8 vCPU cores
- 16 GB RAM
- 200 GB NVMe SSD
- Unmetered bandwidth>
This gives you headroom for PHP-FPM workers, a 4 GB OpenSearch heap, Redis, MariaDB with a 4 GB InnoDB buffer pool, and Varnish all on one box. For stores exceeding ~500 orders/day, split MariaDB and OpenSearch onto a second VPS.
Connect to your server via SSH to get started:
ssh root@your-server-ipStep 1: Update System Packages
Start by updating your package index and upgrading installed packages so subsequent installs resolve against current versions.
sudo apt update && sudo apt upgrade -yIf the kernel was updated, reboot before continuing:
sudo rebootInstall a few baseline tools you will need throughout the install:
sudo apt install -y curl wget git unzip software-properties-common ca-certificates apt-transport-https gnupg lsb-releaseStep 2: Install PHP 8.3 and Required Extensions
Magento 2.4.7 officially supports PHP 8.3. Ubuntu 24.04 ships with PHP 8.3 in its default repos — convenient — but the Ondrej Sury PPA is still worth adding for long-term access to PHP point releases and a wider set of extension packages.
sudo add-apt-repository -y ppa:ondrej/php
sudo apt updateInstall PHP 8.3 with the full list of Magento-required extensions:
sudo apt install -y \
php8.3 php8.3-fpm php8.3-cli php8.3-common \
php8.3-bcmath php8.3-curl php8.3-gd php8.3-intl \
php8.3-mbstring php8.3-mysql php8.3-soap php8.3-xml \
php8.3-xsl php8.3-zip php8.3-sockets php8.3-opcache \
php8.3-readlineThe extensions Magento 2.4.7 requires are: bcmath, ctype, curl, dom, gd, hash, iconv, intl, mbstring, openssl, pdo_mysql, simplexml, soap, xsl, zip, sockets, sodium. Most of these (ctype, dom, hash, iconv, openssl, simplexml, sodium) are compiled into php8.3-common and php8.3-cli by default, so installing the packages above covers every requirement.
Tune PHP for Magento
Magento's installer, Composer operations, and static-content deploys all allocate large amounts of memory. Edit both PHP configs — the FPM one serves the web, the CLI one runs bin/magento and Composer.
Edit /etc/php/8.3/fpm/php.ini:
sudo nano /etc/php/8.3/fpm/php.iniSet the following values:
memory_limit = 2G
max_execution_time = 1800
zlib.output_compression = On
realpath_cache_size = 10M
realpath_cache_ttl = 7200
opcache.enable = 1
opcache.memory_consumption = 512
opcache.max_accelerated_files = 60000
opcache.validate_timestamps = 0
opcache.save_comments = 1Apply the same changes to /etc/php/8.3/cli/php.ini. The memory_limit for CLI should be at least 4G — bin/magento setup:di:compile on a large module set can exceed 2 GB.
Restart PHP-FPM:
sudo systemctl restart php8.3-fpm
sudo systemctl enable php8.3-fpmVerify the version and loaded extensions:
php -v
php -m | grep -Ei 'bcmath|curl|gd|intl|mbstring|soap|xsl|zip|sockets|sodium|pdo_mysql'Step 3: Install Composer 2
Magento 2.4.7 requires Composer 2.x. Ubuntu's repo version may lag, so install directly from getcomposer.org.
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
composer --versionExpected output:
Composer version 2.7.7 2024-06-10 22:11:12
PHP version 8.3.xStep 4: Install and Configure MariaDB
Magento 2.4.7 officially supports MariaDB 10.6 LTS. Install the latest 10.6 release from MariaDB's official repo (or use Ubuntu's bundled mariadb-server if you prefer pinning to the distro release — both work).
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-10.6"
sudo apt update
sudo apt install -y mariadb-server mariadb-client
sudo systemctl enable --now mariadbRun the hardening script:
sudo mariadb-secure-installationAccept the defaults: set a root password, disallow remote root login, remove the test database, and reload privileges.
Create the Magento database and user:
sudo mariadb -u root -pCREATE DATABASE magento CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'magento'@'localhost' IDENTIFIED BY 'CHANGE_ME_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON magento.* TO 'magento'@'localhost';
FLUSH PRIVILEGES;
EXIT;Tune MariaDB for Magento
Magento generates complex multi-join queries on the EAV catalog tables. A properly sized InnoDB buffer pool is the single biggest performance lever.
Edit /etc/mysql/mariadb.conf.d/50-server.cnf:
[mysqld]
innodb_buffer_pool_size = 4G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
max_connections = 300
tmp_table_size = 128M
max_allowed_packet = 128MOn a 16 GB server, set innodb_buffer_pool_size to ~4 GB (about 25%). On dedicated DB servers, use 60-70% of RAM.
Restart MariaDB:
sudo systemctl restart mariadbIf you want more detail on MariaDB tuning, see our guide to installing and tuning MariaDB on Ubuntu.
Step 5: Install OpenSearch 2.x
Starting with Magento 2.4.6, OpenSearch is the officially supported search engine (replacing Elasticsearch, which Magento dropped after licensing changes). OpenSearch 2.x is API-compatible with Elasticsearch 7.x and is a drop-in replacement from Magento's perspective.
Install Java (OpenSearch ships a bundled JVM, but we need apt-transport-https anyway):
sudo apt install -y lsb-release ca-certificates curl gnupgAdd the OpenSearch repo:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch.pgp | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-keyringecho "deb [signed-by=/usr/share/keyrings/opensearch-keyring] https://artifacts.opensearch.org/releases/bundle/opensearch/2.x/apt stable main" | sudo tee /etc/apt/sources.list.d/opensearch-2.x.list
sudo apt update
Install OpenSearch with a one-time admin password:
sudo env OPENSEARCH_INITIAL_ADMIN_PASSWORD='YourStrongInitialPassword1!' apt install -y opensearchEdit /etc/opensearch/opensearch.yml and set:
cluster.name: magento-cluster
node.name: magento-node-1
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
plugins.security.disabled: trueWe disable the security plugin for local-only use — Magento connects over 127.0.0.1:9200 only, and the firewall blocks 9200 from the internet. If you run OpenSearch on a separate VPS, keep security enabled and supply credentials to Magento.
Set the JVM heap in /etc/opensearch/jvm.options:
-Xms2g
-Xmx2gUse ~25% of RAM for the heap, capped at 32 GB. A 2 GB heap is fine for a mid-size catalog (<100k SKUs) on a 16 GB server.
Enable and start OpenSearch:
sudo systemctl daemon-reload
sudo systemctl enable --now opensearchVerify it is responding:
curl http://localhost:9200Expected output:
{
"name" : "magento-node-1",
"cluster_name" : "magento-cluster",
"version" : { "distribution" : "opensearch", "number" : "2.x.x" },
"tagline" : "The OpenSearch Project: https://opensearch.org/"
}For a deeper dive, see our Elasticsearch / OpenSearch tuning guide.
Step 6: Install Redis for Cache and Sessions
Magento uses Redis for the default cache backend, the page cache (when not using Varnish), and session storage. Using three separate Redis databases — one per role — is the standard pattern.
sudo apt install -y redis-server
sudo systemctl enable --now redis-serverEdit /etc/redis/redis.conf:
maxmemory 2gb
maxmemory-policy allkeys-lru
save ""
appendonly noFor Magento, Redis is purely a cache — persistence (save, AOF) is unnecessary overhead. Restart:
sudo systemctl restart redis-server
redis-cli pingExpected: PONG.
See our dedicated Redis installation and tuning guide for memory sizing, replication, and monitoring.
Step 7: Install RabbitMQ for Message Queues
Magento 2.4.x uses RabbitMQ for asynchronous tasks — reindexing after large imports, async checkout processing, B2B workflows, and customer-data updates. It is optional for single-store installs but recommended for any production store.
sudo apt install -y rabbitmq-server
sudo systemctl enable --now rabbitmq-serverCreate a Magento user:
sudo rabbitmqctl add_user magento 'CHANGE_ME_RABBIT_PASSWORD'
sudo rabbitmqctl set_user_tags magento administrator
sudo rabbitmqctl set_permissions -p / magento "." "." ".*"Enable the management plugin for a web UI at :15672:
sudo rabbitmq-plugins enable rabbitmq_managementStep 8: Install Nginx
sudo apt install -y nginx
sudo systemctl enable --now nginxCheck it's running:
curl -I http://localhostWe'll write the full Magento vhost in Step 12. For general Nginx configuration, see our Nginx installation and tuning guide.
Step 9: Get Your Magento Access Keys
Composer downloads Magento from Adobe's private repository at repo.magento.com, which requires authentication keys.
production-server), and copy both the Public Key and Private Key. The Public Key is your Composer username; the Private Key is your Composer password.Keep both keys ready — you'll paste them in the next step.
Step 10: Download Magento with Composer
Create a non-root user that will own the Magento code:
sudo adduser --system --group --disabled-login --home /var/www/magento --shell /bin/bash magento
sudo usermod -a -G www-data magentoSwitch to that user and run Composer as them:
sudo -u magento -i
cd /var/www/magento
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.7 .Composer will prompt for credentials the first time:
Authentication required (repo.magento.com):
Username: <paste your PUBLIC key>
Password: <paste your PRIVATE key>
Do you want to store credentials for repo.magento.com in /var/www/magento/.composer/auth.json ? [Yn] YStoring in auth.json means future composer install runs are non-interactive.
The download pulls ~2 GB of code and several hundred packages. Expect 5-15 minutes depending on network speed.
Set Filesystem Permissions
Still as the magento user:
find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
chmod u+x bin/magentoBack to root:
exit
sudo chown -R magento:www-data /var/www/magentoStep 11: Run the Magento Installer
Run the installer as the magento user so created files have the right ownership.
sudo -u magento -i cd /var/www/magento
bin/magento setup:install \ --base-url=https://shop.example.com/ \ --db-host=localhost \ --db-name=magento \ --db-user=magento \ --db-password='CHANGE_ME_STRONG_PASSWORD' \ --admin-firstname=Admin \ --admin-lastname=User \ [email protected] \ --admin-user=admin \ --admin-password='CHANGE_ME_ADMIN_STRONGpass1!' \ --language=en_US \ --currency=EUR \ --timezone=Europe/Berlin \ --use-rewrites=1 \ --search-engine=opensearch \ --opensearch-host=localhost \ --opensearch-port=9200 \ --opensearch-index-prefix=magento2 \ --opensearch-timeout=15 \ --session-save=redis \ --session-save-redis-host=127.0.0.1 \ --session-save-redis-port=6379 \ --session-save-redis-db=2 \ --cache-backend=redis \ --cache-backend-redis-server=127.0.0.1 \ --cache-backend-redis-db=0 \ --page-cache=redis \ --page-cache-redis-server=127.0.0.1 \ --page-cache-redis-db=1 \ --amqp-host=127.0.0.1 \ --amqp-port=5672 \ --amqp-user=magento \ --amqp-password='CHANGE_ME_RABBIT_PASSWORD' \ --amqp-virtualhost='/'
The installer runs for 3-8 minutes. At the end it prints the admin URL — save it immediately, it contains a random suffix (e.g. /admin_a1b2c3/) that Magento uses as a simple obscurity defense.
Expected final output:
[SUCCESS]: Magento installation complete.
[SUCCESS]: Magento Admin URI: /admin_a1b2c3
Nothing to import.Step 12: Configure Nginx for Magento
Magento ships a battle-tested sample Nginx config at /var/www/magento/nginx.conf.sample. Wrap it in a vhost that handles TLS and the PHP socket.
Create /etc/nginx/sites-available/magento:
upstream fastcgi_backend { server unix:/run/php/php8.3-fpm.sock; }server { listen 80; server_name shop.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name shop.example.com;
set $MAGE_ROOT /var/www/magento; set $MAGE_MODE production;
ssl_certificate /etc/letsencrypt/live/shop.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/shop.example.com/privkey.pem;
include /var/www/magento/nginx.conf.sample;
client_max_body_size 64M; fastcgi_read_timeout 600s; }
The magic line is include /var/www/magento/nginx.conf.sample; — Adobe maintains this file as the canonical Magento Nginx config. It handles static-file rewriting, the pub/static versioning scheme, admin-specific rules, and PHP-FPM proxying.
Enable the site and reload:
sudo ln -s /etc/nginx/sites-available/magento /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginxWe will obtain the TLS certificate in Step 16.
Step 13: Enable Production Mode and Compile
Magento has three modes: default, developer, and production. Production mode pre-compiles dependency injection, pre-generates static view files, and caches everything aggressively — it is the only acceptable mode for a live store.
As the magento user:
cd /var/www/magento
bin/magento deploy:mode:set productionThis runs several sub-commands automatically: setup:di:compile, setup:static-content:deploy, cache flush. On a 4-core VPS it takes 5-15 minutes.
If you skip deploy:mode:set production and want to run the steps manually:
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f en_US
bin/magento cache:flush
bin/magento indexer:reindexVerify the mode:
bin/magento deploy:mode:showExpected:
Current application mode: production.Step 14: Configure the Three Magento Cron Jobs
Magento depends on a system cron to drive indexing, email sending, cache cleanup, sitemap generation, product alerts, and scheduled imports/exports. The correct configuration is three separate cron entries, as documented by Adobe.
Edit the magento user's crontab:
sudo -u magento crontab -ePaste the following three lines:
* /usr/bin/php /var/www/magento/bin/magento cron:run 2>&1 | grep -v "Ran jobs by schedule" >> /var/www/magento/var/log/magento.cron.log
* /usr/bin/php /var/www/magento/update/cron.php >> /var/www/magento/var/log/update.cron.log
* /usr/bin/php /var/www/magento/bin/magento setup:cron:run >> /var/www/magento/var/log/setup.cron.logbin/magento cron:run-- runs the defaultcron_group(indexer, email, sitemap, etc.).update/cron.php-- handles the Web Setup Wizard's deferred tasks.bin/magento setup:cron:run-- processes component and upgrade tasks.
sudo -u magento crontab -lStep 15: Install Varnish for Full-Page Cache
Magento includes an excellent built-in full-page cache, but placing Varnish in front of it cuts Time-To-First-Byte dramatically (often from 800 ms to under 50 ms for cached pages). Adobe officially recommends Varnish and ships a VCL template in the admin.
sudo apt install -y varnishGenerate a Magento-specific VCL from the admin panel:
https://shop.example.com/admin_xxx/localhost)Save the downloaded file to /etc/varnish/default.vcl, overwriting the default.
Make Varnish listen on port 80 and point at Nginx on port 8080. Edit /etc/systemd/system/multi-user.target.wants/varnish.service:
ExecStart=/usr/sbin/varnishd -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,1gMove Nginx off port 80. Edit the server block in /etc/nginx/sites-available/magento:
server {
listen 8080;
server_name shop.example.com;
# Varnish will strip the 8080 and forward to us
...
}Keep the port 443 TLS server block exactly as it was — TLS terminates at Nginx, which then proxies to Varnish on port 80 via a separate upstream. Reload all three services:
sudo systemctl daemon-reload
sudo systemctl restart varnish
sudo systemctl restart nginxA deeper treatment of TLS-Varnish-Nginx topology is out of scope for an install guide — see Adobe's official Varnish deployment docs for the production-grade SSL/Varnish patterns.
Step 16: Secure the Admin URL and Enable TLS
Obtain a Let's Encrypt Certificate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d shop.example.comCertbot injects the TLS paths into your Nginx config and sets up auto-renewal via a systemd timer.
Customize the Admin Path
Magento generated a random admin URL during install (e.g. /admin_a1b2c3). Change it to something you control but that isn't /admin (never /admin — it is the single most probed path on the internet).
cd /var/www/magento
bin/magento setup:config:set --backend-frontname="admin_mybrand_9f3k"
bin/magento cache:flushAccess the admin at https://shop.example.com/admin_mybrand_9f3k/.
Enable Two-Factor Authentication
Magento 2.4.x ships with 2FA enabled by default — on your first login, it prompts you to enroll a Google Authenticator, Authy, or Duo device. Do not disable it.
Firewall
Only ports 22 (SSH), 80, and 443 should be public:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableOpenSearch (9200), Redis (6379), RabbitMQ (5672, 15672), and MariaDB (3306) remain bound to 127.0.0.1 only.
Post-Install: Add Your First Product
Log in to the admin, then:
Catalog, Search)Visit https://shop.example.com/ — you should see the default Luma theme with your product live on the homepage (or at least in the catalog). If you don't see it immediately, run:
sudo -u magento /var/www/magento/bin/magento indexer:reindex
sudo -u magento /var/www/magento/bin/magento cache:flushStorefront search should also return the product — that confirms OpenSearch is wired correctly.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
composer create-project fails with Allowed memory size exhausted | PHP CLI memory limit too low for Composer | Edit /etc/php/8.3/cli/php.ini, set memory_limit = 4G, rerun Composer. Or run: COMPOSER_MEMORY_LIMIT=-1 composer create-project ... |
setup:install fails with Could not connect to Elasticsearch / OpenSearch | OpenSearch not running, wrong port, or security plugin enabled | curl http://localhost:9200 should return JSON. Check systemctl status opensearch. Confirm plugins.security.disabled: true in opensearch.yml. Restart OpenSearch and retry. |
| Admin login returns 404 | Admin URL suffix not correct, or cache not flushed after config:set | Run bin/magento info:adminuri to print the current admin path. Flush cache: bin/magento cache:flush. |
| Storefront returns 503 Service Unavailable or blank page | Maintenance mode left enabled, or static content not deployed in production mode | bin/magento maintenance:status. Disable: bin/magento maintenance:disable. Rerun: bin/magento setup:static-content:deploy -f en_US. |
Indexer stuck in processing or invalid state | A prior indexer crash left lock rows in indexer_state | bin/magento indexer:reset, then bin/magento indexer:reindex. If that fails, truncate indexer_state manually in MariaDB. |
setup:di:compile crashes with OOM kill | PHP CLI memory limit too low, or 2 GB RAM is not enough | Set CLI memory_limit = 4G. If on a 4 GB VPS, add 4 GB of swap: sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile |
| Varnish returns HTTP 503 "Backend fetch failed" | VCL points at a backend port that Nginx isn't listening on | Verify Nginx listens on the port set in default.vcl (.port = "8080" by default). Check sudo varnishlog output for the real error. |
cron:run never seems to do anything | Cron entries missing, wrong user, or log redirection hiding errors | sudo -u magento crontab -l -- confirm all three lines are present. Tail /var/www/magento/var/log/magento.cron.log. Check permissions on var/log. |
| Slow checkout / admin save operations | RabbitMQ not running, consumers not processing | sudo systemctl status rabbitmq-server. Run consumers: bin/magento queue:consumers:start async.operations.all &. In production, configure consumers as systemd units or use cron. |
| Product images 404 after upload | pub/media permissions or missing pub/media/catalog/product directory | sudo chown -R magento:www-data /var/www/magento/pub/media and re-run the Step 10 permission fixup commands. |
Viewing Logs
The three most valuable log streams when debugging:
sudo tail -f /var/www/magento/var/log/exception.log
sudo tail -f /var/www/magento/var/log/system.log
sudo journalctl -u php8.3-fpm -u nginx -u opensearch -u mariadb -fFAQ
What's the difference between Magento 2 Open Source and Adobe Commerce?
Magento 2 Open Source (formerly Magento Community Edition) is the free, open-source edition we install in this guide. It includes the full product catalog, multi-store, multi-currency, B2C checkout, CMS, and API surface.
Adobe Commerce (formerly Magento Enterprise / Commerce) is the paid edition. It adds page builder, visual merchandiser, business-intelligence dashboards, advanced B2B features (company accounts, shared catalogs, quotes), customer segmentation, WYSIWYG rules, and the Commerce Cloud hosting tier. Licensing is revenue-based and starts at roughly $22k/year.
For the majority of mid-market stores, Open Source + a handful of paid extensions matches Adobe Commerce's functionality at a fraction of the cost.
Does Magento 2 still work without Elasticsearch?
No. Since Magento 2.4.0, a search engine is a hard dependency — you cannot run a storefront without one. Magento 2.4.6+ officially supports OpenSearch 2.x (which we install here) and Elasticsearch 7.x / 8.x. MySQL-based catalog search was removed in 2.4.0.
How many orders per day can this single-VPS install handle?
On the recommended CloudCore Business plan (8 vCPU / 16 GB RAM), a well-tuned single-box Magento install reliably handles 200-500 orders per day with a catalog of up to ~50,000 SKUs and typical B2C traffic patterns (Varnish hit rate >90%). Beyond that, split the database and OpenSearch onto a second VPS, then add a second Magento web node behind a load balancer with shared Redis, RabbitMQ, and a shared pub/media mount.
Can I use MySQL 8 instead of MariaDB?
Yes — Magento 2.4.7 officially supports MySQL 8.0. Install mysql-server-8.0 from MySQL's apt repo instead of MariaDB in Step 4. All other steps are identical. MariaDB is the more common choice in the Magento community because of its query-optimizer behavior on EAV schemas and its looser sql_mode defaults, but MySQL works equally well with modern versions.
How do I upgrade Magento later?
Upgrades run via Composer:
sudo -u magento -i
cd /var/www/magento
composer require magento/product-community-edition=2.4.8 --no-update
composer update
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f en_US
bin/magento cache:flushAlways back up the database and pub/media before a major upgrade, test in a staging environment, and review the Magento release notes for breaking changes and module compatibility.
Should I use Nginx or Apache with Magento?
Nginx is the community standard and the one Adobe maintains the sample config for. It handles high-concurrency static file serving and reverse-proxying to Varnish more efficiently than Apache. Use Apache only if you have a specific reason (e.g. .htaccess-based shared hosting compatibility) — Magento works on both.
Next Steps
Your Magento store is live. Here's where to invest time next:
- Pick a theme or go headless -- The default Luma theme is functional but dated. Evaluate Hyvä Themes (Tailwind-based, fast, no legacy JS) for a traditional frontend, or go headless with Vue Storefront or Next.js Commerce + GraphQL.
- Configure payment gateways -- Install Stripe, PayPal, or your regional gateway from the Magento Marketplace. Configure in Stores -> Configuration -> Sales -> Payment Methods. Always test in sandbox mode before going live.
- Set up automated backups -- Database dumps,
pub/media, andapp/etc/env.phpare the three things you must back up. Pairmariadb-dumpwith an S3-compatible off-site target. See our backup strategy guide for VPS.
- Enable GA4 / GTM and structured data -- Install an SEO extension, enable product schema (Magento emits basic
Productschema out of the box but check your output), and wire GA4 via Google Tag Manager.
- Harden security -- Install Fail2Ban with the Magento admin filter, put Cloudflare in front of the store (DDoS, WAF, bot management), and subscribe to the Adobe Commerce Security Bulletins so you patch critical CVEs within 24 hours.
- Monitor performance -- Install the New Relic APM for Magento or self-host a Grafana + Prometheus + PHP-FPM exporter stack. Watch P95 response time on catalog and checkout.
- Read the official docs -- Adobe's developer documentation at developer.adobe.com/commerce is the canonical reference for module development, APIs, and architecture.
Ready for a Production-Grade Magento VPS?>
CloudCore Business is purpose-built for self-hosted ecommerce stacks. Every plan includes:>
- 8 vCPU, 16 GB RAM, 200 GB NVMe SSD
- Unmetered bandwidth with a 1 Gbps port
- Root SSH, IPv4 + IPv6, free reverse DNS
- Datacenter choice: EU (Germany), US, or Asia
- 99.9% uptime SLA>
Deploy CloudCore Business now and have your Magento 2 storefront serving products by tomorrow morning.