How to Install Apache, MySQL, PHP (LAMP Stack) on Debian 12?
Introduction
The installation of the LAMP stack is required to build a dynamic website or a web application on a Debian 12 server. This Debian LAMP server consists of four essential open-source components: Linux, Apache, MySQL, and PHP. Together, the below tools create a powerful and efficient web server setup.
- Linux provides a stable and secure environment. It acts as the foundation for your system.
- Apache is a popular web server. It is responsible for handling incoming web requests and serving your website content.
- MySQL acts as a backend database.
- Lastly, PHP processes the dynamic content of your website and makes it interactive.
Prerequisites
- Deploy Debian 12 on a server using a cloud provider service like Cantech.
- Point a domain to your server. Set up a new A record that maps your domain to the server’s public IP.
 Example: app.example.com
- Access your server via SSH. Log in as a non-root user with sudo privileges.
- Update your system. Run the command below to refresh package lists and install any pending updates.
sudo apt update sudo apt upgrade -y
Now, let’s get started with the setup process of LAMP.
Install Apache on Debian
Apache is included in Debian’s official package repository by default, so installation becomes simple. Follow the steps below to get Apache up and running –
- Install Apache
Use the following command to install Apache. It gets the latest version of Apache and installs it on your server.
sudo apt install apache2 -y
- After installation, check Apache version Debian to verify the installed Apache.
sudo apachectl -v
The output should display details about the Apache version and its build date.
Server version: Apache/2.4.57 (Debian) Server built: 2024-04-05T10:22:18
- Start Apache Service
Start serving web pages by starting the Apache service with this command –
sudo systemctl start apache2
This command ensures that Apache is actively running on your server.
- Enable Apache to Start on Boot
Enable Apache to launch automatically so that you need not start it manually every time the server reboots –
sudo systemctl enable apache2
This step makes sure Apache starts whenever your server is turned on.
- Check Apache Service Status
Verify whether Apache is running properly with the following command –
sudo systemctl status apache2
You should see an output showing the service as active and running if Apache is running.
● apache2.service - The Apache HTTP Server
     Loaded:  loaded (/lib/systemd/system/apache2.service; enabled; preset: enabled)
       Active:  active (running) since Mon 2025-09-01 09:32:41 IST; 10s ago
         Docs:  https://httpd.apache.org/docs/2.4/
   Main PID:  1234 (apache2)
        Tasks:  55 (limit: 4600)
    Memory:  8.2M
           CPU:  40ms
     CGroup:  /system.slice/apache2.service
                    ├─1234 /usr/sbin/apache2 -k start
                    ├─1236 /usr/sbin/apache2 -k start
                    └─1237 /usr/sbin/apache2 -k start
