Skip to content

Commit c05a983

Browse files
roberteinsleclaude
andauthored
Add automated deployment via GitHub Actions
- Add GitHub Actions workflow for automated deployment on push to main - Create deploy.sh script for production server deployment - Update CLAUDE.md with comprehensive CI/CD documentation - Add DEPLOYMENT_SETUP.md with step-by-step setup instructions - Configure .github directory in Claude workspace Deployment flow: Codespaces → git push → GitHub Actions → Hetzner VM Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 36af9cc commit c05a983

5 files changed

Lines changed: 611 additions & 5 deletions

File tree

.claude/settings.local.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@
7474
"Read(//tmp/**)",
7575
"Bash(md5sum:*)",
7676
"Bash(xargs awk:*)"
77+
],
78+
"additionalDirectories": [
79+
"/workspaces/leafmark/.github"
7780
]
7881
}
7982
}

.github/workflows/deploy.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Deploy to Production
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
deploy:
10+
name: Deploy to Hetzner VM
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Deploy to Production Server
15+
uses: appleboy/ssh-action@v1.0.3
16+
with:
17+
host: ${{ secrets.PROD_HOST }}
18+
username: ${{ secrets.PROD_USER }}
19+
key: ${{ secrets.PROD_SSH_KEY }}
20+
port: ${{ secrets.PROD_SSH_PORT }}
21+
script: |
22+
cd /opt/leafmark
23+
bash deploy.sh

CLAUDE.md

Lines changed: 200 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,19 +432,200 @@ The Docker entrypoint ([docker-entrypoint.sh](docker-entrypoint.sh)) automatical
432432
- `storage_data` - Uploaded book covers
433433
- `vendor` - Composer dependencies
434434

