|
| 1 | +# GitHub Actions SSH Setup for Staging Deployment |
| 2 | + |
| 3 | +This document describes how to configure SSH access for GitHub Actions to deploy to the staging server. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +- Access to the staging server |
| 8 | +- GitHub repository admin access (to add secrets) |
| 9 | +- SSH client installed locally |
| 10 | + |
| 11 | +## Step 1: Generate SSH Key Pair |
| 12 | + |
| 13 | +On your local machine or the staging server: |
| 14 | + |
| 15 | +```bash |
| 16 | +# Generate ED25519 key (more secure than RSA) |
| 17 | +ssh-keygen -t ed25519 -f ~/.ssh/github_actions_staging -C "github-actions-staging" |
| 18 | + |
| 19 | +# Leave passphrase empty when prompted (GitHub Actions can't enter passphrases) |
| 20 | +``` |
| 21 | + |
| 22 | +This creates two files: |
| 23 | +- `~/.ssh/github_actions_staging` (private key) - for GitHub Secrets |
| 24 | +- `~/.ssh/github_actions_staging.pub` (public key) - for staging server |
| 25 | + |
| 26 | +## Step 2: Add Public Key to Staging Server |
| 27 | + |
| 28 | +Copy the public key to the staging server's authorized_keys: |
| 29 | + |
| 30 | +```bash |
| 31 | +# Option 1: Using ssh-copy-id (easiest) |
| 32 | +ssh-copy-id -i ~/.ssh/github_actions_staging.pub your-user@staging-server |
| 33 | + |
| 34 | +# Option 2: Manual copy |
| 35 | +cat ~/.ssh/github_actions_staging.pub | ssh your-user@staging-server 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys' |
| 36 | + |
| 37 | +# Option 3: Manual (if you have direct access to server) |
| 38 | +# On staging server: |
| 39 | +mkdir -p ~/.ssh |
| 40 | +chmod 700 ~/.ssh |
| 41 | +# Then paste contents of github_actions_staging.pub into ~/.ssh/authorized_keys |
| 42 | +chmod 600 ~/.ssh/authorized_keys |
| 43 | +``` |
| 44 | + |
| 45 | +## Step 3: Test SSH Connection |
| 46 | + |
| 47 | +Verify the key works: |
| 48 | + |
| 49 | +```bash |
| 50 | +ssh -i ~/.ssh/github_actions_staging your-user@staging-server 'echo "Connection successful"' |
| 51 | +``` |
| 52 | + |
| 53 | +Expected output: "Connection successful" |
| 54 | + |
| 55 | +## Step 4: Add Secrets to GitHub Repository |
| 56 | + |
| 57 | +1. Go to your repository on GitHub |
| 58 | +2. Navigate to: **Settings** → **Secrets and variables** → **Actions** |
| 59 | +3. Click **New repository secret** |
| 60 | +4. Add the following secrets: |
| 61 | + |
| 62 | +### STAGING_SSH_KEY |
| 63 | + |
| 64 | +- Name: `STAGING_SSH_KEY` |
| 65 | +- Value: Contents of `~/.ssh/github_actions_staging` (private key) |
| 66 | + |
| 67 | +```bash |
| 68 | +# Copy private key to clipboard |
| 69 | +cat ~/.ssh/github_actions_staging |
| 70 | +# Copy the entire output including BEGIN and END lines |
| 71 | +``` |
| 72 | + |
| 73 | +### STAGING_HOST |
| 74 | + |
| 75 | +- Name: `STAGING_HOST` |
| 76 | +- Value: Staging server hostname or IP address |
| 77 | +- Example: `staging.example.com` or `192.168.1.100` |
| 78 | + |
| 79 | +### STAGING_USER |
| 80 | + |
| 81 | +- Name: `STAGING_USER` |
| 82 | +- Value: SSH username on staging server |
| 83 | +- Example: `frankbria` |
| 84 | + |
| 85 | +### STAGING_PROJECT_PATH |
| 86 | + |
| 87 | +- Name: `STAGING_PROJECT_PATH` |
| 88 | +- Value: Absolute path to the CodeFRAME project on staging server |
| 89 | +- Example: `/home/frankbria/projects/codeframe` |
| 90 | + |
| 91 | +## Step 5: Verify Secrets |
| 92 | + |
| 93 | +After adding all secrets, verify they appear in the secrets list: |
| 94 | + |
| 95 | +- STAGING_SSH_KEY |
| 96 | +- STAGING_HOST |
| 97 | +- STAGING_USER |
| 98 | +- STAGING_PROJECT_PATH |
| 99 | + |
| 100 | +## Step 6: Test Deployment Workflow |
| 101 | + |
| 102 | +1. Push a commit to the `staging` or `development` branch |
| 103 | +2. Go to **Actions** tab in GitHub repository |
| 104 | +3. Watch the "Deploy to Staging" workflow run |
| 105 | +4. Verify all steps complete successfully |
| 106 | + |
| 107 | +## Security Notes |
| 108 | + |
| 109 | +### Private Key Security |
| 110 | +- **Never commit the private key to the repository** |
| 111 | +- Keep `~/.ssh/github_actions_staging` secure on your local machine |
| 112 | +- Consider deleting the local copy after adding to GitHub Secrets |
| 113 | + |
| 114 | +### Key Rotation |
| 115 | +- Rotate SSH keys every 90 days |
| 116 | +- To rotate: |
| 117 | + 1. Generate new key pair |
| 118 | + 2. Add new public key to staging server |
| 119 | + 3. Update `STAGING_SSH_KEY` secret in GitHub |
| 120 | + 4. Remove old public key from staging server |
| 121 | + 5. Delete old private key locally |
| 122 | + |
| 123 | +### Access Control |
| 124 | +- Only grant repository admin access to trusted users |
| 125 | +- Consider using a dedicated deployment user on staging server |
| 126 | +- Audit secret access logs regularly |
| 127 | + |
| 128 | +## Troubleshooting |
| 129 | + |
| 130 | +### "Permission denied (publickey)" |
| 131 | +- Verify public key is in `~/.ssh/authorized_keys` on staging server |
| 132 | +- Check file permissions: `authorized_keys` should be 600, `.ssh` should be 700 |
| 133 | +- Verify `STAGING_SSH_KEY` secret contains the complete private key |
| 134 | + |
| 135 | +### "Host key verification failed" |
| 136 | +- Workflow includes `ssh-keyscan` to add host key automatically |
| 137 | +- If issue persists, manually add host key to workflow |
| 138 | + |
| 139 | +### "Connection refused" |
| 140 | +- Verify `STAGING_HOST` is correct |
| 141 | +- Ensure staging server is accessible from internet |
| 142 | +- Check firewall settings allow SSH (port 22) |
| 143 | + |
| 144 | +### "No such file or directory" during deployment |
| 145 | +- Verify `STAGING_PROJECT_PATH` is correct |
| 146 | +- Ensure project directory exists on staging server |
| 147 | +- Check user has read/write permissions to project directory |
| 148 | + |
| 149 | +## Additional Resources |
| 150 | + |
| 151 | +- [GitHub Actions SSH documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-cloud-providers) |
| 152 | +- [SSH key generation guide](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) |
| 153 | +- [PM2 deployment documentation](https://pm2.keymetrics.io/docs/usage/deployment/) |
0 commit comments