How to Install WordPress on Ubuntu with Apache, MySQL
Setting up WordPress on your own Ubuntu server is a great way to take full control of your website’s performance, security, and configuration. In this guide, we’ll walk through installing WordPress with Apache, MySQL, and SSL using Certbot’s Let’s Encrypt integration.
For most users, this level of setup isn’t necessary — many hosting providers already offer one-click WordPress installations that handle everything automatically. However, if you’re using a VPS (Virtual Private Server), or you want to create a local development environment to learn, experiment, or host multiple sites, installing WordPress manually gives you complete flexibility and understanding of how everything works under the hood.
Update and Install Required Packages
Before we start we would need to install updates and also add required packages.
sudo apt update && sudo apt upgrade -y
It updates your package list and then upgrades all your installed software to the latest versions automatically.
To make updates run automatically on a fixed schedule, create a cron job:
crontab -e
Add following cront task to ran every sunday at 3 AM
0 3 * * 0 apt update && apt upgrade -y && apt autoremove -y
Regular updates protect your system from security vulnerabilities, fix software bugs, and improve overall performance and stability. You can set up cron task to run this every week. Open and edit your crontab
Install all packages
sudo apt install apache2 mysql-server php php-mysql libapache2-mod-php php-cli php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip unzip wget curl certbot python3-certbot-apache -y
| Package | Purpose |
|---|---|
| apache2 | The web server that serves your WordPress site. |
| mysql-server | The database engine for storing all WordPress data (posts, users, etc.). |
| php | The main programming language WordPress runs on. |
| php-mysql | PHP extension that lets WordPress talk to MySQL. |
| libapache2-mod-php | Integrates PHP with Apache (so .php files run properly). |
| php-cli | Command-line PHP interface (useful for WP-CLI and debugging). |
| php-curl | Required by many plugins (for API requests). |
| php-gd | Image manipulation (used for thumbnails, resizing, etc.). |
| php-mbstring | Multibyte string handling (important for non-English content). |
| php-xml | XML processing (used by WordPress core and some plugins). |
| php-xmlrpc | XML-RPC protocol (used for remote publishing, sometimes optional). |
| php-soap | Enables SOAP API calls (some plugins need this). |
| php-intl | Internationalization / localization support. |
| php-zip | Enables WordPress plugin/theme zip installs. |
| unzip | Extracts compressed files (e.g., WordPress download). |
| wget | Downloads files from the internet (used to fetch WordPress). |
| curl | Makes web requests (used by various scripts and plugins). |
| certbot | The certbot package installs the main Let’s Encrypt client, a free and open-source tool used to automate the creation, installation, and renewal of SSL/TLS certificates on your server. |
| python3-certbot-apache | The package that contains both Certbot (the Let’s Encrypt client) and its Apache integration plugin. |
Download WordPress
cd /var/www/
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xvzf latest.tar.gz
sudo mv wordpress yoursite
sudo chown -R www-data:www-data /var/www/yoursite
sudo find /var/www/yoursite -type d -exec chmod 755 {} \;
sudo find /var/www/yoursite -type f -exec chmod 644 {} \;
Configuration
MySQL
Secure your MySQL installation by running a command
sudo mysql_secure_installation
- Set root password
- Remove anonymous users
- Disallow remote root login
- Remove test DB
- Reload privileges
Next, we’ll create a database for WordPress. To do that, log in to the MySQL server and open the MySQL shell.
sudo mysql -u root -p
This command logs you into the MySQL database server as the root user (administrator) so you can create databases, users, and manage data directly.
Inside MySQL shell:
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Apache
Before we start, you need to add a DNS record in your domain hosting provider that points to your VPS.
If you’re installing on a local server, you can skip this step and continue.
To set up your WordPress site, create a new virtual host file by copying the default Apache configuration file.
This will let you define your own domain name, document root, and other settings without affecting the default site.
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/wordpress.conf
Then you can open it for editing:
sudo nano /etc/apache2/sites-available/wordpress.conf
<VirtualHost *:80>
ServerAdmin admin@yourdomain.com
ServerName yourdomain.com
ServerAlias yourdomain.com
DocumentRoot /var/www/wordpress
<Directory /var/www/wordpress>
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/wordpress_error.log
CustomLog ${APACHE_LOG_DIR}/wordpress_access.log combined
</VirtualHost>
ServerAdmin– your email address (for Apache error notifications).ServerName– your main domain name.ServerAlias– optional, forwwwversion of the domain.DocumentRoot– folder where WordPress files are stored.<Directory>block – allows.htaccessrules to work (important for WordPress permalinks).ErrorLog/CustomLog– specify where logs are saved.
If you’re running your LAMP stack in a local environment, you can set a custom server name such as yourapp.local.
Then, update your hosts file to map that name to localhost (127.0.0.1).
This allows you to access your site using http://yourapp.local instead of http://localhost, which is especially useful when you have multiple sites running on your local machine.
To enable your new WordPress site and disable the default one, run:
sudo a2ensite wordpress.conf
sudo a2dissite 000-default.conf
sudo a2enmod rewrite
sudo systemctl restart apache2
SSL certifacates
When running WordPress on a local environment, you don’t need to install an SSL certificate.
Local servers are only accessible from your own machine, so using plain HTTP is completely fine for development or testing purposes.
However, when your website is hosted on a public domain (for example, on a VPS or web hosting provider), it’s highly recommended — and often required — to use HTTPS.
HTTPS encrypts the connection between your visitors and your server, keeping data like passwords and forms secure.
It also helps your site rank higher on Google and prevents browsers from showing “Not Secure” warnings.
At the very beginning, we installed Certbot, a tool used to generate and manage free SSL certificates from Let’s Encrypt.
Certbot makes it simple to secure your website by automatically verifying your domain, issuing a certificate, and updating your Apache configuration to use HTTPS.
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Certbot will:
- Generate a new SSL certificate for your domain.
- Create its own SSL configuration file inside
/etc/apache2/sites-available/— typically named something like:yourdomain-le-ssl.conf - Link this configuration automatically with your existing virtual host, so Apache starts serving your site over HTTPS (port 443).
- Redirect all HTTP traffic (port 80) to HTTPS for better security.
- Schedule automatic certificate renewal, so your SSL certificate stays valid without manual intervention.
Redirecting HTTP Traffic to HTTPS
Next, we need to make sure that all HTTP traffic on port 80 is redirected to HTTPS (port 443).
There are a couple of ways to achieve this.
Option 1: Update your Apache configuration
You can modify your existing virtual host file for port 80 to include a redirect rule like this:
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
Redirect permanent / https://yourdomain.com/
</VirtualHost>
This ensures that anyone visiting http://yourdomain.com will be automatically redirected to https://yourdomain.com.
It’s the cleanest and most efficient method since the redirect happens directly at the server level.
Option 2: Disable the old configuration and use .htaccess
If you prefer, you can disable the old HTTP site and manage the redirect from your .htaccess file instead.
Disable the default HTTP configuration:
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
Then, in your WordPress .htaccess file (located in /var/www/wordpress/), add the following lines:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
This approach works fine, though it’s slightly less efficient since .htaccess rules are processed after Apache has already served the request.
Best practice:If possible, keep port 80 enabled and use the Apache redirect (Option 1). It’s faster, cleaner, and easier to maintain.









