Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To launch a site on a new VPS, create an Ubuntu server with a non-root sudo account, install Apache, MySQL and PHP, configure a domain-specific Apache virtual host, upload the files over SFTP, point both your apex and www DNS records to the server’s public IP, and then enable HTTPS with Certbot. The sequence below uses Ubuntu 24.04 practices and separates application access from database administration.

What you are building

A VPS is a virtual server with its own operating-system environment and public IP address. You administer it over SSH and decide which services run on it. A LAMP stack combines Linux, Apache, MySQL and PHP: Apache accepts HTTP requests, PHP generates dynamic responses, and MySQL stores application data. Together they can host PHP sites and web applications.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The finished setup has four distinct paths:

  • Visitors reach your public IPv4 address through Apache.
  • Your domain’s A records resolve to that address.
  • Apache sends requests for your domain to its own document root.
  • Your PHP application connects to MySQL through a dedicated, least-privilege account.

Keep the database private. Public access should normally be limited to SSH, HTTP and HTTPS. The current Ubuntu 24.04 LAMP Marketplace image documented by DigitalOcean in 2026 lists Apache 2.4.58, MySQL 8.0.43, PHP 8.4.11, Fail2ban 1.0.2 and Certbot 2.9.0, but package versions can change as updates are published.

1. Create the VPS and record its IP address

Choose the operating system and deployment style

Select Ubuntu 24.04 LTS unless your application requires another supported release. You can install the stack manually for maximum control, or select a provider’s one-click LAMP image for a faster, preconfigured starting point. Whichever route you choose, record the server’s public IPv4 address; it is the value you will later place in DNS.

A one-click image may already include Apache, PHP, MySQL, Certbot and Fail2ban. Do not blindly reinstall those packages. First inspect what is present:

lsb_release -a
apache2 -v
mysql --version
php -v
sudo ufw status verbose

If you chose a plain Ubuntu server, continue with the manual installation below.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a non-root administrator

Use the provider’s console or initial SSH account to create a named administrator. Replace deploy with your preferred username.

sudo adduser deploy
sudo usermod -aG sudo deploy

Open a second terminal and verify that the new account can obtain administrative privileges before changing SSH settings:

ssh deploy@SERVER_IP
sudo -v

SSH keys are preferable to password-only login. From your workstation, copy an existing public key:

ssh-copy-id deploy@SERVER_IP

After confirming key-based login in a separate session, you can disable routine root login and password authentication in /etc/ssh/sshd_config. Make one change at a time, validate the configuration, and keep an existing session open while restarting SSH:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo sshd -t
sudo systemctl restart ssh

Activate the firewall before installing services

Ubuntu’s uncomplicated firewall (UFW) should allow only the ports you need. Start by permitting SSH, then enable the firewall:

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status numbered

Do not enable the firewall until SSH is allowed, or you can lock yourself out. Later, add web traffic:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

The documented DigitalOcean LAMP image exposes SSH 22 (rate limited), HTTP 80 and HTTPS 443 by default. A manually configured server should reach the same minimum, without opening MySQL’s port 3306 to the public internet.

2. Install Apache and verify the server

Update Ubuntu’s package index and install Apache:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo apt update
sudo apt upgrade -y
sudo apt install apache2 -y
sudo systemctl enable --now apache2

Allow HTTP through UFW if you have not already done so:

sudo ufw allow 80/tcp

Visit http://SERVER_IP in a browser. The default Apache page confirms that the web server is reachable. You can also test from the shell:

curl -I http://SERVER_IP

Expect an HTTP response such as 200 OK. If the browser times out, check the provider’s external firewall, the VPS IP, UFW status and Apache’s service state:

sudo systemctl status apache2
sudo ss -tulpn | grep ':80'

3. Install and secure MySQL

Install the database server

sudo apt install mysql-server -y
sudo systemctl enable --now mysql
sudo systemctl status mysql

Run the supplied hardening routine:

sudo mysql_secure_installation

The prompts vary by MySQL release, but the secure choices normally remove anonymous accounts, prevent remote root login, remove the test database and reload privilege tables. Read each prompt rather than accepting every default on autopilot.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create an application database and user

Applications should never connect as the MySQL root account. Log in locally as the administrative MySQL account:

sudo mysql

Create a database with a UTF-8-compatible character set, a dedicated user and only the privileges that application needs. Use a long, unique password and substitute your own names:

CREATE DATABASE site_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'site_user'@'localhost' IDENTIFIED BY 'REPLACE_WITH_A_LONG_RANDOM_PASSWORD';
GRANT ALL PRIVILEGES ON site_db.* TO 'site_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Granting all privileges on one application database is narrower than granting global privileges. If your application needs only selected operations, grant only those operations instead. Store the credentials outside publicly served files where your framework supports it.

Confirm that the account works without exposing MySQL externally:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
mysql -u site_user -p site_db

If you decide to use a managed MySQL service instead of a local database, follow that service’s network and TLS requirements and do not install a second public database endpoint unnecessarily.

4. Install PHP and test it through Apache

Install PHP, Apache’s PHP module and the MySQL connector:

