Looking for a development team? Let's build something amazing together! Hire Us
Codend Logo end

Browse Categories

ESC

Start typing to search through our articles...

How to Deploy PHP Website on Ubuntu VPS: Complete LAMP Stack Guide

How to Deploy PHP Website on Ubuntu VPS: Complete LAMP Stack Guide

A comprehensive guide to deploying your PHP website on an Ubuntu VPS using Apache, MySQL, and PHP (LAMP Stack). ## Prerequisites Before you begin, ensure you have: - A VPS running **Ubuntu 20.04/22.04/24.04** - A domain name pointing to your VPS IP - SSH access to your server - Root or sudo privileges --- ## Initial Server Setup ### Step 1: Connect to Your VPS ```bash ssh root@your_server_ip ``` ### Step 2: Create a Non-Root User ```bash # Create new user adduser webadmin # Grant sudo privileges usermod -aG sudo webadmin # Switch to new user su - webadmin ``` ### Step 3: Update System Packages ```bash sudo apt update && sudo apt upgrade -y ``` --- ## Installing Apache Web Server ### Step 1: Install Apache ```bash sudo apt install apache2 -y ``` ### Step 2: Start and Enable Apache ```bash # Start Apache sudo systemctl start apache2 # Enable on boot sudo systemctl enable apache2 # Check status sudo systemctl status apache2 ``` ### Step 3: Verify Installation Open your browser and navigate to: ``` http://your_server_ip ``` You should see the Apache2 Ubuntu Default Page. ### Step 4: Configure Firewall ```bash # Enable UFW sudo ufw enable # Allow SSH first! sudo ufw allow OpenSSH # Allow Apache sudo ufw allow 'Apache Full' # Check status sudo ufw status ``` --- ## Installing MySQL Database ### Step 1: Install MySQL Server ```bash sudo apt install mysql-server -y ``` ### Step 2: Secure MySQL Installation ```bash sudo mysql_secure_installation ``` Follow the prompts: - Set up VALIDATE PASSWORD plugin (recommended: Yes) - Set root password - Remove anonymous users (Yes) - Disallow root login remotely (Yes) - Remove test database (Yes) - Reload privilege tables (Yes) ### Step 3: Create Database and User ```bash # Access MySQL sudo mysql # Create database CREATE DATABASE mywebsite; # Create user with password CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'StrongPassword123!'; # Grant privileges GRANT ALL PRIVILEGES ON mywebsite.* TO 'webuser'@'localhost'; # Apply changes FLUSH PRIVILEGES; # Exit EXIT; ``` ### Step 4: Test MySQL Connection ```bash mysql -u webuser -p mywebsite ``` --- ## Installing PHP ### Step 1: Install PHP and Common Extensions ```bash sudo apt install php libapache2-mod-php php-mysql -y ``` ### Step 2: Install Additional PHP Extensions ```bash sudo apt install php-curl php-gd php-mbstring php-xml php-zip php-intl php-bcmath php-json -y ``` ### Step 3: Verify PHP Installation ```bash php -v ``` ### Step 4: Test PHP Processing Create a test file: ```bash sudo nano /var/www/html/info.php ``` Add this content: ```php <?php phpinfo(); ?> ``` Visit `http://your_server_ip/info.php` to verify PHP is working. > ⚠️ **Important**: Delete this file after testing: > ```bash > sudo rm /var/www/html/info.php > ``` ### Step 5: Configure Apache to Prefer PHP Files ```bash sudo nano /etc/apache2/mods-enabled/dir.conf ``` Move `index.php` to the front: ```apache <IfModule mod_dir.c> DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm </IfModule> ``` Restart Apache: ```bash sudo systemctl restart apache2 ``` --- ## Configuring Virtual Hosts ### Step 1: Create Directory Structure ```bash # Create web directory sudo mkdir -p /var/www/yourdomain.com/public_html # Set ownership sudo chown -R $USER:$USER /var/www/yourdomain.com # Set permissions sudo chmod -R 755 /var/www/yourdomain.com ``` ### Step 2: Create Virtual Host Configuration ```bash sudo nano /etc/apache2/sites-available/yourdomain.com.conf ``` **Virtual Host Configuration:** ```apache <VirtualHost *:80> ServerAdmin [email protected] ServerName yourdomain.com ServerAlias www.yourdomain.com DocumentRoot /var/www/yourdomain.com/public_html <Directory /var/www/yourdomain.com/public_html> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> # Logging ErrorLog ${APACHE_LOG_DIR}/yourdomain.com_error.log CustomLog ${APACHE_LOG_DIR}/yourdomain.com_access.log combined </VirtualHost> ``` ### Step 3: Enable the Site ```bash # Enable virtual host sudo a2ensite yourdomain.com.conf # Enable mod_rewrite (for .htaccess) sudo a2enmod rewrite # Disable default site (optional) sudo a2dissite 000-default.conf # Test configuration sudo apache2ctl configtest # Restart Apache sudo systemctl restart apache2 ``` --- ## Deploying Your PHP Application ### Option 1: Upload via SFTP Use an SFTP client like FileZilla: - Host: your_server_ip - Username: webadmin - Port: 22 - Upload files to `/var/www/yourdomain.com/public_html/` ### Option 2: Clone from Git Repository ```bash cd /var/www/yourdomain.com/public_html # Clone your repository git clone https://github.com/yourusername/your-php-app.git . ``` ### Option 3: Upload via SCP From your local machine: ```bash scp -r /path/to/local/files/* webadmin@your_server_ip:/var/www/yourdomain.com/public_html/ ``` ### Set Proper Permissions ```bash # Set ownership sudo chown -R www-data:www-data /var/www/yourdomain.com/public_html # Set directory permissions sudo find /var/www/yourdomain.com/public_html -type d -exec chmod 755 {} \; # Set file permissions sudo find /var/www/yourdomain.com/public_html -type f -exec chmod 644 {} \; # Writable directories (uploads, cache, etc.) sudo chmod -R 775 /var/www/yourdomain.com/public_html/uploads sudo chmod -R 775 /var/www/yourdomain.com/public_html/cache ``` ### Configure Database Connection Create or edit your config file: ```php <?php // config.php define('DB_HOST', 'localhost'); define('DB_NAME', 'mywebsite'); define('DB_USER', 'webuser'); define('DB_PASS', 'StrongPassword123!'); try { $pdo = new PDO( "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ] ); } catch (PDOException $e) { die("Connection failed: " . $e->getMessage()); } ?> ``` ### Import Database (if needed) ```bash mysql -u webuser -p mywebsite < /path/to/database.sql ``` --- ## SSL Certificate Setup ### Step 1: Install Certbot ```bash sudo apt install certbot python3-certbot-apache -y ``` ### Step 2: Obtain SSL Certificate ```bash sudo certbot --apache -d yourdomain.com -d www.yourdomain.com ``` Follow the prompts: - Enter email address - Agree to Terms of Service - Choose to redirect HTTP to HTTPS (recommended) ### Step 3: Verify Auto-Renewal ```bash # Test renewal sudo certbot renew --dry-run # Check timer status sudo systemctl status certbot.timer ``` ### Step 4: Verify HTTPS Visit `https://yourdomain.com` to confirm SSL is working. --- ## PHP Configuration Optimization ### Edit PHP Configuration ```bash sudo nano /etc/php/8.1/apache2/php.ini ``` > Replace `8.1` with your PHP version (check with `php -v`) ### Recommended Settings ```ini ; Maximum upload file size upload_max_filesize = 64M post_max_size = 64M ; Maximum execution time max_execution_time = 300 ; Memory limit memory_limit = 256M ; Error handling (production) display_errors = Off log_errors = On error_log = /var/log/php_errors.log ; Timezone date.timezone = UTC ; Session security session.cookie_httponly = 1 session.cookie_secure = 1 session.use_strict_mode = 1 ``` ### Restart Apache ```bash sudo systemctl restart apache2 ``` --- ## Security Hardening ### 1. Hide Apache Version ```bash sudo nano /etc/apache2/conf-available/security.conf ``` Set: ```apache ServerTokens Prod ServerSignature Off ``` ### 2. Hide PHP Version In `php.ini`: ```ini expose_php = Off ``` ### 3. Disable Directory Listing Already done in virtual host with `Options -Indexes` ### 4. Create .htaccess Security Rules ```bash nano /var/www/yourdomain.com/public_html/.htaccess ``` ```apache # Prevent access to sensitive files <FilesMatch "^\."> Order allow,deny Deny from all </FilesMatch> # Block access to config files <FilesMatch "(config\.php|\.env|composer\.json|composer\.lock)$"> Order allow,deny Deny from all </FilesMatch> # Prevent script execution in uploads <Directory "/var/www/yourdomain.com/public_html/uploads"> <FilesMatch "\.(php|phtml|php3|php4|php5|php7|phps|pl|py|jsp|asp|cgi|sh)$"> Order allow,deny Deny from all </FilesMatch> </Directory> # Security headers <IfModule mod_headers.c> Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" </IfModule> ``` ### 5. Secure MySQL ```bash # Ensure MySQL only listens locally sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf ``` Verify this line exists: ``` bind-address = 127.0.0.1 ``` ### 6. Enable Fail2Ban ```bash # Install Fail2Ban sudo apt install fail2ban -y # Enable and start sudo systemctl enable fail2ban sudo systemctl start fail2ban ``` --- ## Optional: Install phpMyAdmin ### Step 1: Install phpMyAdmin ```bash sudo apt install phpmyadmin -y ``` During installation: - Select `apache2` as the web server - Choose `Yes` to configure database with dbconfig-common - Set a password for phpMyAdmin ### Step 2: Enable PHP mcrypt (if needed) ```bash sudo phpenmod mcrypt sudo systemctl restart apache2 ``` ### Step 3: Secure phpMyAdmin ```bash sudo nano /etc/apache2/conf-available/phpmyadmin.conf ``` Add access restriction: ```apache <Directory /usr/share/phpmyadmin> # Restrict by IP Order Deny,Allow Deny from all Allow from your_local_ip # Or use password protection AuthType Basic AuthName "Restricted Access" AuthUserFile /etc/phpmyadmin/.htpasswd Require valid-user </Directory> ``` Create password file: ```bash sudo htpasswd -c /etc/phpmyadmin/.htpasswd admin sudo systemctl restart apache2 ``` --- ## Troubleshooting ### Common Issues and Solutions #### 500 Internal Server Error ```bash # Check Apache error logs sudo tail -f /var/log/apache2/error.log # Check PHP error logs sudo tail -f /var/log/php_errors.log # Check file permissions ls -la /var/www/yourdomain.com/public_html/ ``` #### Permission Denied Errors ```bash # Fix ownership sudo chown -R www-data:www-data /var/www/yourdomain.com/public_html # Fix permissions sudo find /var/www/yourdomain.com -type d -exec chmod 755 {} \; sudo find /var/www/yourdomain.com -type f -exec chmod 644 {} \; ``` #### MySQL Connection Refused ```bash # Check MySQL is running sudo systemctl status mysql # Restart MySQL sudo systemctl restart mysql # Check if listening sudo ss -tulpn | grep mysql ``` #### .htaccess Not Working ```bash # Ensure mod_rewrite is enabled sudo a2enmod rewrite # Check AllowOverride is set to All sudo nano /etc/apache2/sites-available/yourdomain.com.conf # Restart Apache sudo systemctl restart apache2 ``` ### Useful Commands ```bash # View Apache status sudo systemctl status apache2 # View Apache error log sudo tail -f /var/log/apache2/error.log # View access log sudo tail -f /var/log/apache2/access.log # Test Apache configuration sudo apache2ctl configtest # Check PHP modules php -m # Check disk space df -h # Check memory usage free -m ``` --- ## Deployment Workflow For future updates: ```bash # SSH into server ssh webadmin@your_server_ip # Navigate to web directory cd /var/www/yourdomain.com/public_html # Pull latest changes git pull origin main # Clear cache (if applicable) rm -rf cache/* # Set permissions sudo chown -R www-data:www-data . # Restart Apache (if needed) sudo systemctl restart apache2 ``` --- ## Quick Reference | Action | Command | |--------|---------| | Start Apache | `sudo systemctl start apache2` | | Stop Apache | `sudo systemctl stop apache2` | | Restart Apache | `sudo systemctl restart apache2` | | Reload Apache | `sudo systemctl reload apache2` | | Start MySQL | `sudo systemctl start mysql` | | Restart MySQL | `sudo systemctl restart mysql` | | Apache Error Log | `sudo tail -f /var/log/apache2/error.log` | | Test Config | `sudo apache2ctl configtest` | | Renew SSL | `sudo certbot renew` | --- ## Conclusion You now have a fully functional PHP website running on your Ubuntu VPS with: - **Apache** as the web server - **MySQL** as the database - **PHP** for server-side processing - **SSL/HTTPS** via Let's Encrypt - **Security hardening** for production Your LAMP stack is now production-ready! --- *Last Updated: January 2026* *Tags: #PHP #Ubuntu #VPS #LAMP #Apache #MySQL #WebHosting #Deployment*

Comments (0)

Leave a Comment