Environment variables are the backbone of modern application configuration. Your database credentials, API keys, and service tokens all live in `.env` files — but committing plaintext secrets to your repository has always been a security risk. (For the baseline hygiene — `.gitignore` rules, `.env.example` patterns, and what to do when a key leaks — start with our guide on [how to keep API keys out of your Git repository](https://www.deployhq.com/blog/protecting-your-api-keys-a-quick-guide).)

What if you could safely commit your `.env` files to version control, fully encrypted, and have them automatically decrypted during deployment?

That's exactly what dotenvx enables, and in this guide, we'll show you how to integrate it with [DeployHQ](https://www.deployhq.com) for secure, automated PHP deployments.

## What We're Building

By the end of this tutorial, you'll have:

- Encrypted `.env.production` files committed safely to your repository
- [DeployHQ](https://www.deployhq.com) configured to decrypt secrets during deployment
- A PHP application (Laravel or vanilla PHP) running with secure environment variables

## Prerequisites

- A PHP application with a `.env` file
- A [DeployHQ](https://www.deployhq.com) account with a project configured
- SSH access to your production server
- Git repository connected to [DeployHQ](https://www.deployhq.com)

* * *

## Step 1: Install Dotenvx Locally

First, install dotenvx on your development machine:

```
# macOS/Linux
curl -sfS https://dotenvx.sh/install.sh | sh

# Verify installation
dotenvx --version
```

Alternatively, if you're in a Node.js project:

```
npm install @dotenvx/dotenvx --save-dev
```

## Step 2: Create Your Production Environment File

If you don't already have one, create a `.env.production` file with your production secrets:

```
# .env.production
APP_NAME="My PHP App"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://myapp.com

DB_CONNECTION=mysql
DB_HOST=your-db-server.com
DB_PORT=3306
DB_DATABASE=myapp_production
DB_USERNAME=myapp_user
DB_PASSWORD=super_secret_password_123

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@mg.myapp.com
MAIL_PASSWORD=mailgun_api_key_here

STRIPE_SECRET=sk_live_abc123...
```

## Step 3: Encrypt the Production File

Run the encrypt command targeting your production file:

```
dotenvx encrypt -f .env.production
```

Your `.env.production` file is now encrypted:

```
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/ public-key encryption for .env files /
#/ [how it works](https://dotenvx.com/encryption) /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY_PRODUCTION="02f8a3b1c9..."

APP_NAME="encrypted:BHx7kQ..."
APP_ENV="encrypted:BLm9pR..."
DB_PASSWORD="encrypted:BGt5vX..."
STRIPE_SECRET="encrypted:BKw2mN..."
# ... all values encrypted
```

A new `.env.keys` file is created containing your private key:

```
#/------------------!DOTENV_PRIVATE_KEYS!-------------------/
#/ private decryption keys. DO NOT commit to source control /
#/----------------------------------------------------------/

# .env.production
DOTENV_PRIVATE_KEY_PRODUCTION="8f4e2a1b9c7d6e5f..."
```

## Step 4: Secure Your Keys

**Critical:** Add `.env.keys` to your `.gitignore`:

```
echo ".env.keys" >> .gitignore
```

Copy the `DOTENV_PRIVATE_KEY_PRODUCTION` value — you'll need it for [DeployHQ](https://www.deployhq.com).

## Step 5: Commit the Encrypted File

Now you can safely commit your encrypted environment file:

```
git add .env.production .gitignore
git commit -m "Add encrypted production environment configuration"
git push
```

## Step 6: Install Dotenvx on Your Server

Connect to your production server via SSH and install dotenvx:

```
ssh user@your-server.com

# Install dotenvx
curl -sfS https://dotenvx.sh/install.sh | sh

# Verify it's in PATH
dotenvx --version
```

If you need it globally available:

```
sudo mv ~/.dotenvx/bin/dotenvx /usr/local/bin/
```

## Step 7: Configure DeployHQ Environment Variables

In your [DeployHQ](https://www.deployhq.com) project:

1. Go to **Project Settings** → **Environment Variables**
2. Click **New Environment Variable**
3. Add the following:

Name

Value

`DOTENV_PRIVATE_KEY_PRODUCTION`

`8f4e2a1b9c7d6e5f...` (your key from `.env.keys`)

Make sure to mark it as **Secret** so it's masked in logs.

## Step 8: Configure Deployment Commands

Now we need to tell [DeployHQ](https://www.deployhq.com) to decrypt the environment file after deploying your code.

### Option A: Decrypt to a File (Recommended for PHP)

This approach creates a decrypted `.env` file that PHP can read natively.

Go to **Project Settings** → **SSH Commands** → **After deployment**

Add this command:

```
cd %path% && dotenvx decrypt -f .env.production -o .env
```

This decrypts `.env.production` and outputs it as `.env` in your application root.

**For Laravel applications** , you're done — Laravel's `vlucas/phpdotenv` will read the `.env` file automatically.

### Option B: Runtime Decryption (Process Wrapper)

If you prefer to decrypt at runtime (not write a plaintext file), modify your process manager configuration.

For example, with **Supervisor** :

```
[program:myapp]
command=/usr/local/bin/dotenvx run -f /var/www/myapp/.env.production -- php /var/www/myapp/artisan queue:work
directory=/var/www/myapp
user=www-data
environment=DOTENV_PRIVATE_KEY_PRODUCTION="your-key-here"
autostart=true
autorestart=true
```

For **systemd** :

```
[Service]
Environment="DOTENV_PRIVATE_KEY_PRODUCTION=your-key-here"
ExecStart=/usr/local/bin/dotenvx run -f /var/www/myapp/.env.production -- php-fpm
```

## Step 9: Full Deployment Script Example

Here's a complete SSH command sequence for a Laravel deployment:

**SSH Commands → After deployment:**

```
# Navigate to deployment path
cd %path%

# Decrypt environment file
dotenvx decrypt -f .env.production -o .env

# Install/update dependencies
composer install --no-dev --optimize-autoloader

# Run migrations
php artisan migrate --force

# Clear and rebuild caches
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Restart queue workers (if using Supervisor)
sudo supervisorctl restart myapp-worker:*
```

## Step 10: Test Your Deployment

Trigger a deployment in [DeployHQ](https://www.deployhq.com) and verify:

1. Check the deployment logs — you should see dotenvx decrypt running
2. SSH into your server and confirm `.env` exists with decrypted values
3. Verify your application loads correctly

```
# On your server
cat /var/www/myapp/.env | head -5
# Should show decrypted values like:
# APP_NAME="My PHP App"
# APP_ENV=production
```

* * *

## Handling Multiple Environments

If you deploy to staging and production through [DeployHQ](https://www.deployhq.com), create separate encrypted files:

```
# Encrypt each environment
dotenvx encrypt -f .env.staging
dotenvx encrypt -f .env.production
```

In [DeployHQ](https://www.deployhq.com), create separate servers/environments with their respective keys:

**Staging Server Environment Variables:**

`DOTENV_PRIVATE_KEY_STAGING` = `...`

**Production Server Environment Variables:**

`DOTENV_PRIVATE_KEY_PRODUCTION` = `...`

Adjust your SSH commands accordingly:

```
# For staging
cd %path% && dotenvx decrypt -f .env.staging -o .env

# For production  
cd %path% && dotenvx decrypt -f .env.production -o .env
```

* * *

## Updating Secrets

When you need to update a secret:

```
# Update a single value (re-encrypts automatically)
dotenvx set DB_PASSWORD "new_password_here" -f .env.production

# Or edit and re-encrypt the entire file
dotenvx decrypt -f .env.production -o .env.production.tmp
# Edit .env.production.tmp
dotenvx encrypt -f .env.production.tmp
mv .env.production.tmp .env.production
```

Commit and deploy:

```
git add .env.production
git commit -m "Update database credentials"
git push
```

[DeployHQ](https://www.deployhq.com) will deploy the updated encrypted file and decrypt it on the server.

* * *

## Troubleshooting

### dotenvx: command not found

Ensure dotenvx is installed and in your PATH on the server:

```
which dotenvx
# Should return: /usr/local/bin/dotenvx or similar
```

If not found, reinstall or add to PATH in your SSH commands:

```
export PATH="$HOME/.dotenvx/bin:$PATH" && cd %path% && dotenvx decrypt -f .env.production -o .env
```

### Missing private key

Verify the environment variable is set in DeployHQ:

- Check **Project Settings** → **Environment Variables**
- Ensure the variable name matches exactly: `DOTENV_PRIVATE_KEY_PRODUCTION`

### Decryption fails

Ensure the encrypted file matches the key:

- Each encrypted file has a corresponding private key
- The key suffix must match: `DOTENV_PRIVATE_KEY_PRODUCTION` decrypts `.env.production`

* * *

## Security Best Practices

1. **Rotate keys periodically** — Especially when team members leave
2. **Use separate keys per environment** — Never share production keys with staging
3. **Limit server access** — Only those who need production access should have the private key
4. **Audit your `.env.keys`** — Keep it in a secure password manager
5. **Review before committing** — Always verify you're committing encrypted values, not plaintext

* * *

## Conclusion

Dotenvx transforms how we handle secrets in deployments. Instead of juggling separate secrets management tools or copying `.env` files manually, you get:

- **Version-controlled secrets** — Track changes, review diffs, rollback if needed
- **Encrypted at rest** — Safe to commit, even to public repositories
- **Simple key management** — One private key per environment, stored in [DeployHQ](https://www.deployhq.com)
- **Seamless integration** — Works with any PHP framework, no code changes required

Combined with DeployHQ's automated deployment pipeline, you get a secure, auditable, and developer-friendly workflow for managing production secrets.

* * *

Ready to secure your deployments? [Create a free](https://www.deployhq.com/)[DeployHQ](https://www.deployhq.com) account and follow this guide to get started.