Installing MySQL
This guide will take you through every step to get MySQL running on your server.
Step 1 – Add the MySQL APT Repository
- Download the latest MySQL repository setup file using the following command –
sudo wget https://dev.mysql.com/get/mysql-apt-config_0.8.34-1_all.deb
You need to get the most up-to-date version of MySQL.
- Then, install the downloaded package
sudo dpkg -i mysql-apt-config_0.8.34-1_all.deb
This step configures your system to fetch MySQL from the official repositories.
- Select MySQL Server & Clusterand pressEnterwhen prompted.
┌─────────────────────────────────┤ Configuring mysql-apt-config ├─────────────────────────────────┐ │ Which MySQL product do you wish to configure? │ │ │ │ MySQL Server & Cluster (Currently selected: mysql-8.4-lts) │ │ MySQL Connectors (Currently selected: Enabled) │ │ │ │ │ │ <Ok> │ └──────────────────────────────────────────────────────────────────────────────────────────────────┘
- Navigate with the arrow keysto choose the MySQL Server version you prefer, such asmysql-8.4-lts, and pressEnterto continue.
┌─────────────────────────────────┤ Configuring mysql-apt-config ├─────────────────────────────────┐ │ Which server version do you wish to receive? │ │ │ │ mysql-8.0 │ │ mysql-8.2 │ │ mysql-8.4-lts │ │ mysql-innovation │ │ mysql-cluster-8.0 │ │ mysql-cluster-8.2 │ │ mysql-cluster-8.4-lts │ │ None │ │ │ │ <Ok> │ └──────────────────────────────────────────────────────────────────────────────────────────────────┘
- Press Enterto confirm your selection and save changes.┌─────────────────────────────────┤ Configuring mysql-apt-config ├─────────────────────────────────┐ │ Which MySQL product do you wish to configure? │ │ │ │ MySQL Server & Cluster (Currently selected: mysql-8.4-lts) │ │ MySQL Connectors (Currently selected: Enabled) │ │ Ok │ │ │ │ │ │ <Ok> │ └──────────────────────────────────────────────────────────────────────────────────────────────────┘ 
Step 2 – Update Package List and Install MySQL
- Refresh the package list so that your system recognizes the newly added MySQL repository.
sudo apt update
- Install the MySQL server package with all required dependencies.
sudo apt install mysql-server -y
Step 3 – Set Up the Root User Password
- You will be prompted to set a password for the rootdatabase user. Enter a strong password and pressEnter.Enter root password: 
- Re-enter the password to confirm it.
Re-enter root password: 
Step 4 – Verify MySQL Installation
- Check the installed MySQL version with this command –
mysql --version
A sample output may look like this –
mysql Ver 8.4.2 for Linux on x86_64 (MySQL Community Server - GPL)
- Start the MySQL service.
sudo systemctl start mysql
- Enable MySQL to start automatically when the server boots.
sudo systemctl enable mysql
- Verify that MySQL is running properly –
sudo systemctl status mysql
You should see a message stating “MySQL Community Server is operational”. This means everything is working fine.
● mysql.service - MySQL Community Server
       Loaded:   loaded (/lib/systemd/system/mysql.service; enabled; preset: enabled)
         Active:   active (running) since Tue 2025-09-16 10:25:42 IST; 10s ago
            Doc:    man:mysqld(8)
                        http://dev.mysql.com/doc/refman/en/using-systemd.html
    Main PID:    1548 (mysqld)
        Status:    "Server is operational"
         Tasks:    39 (limit: 4578)
     Memory:   362.5M
        CPU:       2.145s
     CGroup:   /system.slice/mysql.service
                      └─1548 /usr/sbin/mysqld
Step 5 – Secure MySQL Installation
- Run the security script to remove unsafe default settings.
sudo mysql_secure_installation
- Enter the rootpassword (you set earlier) when you are prompted.Enter password for user root: 
- Type Y when asked to configure the VALIDATE PASSWORD plugin.
Would you like to setup VALIDATE PASSWORD component? Press y|Y for Yes, any other key for No: Y 
- Choose the password strength level for your MySQL server. For strong passwords, select option 2.
You can choose from 3 password validation policy levels: 0 (LOW) – Minimum length of 8 characters. 1 (MEDIUM) – Requires numbers, uppercase letters, and special characters. 2 (STRONG) – Includes dictionary checks for extra security. 
- Enter 2 for maximum security and press Enter.
- Type N– when asked to change therootpassword. This will keep the existing one.
- Type Yto remove anonymous MySQL users.
- Select Yto disallowrootlogin remotely.
- Enter Yto delete the test MySQL database for security.
- Again type Yto reload privileges to apply the changes.
Learn more about how to install mysql on debian 12.
Installing and Configuring PHP on Debian 12
PHP must be installed correctly with PHP-FPM (FastCGI Process Manager) for better performance. Also, it needs proper configuration for seamless communication between Apache and PHP.
Step 1 – Install PHP and PHP-FPM
- Run the following command to install PHP and PHP-FPM. This ensures that PHP scripts are processed efficiently.
sudo apt install php php-fpm -y
- Install additional PHP modules to enable database interaction and other functionalities.
sudo apt install php-mysql php-cli libapache2-mod-php -y
The command installs these PHP components:
- 
- php-mysql: Connects PHP with MySQL databases.
- php-cli: Runs PHP scripts via the command line.
- libapache2-mod-php: Integrates PHP with Apache web server.
 
- Check the installed PHP version to confirm successful installation with the below command.
php -v
The output you provide should look similar to the example shown below.
PHP 8.4.8 (cli) (built: Jul 8 2025 10:32:45) (NTS) Copyright (c) The PHP Group Zend Engine v4.4.0, Copyright (c) Zend Technologies
Step 2 – Start and Enable PHP-FPM Service
- This command activates PHP-FPM so that Apache can process PHP files.
 
