Installing Magento 2.4.9 on Ubuntu 24.04: the commands from the video
Every command from the lesson, chapter by chapter, ready to copy, and every config file ready to download. nginx 1.30, PHP 8.5, MariaDB 12.3, OpenSearch 3, Valkey 9, Varnish 8 and Composer 2.10, then Magento itself in production mode with HTTPS.
Part 1: preparing the server
Ubuntu 24.04, tuned-adm, nginx 1.30, PHP 8.5, MariaDB 12.3, OpenSearch 3, Valkey 9, Varnish 8 and Composer.
Part 2: installing Magento 2.4.9
Download and install, production mode, cron and indexers, PHP-FPM, nginx and Varnish with HTTPS, the admin panel and go-live.
Downloads
Change www.example.com, the passwords (change-this-password, Change-This-1!), the admin path admin_x7k2 and the user youradmin to your own before you use them.
Before you start
A fresh Ubuntu 24.04 server with at least 4 CPU cores, 8 GB of RAM (16 GB is better) and an SSD, root access over SSH, and a domain pointing at the server. You also need your Magento Marketplace access keys for Composer.
1. Preparing Ubuntu
adduser magento
usermod -aG sudo magento
apt update && apt upgrade -y
timedatectl set-timezone Europe/Berlin && timedatectl | head -4
fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab && swapon --show
ufw default deny incoming
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable
ufw status
apt install -y fail2ban unattended-upgrades
2. tuned-adm
apt install -y tuned
systemctl enable --now tuned
tuned-adm recommend
tuned-adm profile virtual-guest
tuned-adm active
tuned-adm verify
3. nginx 1.30
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx.gpg] http://nginx.org/packages/ubuntu noble nginx" > /etc/apt/sources.list.d/nginx.list
apt update && apt install -y nginx
systemctl enable --now nginx && nginx -v
4. PHP 8.5
add-apt-repository -y ppa:ondrej/php
apt install -y php8.5-fpm php8.5-cli php8.5-bcmath php8.5-curl php8.5-gd php8.5-intl \ php8.5-mbstring php8.5-mysql php8.5-soap php8.5-xml php8.5-xsl php8.5-zip php8.5-sockets
php -v
cat > /etc/php/8.5/fpm/conf.d/99-magento.ini <<'EOF' memory_limit = 2G max_execution_time = 1800 realpath_cache_size = 10M realpath_cache_ttl = 7200 opcache.memory_consumption = 512 opcache.max_accelerated_files = 130000 opcache.validate_timestamps = 0 EOF
Writes /etc/php/8.5/fpm/conf.d/99-magento.ini.
systemctl restart php8.5-fpm && systemctl is-active php8.5-fpm
5. MariaDB 12.3
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-12.3"
apt install -y mariadb-server
mariadb-secure-installation
mariadb -e "CREATE DATABASE magento; CREATE USER 'magento'@'localhost' IDENTIFIED BY 'change-this-password'; GRANT ALL ON magento.* TO 'magento'@'localhost';"
cat > /etc/mysql/mariadb.conf.d/90-magento.cnf <<'EOF' [mysqld] innodb_buffer_pool_size = 4G tmpdir = /dev/shm log_bin_trust_function_creators = 1 EOF
Writes /etc/mysql/mariadb.conf.d/90-magento.cnf.
systemctl restart mariadb && mariadb -e 'SELECT VERSION(); SHOW DATABASES;'
6. OpenSearch 3
curl -fsSL https://artifacts.opensearch.org/publickeys/opensearch-release.pgp | gpg --dearmor -o /usr/share/keyrings/opensearch.gpg
echo "deb [signed-by=/usr/share/keyrings/opensearch.gpg] https://artifacts.opensearch.org/releases/bundle/opensearch/3.x/apt stable main" > /etc/apt/sources.list.d/opensearch-3.x.list
apt update && OPENSEARCH_INITIAL_ADMIN_PASSWORD='Change-This-1!' apt install -y opensearch
cat >> /etc/opensearch/opensearch.yml <<'EOF' network.host: 127.0.0.1 discovery.type: single-node plugins.security.disabled: true EOF
Adds to /etc/opensearch/opensearch.yml.
sed -i 's/^-Xms.*/-Xms2g/; s/^-Xmx.*/-Xmx2g/' /etc/opensearch/jvm.options
systemctl enable --now opensearch
curl -s http://127.0.0.1:9200
7. Valkey 9
apt install -y build-essential pkg-config libssl-dev libsystemd-dev
cd /usr/local/src && curl -fsSL https://github.com/valkey-io/valkey/archive/refs/tags/9.0.6.tar.gz | tar xz
cd valkey-9.0.6 && make -j$(nproc) BUILD_TLS=yes USE_SYSTEMD=yes && make install
cd && valkey-server --version
useradd --system --no-create-home --shell /usr/sbin/nologin valkey mkdir -p /etc/valkey /var/lib/valkey && chown valkey:valkey /var/lib/valkey
cat > /etc/valkey/valkey.conf <<'EOF' bind 127.0.0.1 port 6379 dir /var/lib/valkey supervised systemd maxmemory 1gb maxmemory-policy allkeys-lru EOF
Writes /etc/valkey/valkey.conf.
cat > /etc/systemd/system/valkey.service <<'EOF' [Unit] Description=Valkey After=network.target [Service] Type=notify User=valkey ExecStart=/usr/local/bin/valkey-server /etc/valkey/valkey.conf Restart=always [Install] WantedBy=multi-user.target EOF
Writes /etc/systemd/system/valkey.service.
systemctl daemon-reload && systemctl enable --now valkey && valkey-cli ping
8. Varnish 8 and Composer
curl -s https://packagecloud.io/install/repositories/varnishcache/varnish80/script.deb.sh | bash
apt install -y varnish
varnishd -V
curl -sS https://getcomposer.org/installer -o composer-setup.php
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
sudo -u magento composer --version
9. Downloading Magento 2.4.9
mkdir -p /var/www/magento && chown magento:www-data /var/www/magento
su - magento
ls -l ~/.config/composer/
cd /var/www
composer create-project \ --repository-url=https://repo.magento.com/ \ magento/project-community-edition=2.4.9 magento
ls magento
exit
10. Installing Magento
cd /var/www/magento && chown -R magento:www-data .
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +su - magento
cd /var/www/magento
bin/magento setup:install \ --base-url=https://www.example.com/ \ --db-host=localhost --db-name=magento --db-user=magento --db-password='change-this-password' \ --admin-firstname=Admin --admin-lastname=Store --admin-email=you@example.com \ --admin-user=youradmin --admin-password='Long-unique-passw0rd' \ --backend-frontname=admin_x7k2 \ --language=en_US --currency=EUR --timezone=Europe/Berlin --use-rewrites=1 \ --search-engine=opensearch --opensearch-host=127.0.0.1 --opensearch-port=9200 \ --session-save=valkey --session-save-valkey-host=127.0.0.1 --session-save-valkey-db=2 \ --cache-backend=valkey --cache-backend-valkey-server=127.0.0.1 --cache-backend-valkey-db=0 \ --page-cache=valkey --page-cache-valkey-server=127.0.0.1 --page-cache-valkey-db=1
11. Production mode, cron and indexers
bin/magento deploy:mode:set production
bin/magento cron:install && crontab -l
bin/magento indexer:set-mode schedule
bin/magento indexer:reindex
chmod -R g-w app/etc
sed -i "s/'disable_locking' => '0'/'disable_locking' => '1'/" app/etc/env.php
grep disable_locking app/etc/env.php
bin/magento config:set twofactorauth/general/force_providers google
bin/magento security:tfa:google:set-secret youradmin "$TFA_SECRET"
bin/magento cache:flush
exit
12. Web server: PHP-FPM, nginx, Varnish
cat > /etc/php/8.5/fpm/pool.d/magento.conf <<'EOF' [magento] user = magento group = www-data listen = /run/php/magento.sock listen.owner = nginx listen.group = www-data pm = dynamic pm.max_children = 20 pm.start_servers = 4 pm.min_spare_servers = 2 pm.max_spare_servers = 6 EOF
Writes /etc/php/8.5/fpm/pool.d/magento.conf.
systemctl restart php8.5-fpm
mkdir -p /etc/nginx/ssl && openssl req -x509 -nodes -newkey rsa:2048 -days 365 -subj "/CN=www.example.com" \ -keyout /etc/nginx/ssl/www.key -out /etc/nginx/ssl/www.crt
rm /etc/nginx/conf.d/default.conf
cat > /etc/nginx/conf.d/magento.conf <<'EOF'
upstream fastcgi_backend { server unix:/run/php/magento.sock; }
server {
listen 127.0.0.1:8080;
server_name www.example.com;
set $MAGE_ROOT /var/www/magento;
include /var/www/magento/nginx.conf.sample;
}
server {
listen 443 ssl;
http2 on;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/www.crt;
ssl_certificate_key /etc/nginx/ssl/www.key;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k;
proxy_read_timeout 600s;
}
}
EOFWrites /etc/nginx/conf.d/magento.conf.
nginx -t && systemctl reload nginx
mkdir -p /etc/systemd/system/varnish.service.d cat > /etc/systemd/system/varnish.service.d/override.conf <<'EOF' [Service] ExecStart= ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -P %t/%N/varnishd.pid -p feature=+http2 -s malloc,1g EOF
Writes /etc/systemd/system/varnish.service.d/override.conf.
systemctl daemon-reload && systemctl restart varnish
echo "127.0.0.1 www.example.com" >> /etc/hosts
ss -ltn | grep -E ':(80|443|8080) '
curl -skI https://www.example.com/ | head -1
13. Loading the Varnish config
cd /var/www/magento && sudo -u magento bin/magento varnish:vcl:generate --export-version=7 \ --backend-host=127.0.0.1 --backend-port=8080 > /etc/varnish/default.vcl
grep -A3 'backend default' /etc/varnish/default.vcl
systemctl reload varnish
sudo -u magento bin/magento setup:config:set --http-cache-hosts=127.0.0.1:80 -n > /dev/null
curl -skI https://www.example.com/ | grep -iE '^HTTP|x-magento-cache-debug'
curl -skI https://www.example.com/ | grep -iE '^HTTP|x-magento-cache-debug'
Next lessons
- Lesson 2: switching Magento to Varnish, with HTTPS, with a side-by-side speed test.
- Lesson 3: creating categories and subcategories, with a REST API script.
▶ Watch every MageBooster lesson on YouTube: all lessons in order · subscribe to the channel