sudo apt install php libapache2-mod-php php-mysql -y
php -v
sudo systemctl restart apache2

The installed version should match the requirements of your application. The 2026 Ubuntu 24.04 image documentation lists PHP 8.4.11, but a manually installed server can receive a different point release through Ubuntu updates.

Run a temporary PHP test

Create a small test file in the current default web root:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
echo '<?php phpinfo(); ?>' | sudo tee /var/www/html/info.php

Open http://SERVER_IP/info.php. A PHP information page proves that Apache is executing PHP rather than downloading the source. Remove it immediately afterward because it reveals server paths, modules and configuration details:

sudo rm /var/www/html/info.php

A safer production test is a file that prints only a short, known value. Remove that file as well when the check is complete.

5. Create a document root and Apache virtual host

Use a site-specific directory

The one-click image uses /var/www/html as its default web root. That path is suitable for a single default site, but a custom virtual host should have its own document root. The following example uses example.com:

sudo mkdir -p /var/www/example.com/public_html
sudo chown -R deploy:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 750 {} ;
sudo find /var/www/example.com -type f -exec chmod 640 {} ;

These permissions let the SFTP administrator edit files while Apache, through the www-data group, can read them. If an application must write to a specific directory, grant write access only to that directory instead of making the entire document root writable by the web server.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a temporary index page so you can distinguish your virtual host from Apache’s default page:

cat <<'EOF' | sudo tee /var/www/example.com/public_html/index.php
<?php
echo 'example.com is live';
EOF

Define the virtual host

Create /etc/apache2/sites-available/example.com.conf:

sudo nano /etc/apache2/sites-available/example.com.conf

Insert this configuration, replacing the domain and administrator address:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin admin@example.com
    DocumentRoot /var/www/example.com/public_html

    <Directory /var/www/example.com/public_html>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

ServerName must be the real hostname that DNS will resolve. ServerAlias handles the www name. Keep AllowOverride All only if the application needs .htaccess; otherwise use AllowOverride None and place rules in the virtual-host configuration.

Enable the site and reload Apache

sudo a2ensite example.com.conf
sudo a2enmod rewrite
sudo apache2ctl configtest
sudo systemctl reload apache2

The configuration test must report Syntax OK. If this is replacing Apache’s sample page, disable the default site:

sudo a2dissite 000-default.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

Do not disable a site that still serves another hostname. At this stage, the domain may not work until DNS is configured, but you can test locally with a Host header:

curl -H 'Host: example.com' http://SERVER_IP

6. Upload your website with SFTP

SFTP uses SSH encryption and the same server account you created earlier. It is preferable to plain FTP because credentials and file contents are protected in transit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Command-line SFTP

From your computer, connect with:

sftp deploy@SERVER_IP

Inside the SFTP prompt, upload a local site directory to the virtual host’s document root:

