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

  1. Never commit wp-config.php — Use environment variables or .gitignore to protect database credentials
  2. Use .gitignore extensively — Exclude upload directories, cache, and node_modules
  3. Test updates locally first — Always test WordPress updates on a staging environment before production
  4. Automate deployments — Use GitHub Actions or Webhook integrations to trigger deploy.sh automatically
  5. 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