sudo systemctl start php8.4-fpm
- Ensuring PHP-FPM starts automatically prevents downtime after a server restarts.
sudo systemctl enable php8.4-fpm
- Check PHP-FPM status to confirm whether the PHP-FPM service is running properly.
sudo systemctl status php8.4-fpm
Output:
● php8.4-fpm.service - The PHP 8.4 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php8.4-fpm.service; enabled; vendor preset: enabled)
       Active: active (running) since Tue 2025-09-16 10:15:23 UTC; 1h 22min ago
         Docs: man:php-fpm8.4(8)
   Main PID: 1342 (php-fpm8.4)
       Status: "Processes active: 0, idle: 3, Requests: 120, slow: 0, Traffic: 0req/sec"
        Tasks: 3 (limit: 4567)
    Memory: 15.6M
           CPU: 2.345s
     CGroup: /system.slice/php8.4-fpm.service
                   ├─1342 "php-fpm: master process (/etc/php/8.4/fpm/php-fpm.conf)"
                   ├─1343 "php-fpm: pool www"
                   └─1344 "php-fpm: pool www"
Step 3 – Configure PHP-FPM for Apache
- Apache must communicate with PHP-FPM for processing PHP scripts. Activate the FastCGI module for the same.
 
sudo a2enmod proxy_fcgi
- Check active PHP-FPM socket path. The below command verifies the Unix socket used by PHP-FPM.
ss -pl | grep php
The output will display the active socket path, typically /run/php/php8.4-fpm.sock.
tcp LISTEN 0 128 /run/php/php8.4-fpm.sock 45907 * 0
- Enable PHP-FPM Configuration for Apache.
sudo a2enconf php8.4-fpm
- Restart Apache for Changes to Take Effect.
sudo systemctl restart apache2
Step 4 – Modify PHP-FPM Configuration
- Open PHP-FPM Configuration File.
Use a text editor to modify the PHP-FPM pool settings.
sudo nano /etc/php/8.4/fpm/pool.d/www.conf
- Check the PHP-FPM pool and confirm it is set to www.
[www]
- Make sure the directives shown are set to www-data.
user = www-data group = www-data listen.owner = www-data listen.group = www-data
- Make sure the listendirective uses the PHP-FPM Unix socket path/run/php/php8.4-fpm.sock
listen = /run/php/php8.4-fpm.sock
Adjust Process Management Settings
Modify the following directives based on your server resources.
pm: Defines the process manager type; dynamic adjusts child processes automatically. pm.max_children: Maximum PHP child processes running together. pm.start_servers: Number of child processes created at startup. pm.min_spare_servers: Minimum idle child processes; new ones are created if fewer exist. pm.max_spare_servers: Maximum idle child processes; extra ones are stopped.
Save and Exit the File.
- Restart PHP-FPM Service to Apply Fresh Changes.
sudo systemctl restart php8.4-fpm
Configure Apache with PHP-FPM on Debian 12
Apache can process PHP scripts separately from the web server with PHP-FPM (FastCGI Process Manager). This improves performance and reduces resource usage.
To make this setup work, Apache needs to communicate with PHP-FPM using the proxy_fcgi module and a Unix socket. Below are the steps to configure Apache with PHP-FPM on Debian 12.
1. Create an Apache Virtual Host Configuration
Apache uses virtual hosts to serve websites, so you need to create a new virtual host configuration file for your application.
Open the Apache configuration directory and create a new file –
sudo nano /etc/apache2/sites-available/website.conf
Next, add the following configuration (replacing app.example.com with your actual domain name and [email protected] with your administrator email) –
 <VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName app.example.com
    DocumentRoot /var/www/html
    DirectoryIndex index.html index.php
    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/"
    </FilesMatch>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
2. Understand the Configuration
Handle each line in the virtual host file carefully, as each of them plays a role in handling requests correctly –
- <VirtualHost *:80>
 Means it configures Apache to listen on port80for incoming HTTP requests.
- ServerAdmin [email protected]
 The admin email where server errors will be reported
- ServerName app.example.com
 The domain name to which this configuration applies.
- DocumentRoot /var/www/html
 Tells Apache where to find the website’s files.
- DirectoryIndex index.html index.php
 which file should be loaded when a visitor accesses the root directory.
- <Directory /var/www/html>
 Sets rules for the web root directory/var/www/html
- <FilesMatch \.php$>
 This directs Apache to handle .php files using PHP-FPM.
- SetHandler “proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/”
 Configures Apache to pass PHP requests to the PHP-FPM service
- ErrorLog and CustomLog
 Location where Apache stores error and access logs.
