How to Deploy WordPress with Git Version Control on DigitalOcean 2025
How to Deploy WordPress with Git Version Control on DigitalOcean 2025
WordPress developers often struggle with a fundamental problem: how do you keep WordPress core updated while preserving custom code changes? The official WordPress GitHub repository is a read-only mirror of the SVN repository, designed for reference and contribution workflows through wordpress-develop. But you can use Git strategically to manage WordPress deployments on DigitalOcean, separating your custom code from core files.
This guide walks you through deploying WordPress with Git-based version control on DigitalOcean, allowing you to:
- Track WordPress core separately from your custom themes and plugins
- Deploy updates safely without losing modifications
- Roll back changes quickly if something breaks
- Collaborate with team members using standard Git workflows
Prerequisites
Before starting, ensure you have:
- A DigitalOcean account with an active Droplet (Ubuntu 20.04 LTS or later recommended)
- SSH access to your Droplet
- Git installed on both your local machine and the Droplet
- PHP 7.4+ and MySQL 5.5.5+ on your Droplet (PHP 8.3+ and MySQL 8.0+ recommended)
- Basic familiarity with Git and command-line operations
Step 1: Prepare Your DigitalOcean Droplet
SSH into your DigitalOcean Droplet and update system packages:
ssh root@your_droplet_ip
apt update && apt upgrade -y
apt install -y git php-fpm php-mysql php-cli mysql-server nginx
Create a dedicated directory for your WordPress installation:
mkdir -p /var/www/wordpress
cd /var/www/wordpress
Initialize a Git repository in this directory:
git init
git config user.name "Your Name"
git config user.email "your-email@example.com"
Step 2: Set Up WordPress Core with Git Subtree (Recommended Approach)
The safest way to manage WordPress with Git is using Git subtree or submodules. This keeps WordPress core tracked separately from your custom code.
Add the official WordPress GitHub mirror as a remote:
git remote add wordpress https://github.com/WordPress/WordPress.git
git fetch wordpress
Bring in WordPress core files using subtree (this tracks core in a subdirectory):
git subtree add --prefix wordpress wordpress main --squash
This creates a /wordpress directory containing the latest WordPress core. The --squash flag keeps your repository clean by not importing the entire WordPress commit history.
Step 3: Organize Your Project Structure
Structure your Git repository to separate concerns:
/var/www/wordpress/
├── .gitignore
├── .git/
├── wordpress/ # WordPress core (subtree)
├── custom-themes/ # Your custom themes
├── custom-plugins/ # Your custom plugins
├── wp-config-local.php # Environment-specific config (not in Git)
└── deploy.sh # Deployment script
Create a .gitignore file to exclude sensitive and unnecessary files:
cat > .gitignore << 'EOF'
wp-config.php
wp-config-local.php
.env
.env.local
wordpress/wp-content/uploads/
wordpress/wp-content/cache/
node_modules/
.DS_Store
EOF
Step 4: Configure WordPress
Create wp-config.php pointing to your WordPress core:
cp wordpress/wp-config-sample.php wp-config-local.php
Edit wp-config-local.php with your database credentials, then create a wrapper wp-config.php:
<?php
// Load environment-specific config
if (file_exists(__DIR__ . '/wp-config-local.php')) {
require_once(__DIR__ . '/wp-config-local.php');
}
// Standard WordPress settings
if (!defined('ABSPATH')) {
define('ABSPATH', __DIR__ . '/wordpress/');
}
require_once(ABSPATH . 'wp-settings.php');
?>
Set correct permissions:
chown -R www-data:www-data /var/www/wordpress
chmod 644 wp-config.php
Step 5: Commit Your Initial Setup
git add -A
git commit -m "Initial WordPress setup with custom themes and plugins"
Step 6: Create a Deployment Script
Create an automated deployment script (deploy.sh):
#!/bin/bash
set -e
echo "Pulling latest changes from Git..."
git pull origin main
echo "Updating WordPress core subtree..."
git subtree pull --prefix wordpress https://github.com/WordPress/WordPress.git main --squash
echo "Running WordPress database migrations..."
wp db upgrade --allow-root --path=/var/www/wordpress/wordpress/
echo "Clearing cache..."
wp cache flush --allow-root --path=/var/www/wordpress/wordpress/
echo "Setting correct permissions..."
chown -R www-data:www-data /var/www/wordpress
echo "Deployment complete!"
Make it executable:
chmod +x deploy.sh
Step 7: Configure Nginx
Create an Nginx configuration file:
cat > /etc/nginx/sites-available/wordpress << 'EOF'
server {
listen 80;
server_name your-domain.com www.your-domain.com;
root /var/www/wordpress;
index index.php;
location / {
try_files $uri $uri/ /wordpress/index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
EOF
ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
Step 8: Manage WordPress Updates
Update WordPress Core Safely
When a new WordPress version is released:
cd /var/www/wordpress
git subtree pull --prefix wordpress https://github.com/WordPress/WordPress.git main --squash
git add -A
git commit -m "Update WordPress to version X.X.X"
git push origin main
Then run your deployment script:
./deploy.sh
Roll Back if Needed
If an update breaks something:
git log --oneline | head -20 # Find the commit
git revert <commit-hash>
git push origin main
./deploy.sh
Comparison: Git Approaches for WordPress
| Approach | Setup | Maintenance | Core Updates | Collaboration |
|----------|-------|-------------|--------------|---------------|
| Git Subtree | Medium | Easy | Simple subtree pull | Excellent for teams |
| Git Submodule | Medium | Moderate | Requires submodule updates | Good, can be confusing |
| Manual + Git | Simple | Hard | Manual downloads | Difficult |
| Composer | Medium | Easy | Via composer update | Excellent |
Best Practices
- Never commit
wp-config.php— Use environment variables or.gitignoreto protect database credentials - Use
.gitignoreextensively — Exclude upload directories, cache, and node_modules - Test updates locally first — Always test WordPress updates on a staging environment before production
- Automate deployments — Use GitHub Actions or Webhook integrations to trigger
deploy.shautomatically - Backup before updates — Always backup your database before pulling updates:
wp db export backup-$(date +%Y%m%d).sql --allow-root --path=/var/www/wordpress/wordpress/
Troubleshooting Common Issues
Issue: Permission denied when pulling updates
Ensure the web server user owns the directory:
sudo chown -R www-data:www-data /var/www/wordpress
Issue: WordPress still shows old version after subtree pull
Clear WordPress cache and reload:
wp cache flush --allow-root
wp core version --allow-root --path=/var/www/wordpress/wordpress/
Next Steps
- Set up automated testing for custom plugins
- Implement GitHub Actions for CI/CD pipelines
- Use database migration tools like WP-CLI for production deployments
- Consider using Composer for dependency management of plugins and themes
By separating WordPress core from your custom code using Git, you gain the flexibility to update WordPress regularly while maintaining complete control over your customizations.
Recommended Tools
- DigitalOceanCloud hosting built for developers — $200 free credit for new users