13 KiB
Gitea Secrets Configuration Guide
Purpose: Step-by-step guide to configure all required secrets for staging and production deployments.
Prerequisites:
- Admin access to Gitea repository
- SSH access to staging and production servers
- OpenSSH installed locally
Quick Start Checklist
- Generate SSH key pair
- Distribute public key to target servers
- Configure staging secrets in Gitea
- Configure production secrets in Gitea
- Test SSH connection manually
- Verify secrets are accessible to workflows
Step 1: Generate SSH Keys
Option A: Generate New Deployment Keys (Recommended)
# Navigate to project root
cd /home/michael/dev/michaelschiemer
# Create SSH keys directory
mkdir -p .gitea/ssh-keys
cd .gitea/ssh-keys
# Generate staging key
ssh-keygen -t rsa -b 4096 -f gitea-staging-deploy \
-C "gitea-staging-deployment" -N ""
# Generate production key
ssh-keygen -t rsa -b 4096 -f gitea-production-deploy \
-C "gitea-production-deployment" -N ""
# Verify keys created
ls -la
# Expected output:
# gitea-staging-deploy (private key)
# gitea-staging-deploy.pub (public key)
# gitea-production-deploy (private key)
# gitea-production-deploy.pub (public key)
⚠️ Security Note:
- Private keys should NEVER be committed to git
- Add
.gitea/ssh-keys/to.gitignoreif not already present - Store private keys securely (e.g., password manager, Vault)
Step 2: Distribute Public Keys to Servers
Staging Server Setup
# Copy public key to staging server
ssh-copy-id -i .gitea/ssh-keys/gitea-staging-deploy.pub deploy@YOUR_STAGING_HOST
# Or manually (if ssh-copy-id not available):
cat .gitea/ssh-keys/gitea-staging-deploy.pub | \
ssh deploy@YOUR_STAGING_HOST "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Set proper permissions on server
ssh deploy@YOUR_STAGING_HOST "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
# Test connection
ssh -i .gitea/ssh-keys/gitea-staging-deploy deploy@YOUR_STAGING_HOST "echo 'Staging SSH connection successful'"
Production Server Setup
# Copy public key to production server
ssh-copy-id -i .gitea/ssh-keys/gitea-production-deploy.pub deploy@YOUR_PRODUCTION_HOST
# Or manually:
cat .gitea/ssh-keys/gitea-production-deploy.pub | \
ssh deploy@YOUR_PRODUCTION_HOST "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Set proper permissions
ssh deploy@YOUR_PRODUCTION_HOST "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
# Test connection
ssh -i .gitea/ssh-keys/gitea-production-deploy deploy@YOUR_PRODUCTION_HOST "echo 'Production SSH connection successful'"
Deployment User Requirements:
- User must exist on target server (e.g.,
deploy,www-data,ubuntu) - User must have sudo privileges for Docker commands
- User must have write access to deployment directories:
- Staging:
/opt/framework-staging/ - Production:
/opt/framework-production/
- Staging:
Step 3: Prepare Secret Values
Extract Private Key Content
cd /home/michael/dev/michaelschiemer/.gitea/ssh-keys
# Display staging private key (copy entire output)
echo "=== STAGING_SSH_KEY ==="
cat gitea-staging-deploy
echo ""
# Display production private key (copy entire output)
echo "=== PRODUCTION_SSH_KEY ==="
cat gitea-production-deploy
echo ""
Important: Copy the entire key content including:
-----BEGIN RSA PRIVATE KEY-----
[key content here]
-----END RSA PRIVATE KEY-----
Determine Server Details
Staging Server:
# Get staging hostname/IP (replace with your actual server)
STAGING_HOST="staging.michaelschiemer.de" # or IP: 203.0.113.42
# Get SSH port (default: 22)
STAGING_SSH_PORT="22"
# Get deployment user
STAGING_USER="deploy"
Production Server:
# Get production hostname/IP
PRODUCTION_HOST="michaelschiemer.de" # or IP: 198.51.100.10
# Get SSH port (default: 22)
PRODUCTION_SSH_PORT="22"
# Get deployment user
PRODUCTION_USER="deploy"
Step 4: Configure Secrets in Gitea
Access Gitea Secrets Configuration
-
Navigate to Repository:
- Open Gitea web interface
- Go to your framework repository
-
Access Secrets Settings:
- Click
Settings(⚙️ icon) - Click
Secretsin left sidebar - Or direct URL:
https://git.michaelschiemer.de/michael/framework/settings/secrets
- Click
-
Add New Secret:
- Click
Add Secretbutton - Fill in
NameandValuefields - Click
Add Secretto save
- Click
Staging Secrets Configuration
Secret 1: STAGING_HOST
- Name:
STAGING_HOST - Value:
staging.michaelschiemer.de(or your staging server hostname/IP) - Description: Staging server hostname or IP address
Secret 2: STAGING_USER
- Name:
STAGING_USER - Value:
deploy(or your deployment user) - Description: SSH username for staging deployments
Secret 3: STAGING_SSH_KEY
- Name:
STAGING_SSH_KEY - Value: [Paste entire content of
gitea-staging-deployprivate key] - Description: Private SSH key for staging authentication
- ⚠️ Important: Include
-----BEGIN RSA PRIVATE KEY-----and-----END RSA PRIVATE KEY-----lines
Secret 4: STAGING_SSH_PORT
- Name:
STAGING_SSH_PORT - Value:
22(or your custom SSH port) - Description: SSH port for staging server (optional, defaults to 22)
Production Secrets Configuration
Secret 5: PRODUCTION_HOST
- Name:
PRODUCTION_HOST - Value:
michaelschiemer.de(or your production server hostname/IP) - Description: Production server hostname or IP address
Secret 6: PRODUCTION_USER
- Name:
PRODUCTION_USER - Value:
deploy(or your deployment user) - Description: SSH username for production deployments
Secret 7: PRODUCTION_SSH_KEY
- Name:
PRODUCTION_SSH_KEY - Value: [Paste entire content of
gitea-production-deployprivate key] - Description: Private SSH key for production authentication
- ⚠️ Important: Include
-----BEGIN RSA PRIVATE KEY-----and-----END RSA PRIVATE KEY-----lines
Secret 8: PRODUCTION_SSH_PORT
- Name:
PRODUCTION_SSH_PORT - Value:
22(or your custom SSH port) - Description: SSH port for production server (optional, defaults to 22)
Step 5: Verify Secrets Configuration
Via Gitea UI
-
Navigate to
Settings→Secrets -
Verify all 8 secrets are listed:
- ✅ STAGING_HOST
- ✅ STAGING_USER
- ✅ STAGING_SSH_KEY
- ✅ STAGING_SSH_PORT
- ✅ PRODUCTION_HOST
- ✅ PRODUCTION_USER
- ✅ PRODUCTION_SSH_KEY
- ✅ PRODUCTION_SSH_PORT
-
Check that secrets show "Last Updated" timestamp
Note: Secret values are masked in the UI for security (you cannot view them after saving).
Manual SSH Connection Test
Test SSH connections using the same credentials that workflows will use:
cd /home/michael/dev/michaelschiemer/.gitea/ssh-keys
# Test staging connection
ssh -i gitea-staging-deploy deploy@YOUR_STAGING_HOST \
"echo 'Staging SSH test successful'; docker --version"
# Test production connection
ssh -i gitea-production-deploy deploy@YOUR_PRODUCTION_HOST \
"echo 'Production SSH test successful'; docker --version"
Expected Output:
Staging SSH test successful
Docker version 24.0.7, build afdd53b
If Connection Fails:
- Verify hostname/IP is correct
- Check SSH port (try specifying:
ssh -p 2222 ...) - Verify public key is in
~/.ssh/authorized_keyson server - Check server firewall allows SSH connections
- Verify user has Docker permissions:
ssh user@host "docker ps"
Step 6: Test Workflow Access to Secrets
Trigger Test Workflow
Create a minimal test workflow to verify secrets are accessible:
File: .gitea/workflows/test-secrets.yml
name: Test Secrets Configuration
on:
workflow_dispatch:
jobs:
test-secrets:
runs-on: ubuntu-latest
steps:
- name: Test staging secrets
run: |
echo "Testing staging secrets..."
echo "STAGING_HOST: ${{ secrets.STAGING_HOST }}"
echo "STAGING_USER: ${{ secrets.STAGING_USER }}"
echo "STAGING_SSH_PORT: ${{ secrets.STAGING_SSH_PORT }}"
echo "STAGING_SSH_KEY length: ${#STAGING_SSH_KEY}"
env:
STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
- name: Test production secrets
run: |
echo "Testing production secrets..."
echo "PRODUCTION_HOST: ${{ secrets.PRODUCTION_HOST }}"
echo "PRODUCTION_USER: ${{ secrets.PRODUCTION_USER }}"
echo "PRODUCTION_SSH_PORT: ${{ secrets.PRODUCTION_SSH_PORT }}"
echo "PRODUCTION_SSH_KEY length: ${#PRODUCTION_SSH_KEY}"
env:
PRODUCTION_SSH_KEY: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: Test SSH connection to staging
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.STAGING_USER }}
key: ${{ secrets.STAGING_SSH_KEY }}
port: ${{ secrets.STAGING_SSH_PORT || 22 }}
script: |
echo "Staging SSH connection successful"
docker --version
docker-compose --version
- name: Test SSH connection to production
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PRODUCTION_HOST }}
username: ${{ secrets.PRODUCTION_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
port: ${{ secrets.PRODUCTION_SSH_PORT || 22 }}
script: |
echo "Production SSH connection successful"
docker --version
docker-compose --version
Run Test:
- Commit and push test workflow:
git add .gitea/workflows/test-secrets.yml && git commit -m "Add secrets test workflow" && git push - Go to Gitea Actions tab
- Select "Test Secrets Configuration" workflow
- Click "Run workflow"
- Monitor execution logs
Expected Result:
- All secrets should be accessible
- SSH connections should succeed
- Docker/docker-compose versions should be displayed
Security Best Practices
SSH Key Management
✅ Do:
- Use 4096-bit RSA keys (or Ed25519)
- Generate separate keys for staging and production
- Rotate keys quarterly
- Store private keys in secure password manager
- Use dedicated deployment user (not root)
- Restrict deployment user permissions
❌ Don't:
- Commit private keys to git
- Share keys between environments
- Use personal SSH keys for deployments
- Store keys in plain text files
- Reuse keys across projects
Secret Rotation Schedule
Quarterly (Every 3 Months):
- Generate new SSH key pairs
- Add new public keys to servers (keep old keys active)
- Update Gitea secrets with new private keys
- Test deployments with new keys
- Remove old public keys from servers
- Delete old private keys securely
Template for Rotation:
# Generate new keys with date suffix
ssh-keygen -t rsa -b 4096 -f gitea-staging-deploy-2025-04 \
-C "gitea-staging-deployment-2025-04" -N ""
# Repeat process from Step 2 onwards
Access Control
Gitea Repository Permissions:
- Limit "Secrets" access to repository admins only
- Require 2FA for admin accounts
- Audit secret access logs regularly
Server Access Control:
- Deployment user should have minimal required permissions
- Use sudo configuration for Docker commands only
- Monitor SSH access logs
- Implement IP whitelisting if possible
Troubleshooting
Issue: Secret Not Found in Workflow
Symptoms:
- Workflow fails with "secret not found" error
- Secret value is empty in workflow logs
Solutions:
- Verify secret name matches exactly (case-sensitive)
- Check secret is created at repository level (not organization or user level)
- Ensure workflow has access to repository secrets
- Try re-creating the secret
Issue: SSH Authentication Failed
Symptoms:
- Workflow fails: "Permission denied (publickey)"
- Cannot connect to server via SSH
Solutions:
- Verify entire private key content is in secret (including BEGIN/END lines)
- Check public key is in
~/.ssh/authorized_keyson server - Verify SSH key format (PEM vs OpenSSH format)
- Check server SSH configuration allows public key authentication
- Test manual connection:
ssh -i key-file user@host
Issue: Docker Permission Denied
Symptoms:
- SSH connection succeeds but Docker commands fail
- Error: "permission denied while trying to connect to Docker daemon"
Solutions:
# Add deployment user to docker group (on server)
ssh deploy@server
sudo usermod -aG docker deploy
# Log out and back in for group changes to take effect
exit
ssh deploy@server
# Verify Docker access
docker ps
Next Steps
After secrets are configured and tested:
- ✅ Secrets configured in Gitea
- ⏳ Test staging deployment workflow
- ⏳ Test production deployment workflow
- ⏳ Update main deployment documentation
- ⏳ Set up monitoring and alerting
Continue to: Testing Deployment Workflows section in main README.md
Last Updated: 2025-01-28 Guide Version: 1.0 Security Review Date: 2025-01-28