435+
## CI/CD & Automated Deployment
436+
437+
The application uses **GitHub Actions** for automated deployment to production when code is pushed to the `main` branch.
438+
439+
### Deployment Workflow
440+
441+
**Development → Production Flow:**
442+
1. Development happens in **GitHub Codespaces** (https://silver-space-orbit-xx4x79vwgpcvpp.github.dev/)
443+
2. Developer manually commits and pushes changes to GitHub (`git push`)
444+
3. GitHub Actions automatically triggers deployment
445+
4. Production server pulls latest code and restarts containers
446+
447+
**Automated Deployment Process:**
448+
- Triggered on: `git push` to `main` branch
449+
- GitHub Actions workflow: [.github/workflows/deploy.yml](.github/workflows/deploy.yml)
450+
- Deployment script: [deploy.sh](deploy.sh) (runs on production server)
451+
- No manual intervention required after push
452+
453+
### Production Server Details
454+
455+
**Server Environment:**
456+
- Provider: Hetzner VM
457+
- User: `deploy`
458+
- Application directory: `/opt/leafmark`
459+
- Git repository: Cloned from `https://github.com/roberteinsle/leafmark.git`
460+
461+
**Directory Structure:**
462+
```
463+
/opt/leafmark/
464+
├── docker-compose.yaml # Docker configuration
465+
├── Dockerfile # App container build instructions
466+
├── deploy.sh # Deployment script (executable)
467+
└── [Laravel application files...]
468+
```
469+
470+
### Initial Production Setup
471+
472+
**Prerequisites on Hetzner VM:**
473+
```bash
474+
# Install Docker and Docker Compose
475+
curl -fsSL https://get.docker.com -o get-docker.sh
476+
sudo sh get-docker.sh
477+
sudo usermod -aG docker deploy
478+
479+
# Install Git
480+
sudo apt update
481+
sudo apt install -y git
482+
```
483+
484+
**Setup deployment user and repository:**
485+
```bash
486+
# Login as deploy user
487+
sudo su - deploy
488+
489+
# Create application directory
490+
sudo mkdir -p /opt/leafmark
491+
sudo chown deploy:deploy /opt/leafmark
492+
cd /opt/leafmark
493+
494+
# Clone repository
495+
git clone https://github.com/roberteinsle/leafmark.git .
496+
497+
# Make deployment script executable
498+
chmod +x deploy.sh
499+
500+
# Configure environment (if not already done)
501+
# See "Initial Server Setup" section below for .env configuration
502+
```
503+
504+
**Setup GitHub Actions SSH Access:**
505+
506+
1. Generate SSH key pair on your local machine:
507+
```bash
508+
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/leafmark_deploy
509+
```
510+
511+
2. Copy public key to production server:
512+
```bash
513+
ssh-copy-id -i ~/.ssh/leafmark_deploy.pub deploy@YOUR_SERVER_IP
514+
```
515+
516+
3. Add GitHub Secrets (GitHub Repository → Settings → Secrets and variables → Actions):
517+
- `PROD_HOST` - Production server IP address
518+
- `PROD_USER` - `deploy`
519+
- `PROD_SSH_KEY` - Contents of private key file (`cat ~/.ssh/leafmark_deploy`)
520+
- `PROD_SSH_PORT` - SSH port (usually `22`)
521+
522+
**Test SSH connection:**
523+
```bash
524+
ssh -i ~/.ssh/leafmark_deploy deploy@YOUR_SERVER_IP "cd /opt/leafmark && pwd"
525+
```
526+
527+
### Deployment Script Details
528+
529+
The [deploy.sh](deploy.sh) script performs these steps:
530+
531+
1. **Pull latest code** from GitHub (`git pull origin main`)
532+
2. **Stop containers** (`docker compose down`)
533+
3. **Rebuild containers** (`docker compose up -d --build`)
534+
4. **Wait for startup** (10 seconds)
535+
5. **Run migrations** (`php artisan migrate --force`)
536+
6. **Clear caches** (`config:cache`, `route:cache`, `view:cache`)
537+
7. **Verify storage symlink** (`storage:link`)
538+
539+
**Key Features:**
540+
- Preserves Docker volumes (database and uploaded files are NOT deleted)
541+
- Automatic migration execution
542+
- Cache clearing for updated routes/config
543+
- Logs deployment timestamp and status
544+
545+
### Manual Deployment
546+
547+
If you need to deploy manually without pushing to GitHub:
548+
549+
```bash
550+
# SSH into production server
551+
ssh deploy@YOUR_SERVER_IP
552+
553+
# Navigate to application directory
554+
cd /opt/leafmark
555+
556+
# Run deployment script
557+
bash deploy.sh
558+
```
559+
560+
### Deployment Monitoring
561+
562+
**View deployment logs in GitHub:**
563+
1. Go to repository → Actions tab
564+
2. Select the latest workflow run
565+
3. View deployment logs and status
566+
567+
**View application logs on server:**
568+
```bash
569+
# SSH into server
570+
ssh deploy@YOUR_SERVER_IP
571+
572+
# View Docker container logs
573+
cd /opt/leafmark
574+
docker compose logs -f app
575+
```
576+
577+
### Rollback Procedure
578+
579+
If deployment fails and you need to rollback:
580+
581+
```bash
582+
# SSH into production server
583+
ssh deploy@YOUR_SERVER_IP
584+
cd /opt/leafmark
585+
586+
# Check git log for previous commit
587+
git log --oneline -n 5
588+
589+
# Rollback to previous commit (replace COMMIT_HASH)
590+
git reset --hard COMMIT_HASH
591+
592+
# Re-run deployment script
593+
bash deploy.sh
594+
```
595+
596+
**⚠️ WARNING:** Rolling back code does NOT rollback database migrations. If new migrations were run, you may need to manually rollback migrations:
597+
```bash
598+
docker compose exec app php artisan migrate:rollback
599+
```
600+
435601
## Production Deployment
436602

603+
**Note:** This section describes manual production setup. For automated deployment via GitHub Actions, see [CI/CD & Automated Deployment](#cicd--automated-deployment).
604+
605+
**Production Server:**
606+
- Server: Hetzner VM
607+
- User: `deploy`
608+
- Location: `/opt/leafmark`
609+
- Automated deployment: Enabled via GitHub Actions
610+
437611
### Initial Server Setup
438612

439613
```bash
614+
# Login as deploy user
615+
sudo su - deploy
616+
440617
# Create directory and clone repository
441-
cd ~/leafmark
442-
git clone https://github.com/roberteinsle/leafmark.git app-source
443-
cd app-source
618+
sudo mkdir -p /opt/leafmark
619+
sudo chown deploy:deploy /opt/leafmark
620+
cd /opt/leafmark
621+
git clone https://github.com/roberteinsle/leafmark.git .
444622

445623
# Create and configure .env
446624
cp .env.example .env
447625
nano .env
626+
627+
# Make deployment script executable
628+
chmod +x deploy.sh
448629
```
449630

450631
**Environment variables are set via docker-compose.yaml:**
@@ -506,10 +687,24 @@ Then configure registration settings:
506687

507688
### Update Workflow
508689

509-
To update the application:
690+
**⚠️ IMPORTANT:** Updates are now **automated via GitHub Actions**. Simply push to `main` branch and deployment happens automatically.
510691

692+
**Automated deployment** (recommended):
693+
1. Push changes to GitHub: `git push origin main`
694+
2. GitHub Actions automatically deploys to production
695+
3. No manual intervention required
696+
697+
**Manual deployment** (if needed):
511698
```bash
512-
cd ~/leafmark/app-source
699+
cd /opt/leafmark
700+
701+
# Run deployment script (does everything automatically)
702+
bash deploy.sh
703+
```
704+
705+
**Manual step-by-step** (for troubleshooting only):
706+
```bash
707+
cd /opt/leafmark
513708

514709
# Pull latest code from GitHub
515710
git pull origin main

0 commit comments

Comments
 (0)