Could not create work tree dir 'example.com'.: Permission denied

Learn could not create work tree dir 'example.com'.: permission denied with practical examples, diagrams, and best practices. Covers git, github, nginx development techniques with visual explanations.

Resolving 'Could not create work tree dir': Permission Denied in Git Deployments

Hero image for Could not create work tree dir 'example.com'.: Permission denied

Encountering 'Permission denied' when Git tries to create a work tree directory is a common issue, especially in server environments. This article guides you through diagnosing and fixing this problem, ensuring smooth deployments.

When deploying code to a server using Git, you might run into the error message: Could not create work tree dir 'example.com'.: Permission denied. This typically indicates that the user executing the Git command (often via SSH) lacks the necessary write permissions in the target directory where Git is attempting to create or update the work tree. This issue is prevalent in environments involving VPS, Nginx, and automated deployment scripts.

Understanding the 'Permission Denied' Error

The 'Permission denied' error is a fundamental operating system security mechanism. When Git tries to create or modify files and directories within a specific path, the operating system checks if the user running the Git process has the appropriate permissions. If not, the operation is blocked, and this error is returned. In deployment scenarios, this often happens when the Git user (e.g., git, www-data, or your SSH user) doesn't own the deployment directory or lacks write access to it.

flowchart TD
    A[Git Push/Deploy Command] --> B{Server SSH User}
    B --> C{Attempt to create/update work tree dir}
    C --> D{Check Directory Permissions}
    D -- Permission Granted --> E[Work tree created/updated]
    D -- Permission Denied --> F["Error: Could not create work tree dir 'example.com'.: Permission denied"]
    F --> G[Deployment Fails]

Flowchart illustrating the Git deployment process and where permission errors occur.

Common Causes and Solutions

Several factors can lead to this permission issue. Identifying the root cause is crucial for applying the correct fix. We'll explore the most common scenarios and their respective solutions.

1. Identify the Target Directory

First, confirm the exact directory where Git is trying to create the work tree. This is usually the path specified in your deployment script or the GIT_WORK_TREE environment variable. For example, /var/www/example.com.

2. Check Current Permissions and Ownership

Use the ls -ld command to inspect the permissions and ownership of the parent directory. For instance, if Git is trying to create example.com inside /var/www/, check /var/www/.

3. Determine the Executing User

Find out which user is executing the Git command. If you're deploying via SSH, it's your SSH user. If it's an automated process (e.g., a CI/CD pipeline or a Git hook), it might be a dedicated system user like git, www-data, or the user configured for your web server (Nginx/Apache).

4. Grant Ownership to the Correct User

If the executing user does not own the directory, change its ownership using chown. For example, if your SSH user is deployuser and the directory is /var/www/example.com:

5. Adjust Directory Permissions

Ensure the directory has appropriate write permissions for the owner or group. A common setting for web directories is 755 for directories and 644 for files, but for the user to write, 775 or 770 might be necessary for the parent directory if group write access is desired, or 700 if only the owner should write.

6. Verify SSH Key Permissions (if applicable)

If you're using SSH keys for authentication, ensure your private key has the correct permissions (chmod 400 ~/.ssh/id_rsa). While not directly related to the 'work tree dir' error, incorrect SSH key permissions can prevent successful authentication, leading to other issues.

ls -ld /var/www/
# Example output:
drwxr-xr-x 3 root root 4096 Jan 1 10:00 /var/www/

# If 'deployuser' needs to write to /var/www/example.com:
sudo chown deployuser:deployuser /var/www/example.com

# Or, if 'deployuser' needs to create 'example.com' inside /var/www/:
sudo chown deployuser:deployuser /var/www/
sudo chmod 775 /var/www/ # Grant group write access

# Alternatively, if Nginx user (www-data) needs access:
sudo chown -R deployuser:www-data /var/www/example.com
sudo chmod -R g+w /var/www/example.com

Commands to check and modify directory ownership and permissions.

Using Git Hooks for Deployment

When deploying with Git hooks (e.g., a post-receive hook), the Git user (often git or the user who owns the bare repository) is the one executing the commands. It's crucial that this user has permissions to write to the web root directory. A common pattern is to set up a bare repository and then use a post-receive hook to checkout the files to the web directory.

# Example post-receive hook (located in your_repo.git/hooks/post-receive)
#!/bin/sh
GIT_WORK_TREE=/var/www/example.com git checkout -f

# Ensure the hook is executable
chmod +x your_repo.git/hooks/post-receive

A basic post-receive hook for deploying to a web directory.

Nginx and Web Server User Considerations

If your web server (like Nginx) needs to serve files from the deployed directory, its user (commonly www-data on Debian/Ubuntu or nginx on CentOS/RHEL) must have read access. If your deployment process also involves the web server user (e.g., for log files or temporary directories), ensure it has appropriate write permissions as well. Often, setting the group of the web directory to www-data and granting group write permissions (g+w) is a secure approach.

By systematically checking the user, directory ownership, and permissions, you can effectively troubleshoot and resolve the 'Could not create work tree dir: Permission denied' error, leading to more reliable Git deployments.