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.
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 for secure, automated PHP deployments.
What We're Building
By the end of this tutorial, you'll have:
- Encrypted
.env.productionfiles committed safely to your repository - DeployHQ configured to decrypt secrets during deployment
- A PHP application (Laravel or vanilla PHP) running with secure environment variables
Prerequisites
- A PHP application with a
.envfile - A DeployHQ account with a project configured
- SSH access to your production server
- Git repository connected to DeployHQ
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.
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 project:
- Go to Project Settings → Environment Variables
- Click New Environment Variable
- 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 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 and verify:
- Check the deployment logs — you should see dotenvx decrypt running
- SSH into your server and confirm
.envexists with decrypted values - 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, create separate encrypted files:
# Encrypt each environment
dotenvx encrypt -f .env.staging
dotenvx encrypt -f .env.production
In DeployHQ, 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 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_PRODUCTIONdecrypts.env.production
Security Best Practices
- Rotate keys periodically — Especially when team members leave
- Use separate keys per environment — Never share production keys with staging
- Limit server access — Only those who need production access should have the private key
- Audit your
.env.keys— Keep it in a secure password manager - 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
- 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 DeployHQ account and follow this guide to get started.