cd /var/www/example.com/public_html
put -r ./local-site/*
ls
bye

If your local shell expands the wildcard unexpectedly, use an SFTP client’s directory-upload function or upload individual files. Confirm that the remote account owns the files and that Apache can read them:

ssh deploy@SERVER_IP 'find /var/www/example.com/public_html -maxdepth 2 -type f -ls'

The default one-click path is /var/www/html. Upload there only when you intentionally use the default Apache site; files uploaded there will not automatically appear under a custom virtual host with another DocumentRoot.

Keep SFTP access narrow

  • Use a named, non-root account and SSH keys.
  • Do not give the SFTP account unrestricted write access to operating-system directories.
  • Keep executable application code owned by the deployment account and readable by Apache.
  • Set writable permissions only on directories the application genuinely needs, such as an uploads or cache directory.
  • After deployment, inspect for accidentally uploaded secrets, backups, database dumps and configuration files.

7. Point DNS to the VPS

At your DNS provider, create two A records:

Name Type Value Purpose
@ (or the provider’s apex notation) A VPS public IPv4 address Loads example.com
www A VPS public IPv4 address Loads www.example.com

Some providers display the apex name as the full domain rather than @. Use the provider’s documented notation. Remove conflicting A records for the same names. Add an AAAA record only when the VPS has a working IPv6 address and Apache, the firewall and the application are configured for IPv6; an incorrect AAAA record can make some visitors reach the wrong server.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

DNS changes are cached according to the records’ TTL. Check resolution from your workstation:

dig +short example.com A
dig +short www.example.com A

Both commands should return the VPS address. Test the domain, not just the IP, because Apache chooses a virtual host based on the hostname:

curl -I http://example.com
curl -I http://www.example.com

8. Enable HTTPS with Certbot

Certbot requires a registered domain and two DNS records that resolve to the server. Ensure Apache’s ServerName and ServerAlias match the names you will certify. Keep ports 80 and 443 reachable while validation runs.

Install and run Certbot

sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d example.com -d www.example.com

Certbot can obtain the certificate, update the Apache virtual host and offer an HTTP-to-HTTPS redirect. Choose the redirect when all required site resources work over HTTPS. If validation fails, first check that both A records resolve to this VPS, port 80 is allowed through UFW and any provider-level firewall, and the correct virtual host answers an HTTP request.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verify renewal configuration:

sudo systemctl list-timers | grep certbot
sudo certbot renew --dry-run

Do not remove port 80 after issuance if you rely on HTTP-01 renewal. The redirect can remain in place; the validation request still needs to reach the server.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

9. Validate the complete launch

Run these checks in order so a failure points to a specific layer:

  1. Server reachability: curl -I http://SERVER_IP returns an Apache response.
  2. PHP execution: a temporary PHP test executes through Apache, then the test file is deleted.
  3. Database access: a small application-level test connects with the dedicated MySQL user and database, not root.
  4. Virtual host selection: the domain displays your site rather than the default Apache page.
  5. DNS: both the apex and www names resolve to the VPS IPv4 address.
  6. SFTP: the deployment account can create and update files in the document root without broad system write access.
  7. TLS: HTTPS opens without certificate warnings and HTTP redirects as intended.

For a database test, create a temporary PHP script outside the publicly accessible path when possible. If you must place it in the document root, have it return only success or failure, test it once, and delete it immediately so credentials and schema details are never exposed.

Common failures and fixes

Symptom Likely cause Fix
SSH times out after enabling UFW SSH was not allowed before the firewall was enabled, or a provider firewall blocks port 22 Use the provider console, allow OpenSSH in UFW, and verify the external firewall.
Browser shows a timeout on port 80 Apache is stopped, port 80 is blocked, or the wrong IP was used Check systemctl status apache2, ufw status, listening sockets and the VPS address.
Apache default page appears for the domain The default site is enabled, DNS is stale, or the request does not match ServerName Run apache2ctl -S, confirm the virtual-host file, disable the conflicting default when appropriate, and test with a Host header.
PHP source downloads or displays as text The PHP module is missing or Apache was not reloaded Install libapache2-mod-php, check php -v, restart Apache and inspect its error log.
PHP reports a database connection error Wrong database name, password, host, socket or privileges Log in with the application account from the VPS, verify grants and use localhost when the database is local.
SFTP uploads fail with permission denied The remote directory is owned by another account or lacks group read/write permissions Check ownership and modes with ls -ld; grant access to the deployment account without making the entire tree writable by Apache.
Certbot cannot validate the domain A or AAAA records point elsewhere, DNS has not propagated, port 80 is blocked, or ServerName is wrong Check both names with dig, remove incorrect records, allow port 80 and test the HTTP virtual host before rerunning Certbot.
HTTPS works but assets or forms fail Hard-coded HTTP URLs, mixed content, incorrect rewrite rules or an application URL setting Update the application’s canonical URL, inspect browser developer tools and confirm rewrite rules in the HTTPS virtual host.

Security and maintenance after launch

Launching the site is the beginning of server maintenance, not the end. Apply Ubuntu and application updates regularly, review Apache and authentication logs, and remove services you do not use. Fail2ban can help rate-limit repeated authentication attacks; the documented one-click image includes Fail2ban 1.0.2, while a manual installation requires you to install and configure it separately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Keep SSH key access current and remove keys belonging to former administrators.
  • Use UFW rules that expose only SSH, HTTP and HTTPS unless a documented architecture needs another port.
  • Keep MySQL bound to local access unless remote database access is explicitly required and protected by network controls and encryption.
  • Back up both the database and uploaded files. Store at least one backup away from the VPS and periodically restore it to verify that it is usable.
  • Rotate application credentials if an administrator leaves or a secret may have been exposed.
  • Monitor disk usage, especially logs, uploads and database growth.
  • Test certificate renewal before the existing certificate approaches expiration.

Manual installation or a one-click LAMP image?

Both approaches can produce the same Apache, MySQL and PHP architecture. The practical differences are in who makes the initial decisions and who owns the resulting maintenance work.

Consideration Manual Ubuntu installation One-click LAMP image
Setup time Longer; you install and configure each service Shorter; core services are preinstalled
Package-version control Explicit choices and staged upgrades are easier Versions and defaults are chosen by the image publisher
Firewall and hardening You must define UFW, SSH and database settings The documented image starts with SSH 22, HTTP 80 and HTTPS 443 defaults and includes Fail2ban
Database placement Local MySQL by default; you choose another design Local MySQL is preinstalled and the image can optionally attach Managed MySQL
Rollback Requires your own snapshots, backups and package plan A provider image can simplify initial provisioning, but application rollback still depends on your backups
Ongoing updates You own every package and configuration update You still own OS, application and data maintenance after deployment

Choose manual installation when you need a tightly controlled baseline, custom package versions or a repeatable configuration-management process. Choose an image when speed matters and its defaults match your security and deployment requirements. In either case, inspect the resulting services, firewall and credentials rather than assuming the image is production-ready for your application.

Operational hand-off

Document the VPS IP address, SSH administrators, DNS records, virtual-host paths, database name, backup location, certificate renewal method and the commands used to deploy. Keep secrets in a password manager or a protected secrets system, never in this document or inside the public web root. A second administrator should be able to identify the correct virtual host, restore a backup and renew access without using a root login.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.