3. Disable the Default Apache Virtual Host Configurations
sudo a2dissite 000-default
4. Activate the New Virtual Host
Activate the new configuration for your website –
sudo a2ensite website
5. Test Apache Configuration
Check if there are any syntax errors in the configuration before restarting Apache –
sudo apachectl configtest
Output ok means everything is set up correctly.
Syntex OK
6. Restart Apache
Apply the changes by restarting the Apache service.
sudo systemctl restart apache2
7. HTTP Traffic Through Firewall
Ensure Apache can receive traffic on port 80 if your firewall is enabled –
sudo ufw allow 80/tcp
- Reload the firewall to apply changes.
sudo ufw reload
8. Test PHP-FPM Integration
You need to confirm that Apache and PHP are working together. Create a PHP test file for the same.
- Create a new index.phpfile in your web root directory.
sudo touch /var/www/html/index.php
- Add the following PHP code.
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/index.php
- Open your browser and go to.
http://app.example.com/index.php
You should see a PHP information page displaying the server configuration. This means everything is working.
Configure Security With Server
Apache runs on HTTP port 80 by default so it transmits data in plain text. This can expose sensitive information to attackers.
You must enable HTTPS by setting up an SSL certificate and securing Apache with a firewall. Below are the steps to configure your server properly and protect your website.
Configuring the Uncomplicated Firewall (UFW)
UFW (Uncomplicated Firewall) is a simple tool to control network traffic. It ensures that only authorized connections are allowed.
- Make sure your website is accessible so allow HTTP (port 80) and HTTPS (port 443):
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
- Reload the firewall to apply changes.
sudo ufw reload
- Verify the firewall status.
sudo ufw status
You will see rules allowing traffic on ports 80 and 443 if configured correctly.
Output:
To Action From -- ------ ---- 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
Generating an SSL Certificate with Let’s Encrypt
- Install Certbot for Apache. It is a free tool that automates SSL certificate installation.
sudo apt install certbot python3-certbot-apache -y
- Generate an SSL certificate.
Replace app.example.com with your actual domain name: [email protected]
sudo certbot --apache --agree-tos --redirect --email [email protected] -d app.example.com
- Verify SSL certificate renewal.
Certificates expire in 90 days. Certbot automatically renews them, but you can test the process manually.
sudo certbot renew --dry-run
- Restart Apache2 Service to apply changes.
sudo systemctl restart apache2
- Test your website’s SSL setup.
Open your browser and visit:
https://app.example.com
You will see a padlock icon in the address bar if everything is configured correctly. This indicates a secure connection.
Testing the Installation with a Sample Database Application
- Log in to MySQL
mysql -u root -p
- Create a new database as a sample.
CREATE DATABASE CantechDB; USE CantechDB;
- Add a new sample database user named db_userand assign it a strong password. Replacestr0ng_p@ssw0rd!with your own secure password.
CREATE USER 'db_user'@'localhost' IDENTIFIED BY 'StrongP@ssw0rd!';
- Provide db_userwith full access rights to theCantechDBdatabase.
GRANT ALL PRIVILEGES ON CantechDB.* TO 'db_user'@'localhost';
- Refresh the MySQL privilege table to make the changes take effect.
FLUSH PRIVILEGES;
- Exit from the MySQL console.
exit;
- Create a PHP script to insert data.
sudo nano /var/www/html/insert.php
- Add the following PHP code.
 <?php
$conn = new mysqli("localhost", "db_user", "StrongP@ssw0rd!", "CantechDB");
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$conn->query("CREATE TABLE IF NOT EXISTS CantechTable (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255))");
$conn->query("INSERT INTO CantechTable (message) VALUES ('Hello from Cantech!')");
echo "Record added!";
$conn->close();
?>
Save and close the file.
This PHP application connects to the MySQL database as db_user. It checks if the CantechTable table exists in the CantechDB database and creates a new one if not.
A successful connection gives a “Greetings from Cantech” record to the table.
- Create a script to display data.
sudo nano /var/www/html/display.php
- Add this code
 <?php
$conn = new mysqli("localhost", "db_user", "StrongP@ssw0rd!", "CantechDB");
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$result = $conn->query("SELECT * FROM CantechTable");
while ($row = $result->fetch_assoc()) {
    echo "<h1>" . $row["id"] . " : " . $row["message"] . "</h1><br>";
}
$conn->close();
?>
- Save and close the file.
- Test the scripts in your browser
Insert Data:
http://app.example.com/insert.php
View Data:
http://app.example.com/display.php
“Hello from Cantech!” displayed means your Apache, MySQL, and PHP setup is working perfectly.
Conclusion
You have now installed all the necessary components with LAMP stack on Debian 12 for dynamic web development. You are now ready to deploy full-fledged websites, applications, and databases with ease. For other setups, you can also check Install Apache, MySQL, PHP (LAMP Stack) on Rocky Linux 9.