⚡ Quick Setup - Self-Hosted Runner on EC2 (15 minutes)
Step 1: Launch EC2 Instance (5 minutes)
Via AWS Console:
-
Go to EC2 Console → Click Launch Instance
-
Configure:
Name: github-runner AMI: Ubuntu Server 22.04 LTS Instance type: t3.medium Key pair: Create new or select existing Network settings: - VPC: Same as your RDS - Subnet: Private subnet (with NAT) or Public - Auto-assign public IP: Enable (for now) Security Group: - Add rule: SSH (22) from My IP - Add rule: All traffic to 0.0.0.0/0 (outbound) ✅ Storage: 30 GB gp3 -
Click Launch Instance
-
Add Inbound Rule to RDS Security Group:
- Go to RDS → Your database → Security → Security groups
- Edit inbound rules → Add rule:
Type: PostgreSQL (or MySQL) Port: 5432 (or 3306) Source: <EC2-Security-Group-ID>
Step 2: Connect to EC2 and Install Runner (10 minutes)
SSH into your instance:
ssh -i your-key.pem ubuntu@<EC2-PUBLIC-IP>Now run this complete setup script:Copy and paste this into your EC2 terminal:
#!/bin/bash
# Quick GitHub Actions Runner Setup Script
# Run this on your EC2 instance
set -e
echo "========================================="
echo "GitHub Actions Runner Quick Setup"
echo "========================================="
# Update system
echo "📦 Updating system packages..."
sudo apt update && sudo apt upgrade -y
# Install essential tools
echo "🔧 Installing essential tools..."
sudo apt install -y curl wget git jq unzip build-essential
# Install Docker
echo "🐳 Installing Docker..."
sudo apt install -y docker.io
sudo usermod -aG docker ubuntu
sudo systemctl enable docker
sudo systemctl start docker
# Install Docker Compose
echo "📦 Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Install PostgreSQL client
echo "🐘 Installing PostgreSQL client..."
sudo apt install -y postgresql-client
# Install MySQL client
echo "🐬 Installing MySQL client..."
sudo apt install -y mysql-client
# Install AWS CLI
echo "☁️ Installing AWS CLI..."
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
rm -rf aws awscliv2.zip
# Install Node.js 20
echo "📗 Installing Node.js..."
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Install Python and pip
echo "🐍 Installing Python..."
sudo apt install -y python3 python3-pip python3-venv
# Download GitHub Actions Runner
echo "🏃 Downloading GitHub Actions Runner..."
mkdir -p ~/actions-runner && cd ~/actions-runner
# Get latest runner version
RUNNER_VERSION=$(curl -s https://api.github.com/repos/actions/runner/releases/latest | jq -r '.tag_name' | sed 's/v//')
echo "Latest runner version: $RUNNER_VERSION"
curl -o actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz -L \
"https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz"
# Extract
tar xzf ./actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
rm actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
echo ""
echo "========================================="
echo "✅ Installation Complete!"
echo "========================================="
echo ""
echo "Installed versions:"
docker --version
docker-compose --version
psql --version
mysql --version
aws --version
node --version
python3 --version
echo ""
echo "========================================="
echo "📝 NEXT STEPS:"
echo "========================================="
echo ""
echo "1. Get your GitHub runner token:"
echo " - Go to: https://github.com/YOUR_ORG/YOUR_REPO/settings/actions/runners/new"
echo " - Copy the token"
echo ""
echo "2. Configure the runner:"
echo " cd ~/actions-runner"
echo " ./config.sh --url https://github.com/YOUR_ORG/YOUR_REPO --token YOUR_TOKEN"
echo ""
echo "3. Install as a service:"
echo " sudo ./svc.sh install"
echo " sudo ./svc.sh start"
echo ""
echo "4. For Docker commands to work without sudo, logout and login again"
echo ""
echo "========================================="# Download and run the setup script
curl -sSL https://gist.githubusercontent.com/YOUR_GIST/setup-runner.sh | bashOR manually copy the script above and run:
chmod +x setup-runner.sh
./setup-runner.shStep 3: Configure Runner (2 minutes)
Get GitHub Token:
- Go to your repository on GitHub
- Settings → Actions → Runners → New self-hosted runner
- Select Linux
- Copy the token shown (starts with
A...)
Configure the runner:
cd ~/actions-runner
# Configure (replace with your values)
./config.sh \
--url https://github.com/YOUR_ORG/YOUR_REPO \
--token YOUR_COPIED_TOKEN \
--name aws-runner-1 \
--labels self-hosted,linux,x64,production,vpc \
--work _work \
--unattended
# You should see:
# ✓ Runner successfully added
# ✓ Runner connection is goodStep 4: Install as Service (1 minute)
# Install service
sudo ./svc.sh install
# Start service
sudo ./svc.sh start
# Check status
sudo ./svc.sh status
# Should show: "Active: active (running)"Enable auto-start on reboot:
sudo systemctl enable actions.runner.*.serviceStep 5: Test Database Connection (1 minute)
# Test PostgreSQL connection
PGPASSWORD='your_password' psql \
-h your-rds-host.rds.amazonaws.com \
-p 5432 \
-U your_username \
-d your_database \
-c "SELECT version();"
# If successful, you'll see PostgreSQL version infoIf connection fails:
# Check network connectivity
nc -zv your-rds-host.rds.amazonaws.com 5432
# If timeout, check:
# 1. RDS Security Group allows EC2 Security Group
# 2. EC2 is in same VPC as RDSStep 6: Quick Test Workflow
Create this in your repo:### Add Secrets to GitHub:
# .github/workflows/quick-test.yml
name: Quick Test Runner
on:
workflow_dispatch:
push:
branches: [main]
jobs:
test:
runs-on: [self-hosted, linux, production]
steps:
- name: Test runner
run: |
echo "✅ Runner working!"
echo "Runner: $RUNNER_NAME"
echo "OS: $RUNNER_OS"
hostname
- name: Test database
env:
PGPASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
psql \
-h ${{ secrets.RDS_HOST }} \
-p ${{ secrets.RDS_PORT }} \
-U ${{ secrets.DB_USER }} \
-d ${{ secrets.DB_NAME }} \
-c "SELECT 'Connected!' as status, NOW() as time;"- Go to Settings → Secrets and variables → Actions
- Add these secrets:
RDS_HOST = your-db.region.rds.amazonaws.com RDS_PORT = 5432 DB_NAME = your_database DB_USER = your_user DB_PASSWORD = your_password
Run the workflow:
- Go to Actions tab
- Click Quick Test Runner
- Click Run workflow
All-in-One Command Script
Save this as setup-runner.sh on your local machine:Use it like this:
# On your local machine
scp -i your-key.pem setup-runner.sh ubuntu@<EC2-IP>:~/
# SSH to EC2
ssh -i your-key.pem ubuntu@<EC2-IP>
# Run setup
chmod +x setup-runner.sh
./setup-runner.sh YOUR_GITHUB_TOKEN https://github.com/YOUR_ORG/YOUR_REPOSuper Quick Checklist (15 min total)
- Minute 1-5: Launch EC2 (t3.medium, Ubuntu 22.04, same VPC as RDS)
- Minute 5-6: Add RDS security group rule (allow EC2 SG)
- Minute 6-7: SSH to EC2
- Minute 7-14: Run setup script (installs everything)
- Minute 14-15: Get GitHub token, configure runner, start service
- Done! Runner shows in GitHub as "Idle"
Troubleshooting (if needed)
Runner not showing in GitHub:
# Check service status
sudo systemctl status actions.runner.*.service
# View logs
sudo journalctl -u actions.runner.*.service -f
# Restart
sudo ./svc.sh restartCan't connect to RDS:
# Test connectivity
nc -zv your-rds-host.rds.amazonaws.com 5432
# Check route
traceroute your-rds-host.rds.amazonaws.com
# Verify security groups in AWS consoleDocker permission denied:
# Logout and login again
exit
ssh -i your-key.pem ubuntu@<EC2-IP>
# Or force group reload
newgrp dockerQuick Commands Reference
# Check runner status
sudo systemctl status actions.runner.*.service
# View runner logs
sudo journalctl -u actions.runner.*.service -f
# Restart runner
cd ~/actions-runner
sudo ./svc.sh restart
# Stop runner
sudo ./svc.sh stop
# Start runner
sudo ./svc.sh start
# Remove runner
sudo ./svc.sh stop
./config.sh remove --token YOUR_TOKENWhat You Get
✅ Self-hosted runner running on EC2
✅ Direct access to RDS (no networking issues)
✅ Docker, AWS CLI, Node.js, Python installed
✅ Auto-starts on reboot
✅ Ready to run your workflows
Cost: ~$30/month for t3.medium running 24/7