Skip to content

Repository files navigation

Book Review Backend

A production-grade REST API built with Go, deployed on AWS EC2 with full CI/CD automation.

Tech Stack

Layer Technology
Language Go 1.26
Router Chi
Database PostgreSQL (NeonDB — serverless managed)
ORM / Query SQLC (type-safe generated queries)
Migrations Goose
Container Docker (multi-stage build)
Reverse Proxy Nginx
Cloud AWS EC2 (t3.micro, eu-west-1)
DNS / CDN / DDoS Cloudflare
SSL Cloudflare Origin Certificate (Full Strict)
CI/CD GitHub Actions

Architecture

Client (Browser / Mobile)
        │
        ▼
  Cloudflare Edge
  (DDoS protection, CDN, SSL termination)
        │
        ▼ HTTPS (Cloudflare Origin Cert)
  AWS EC2 — t3.micro (eu-west-1)
  ┌─────────────────────────────┐
  │  Nginx (reverse proxy)      │
  │  Port 80 → redirect HTTPS   │
  │  Port 443 → proxy to :8080  │
  │         │                   │
  │         ▼                   │
  │  Docker Container           │
  │  Go binary → port 8080      │
  └─────────────────────────────┘
        │
        ▼
  NeonDB (Serverless PostgreSQL)
  (managed, external, connection via DATABASE_URL)

CI/CD Pipeline

Every push to main triggers an automated deployment via GitHub Actions.

Developer pushes to main
        │
        ▼
GitHub Actions Runner (ubuntu-latest)
        │
        ├── Checkout code
        │
        └── SSH into EC2
              │
              ├── git fetch + reset --hard (sync with GitHub)
              ├── docker build (multi-stage, compiles Go binary)
              ├── docker stop + rm (remove old container)
              ├── docker run (start new container)
              ├── curl /health (verify deployment succeeded)
              └── docker image prune (clean up old images)

Workflow file: .github/workflows/deploy.yml


Docker — Multi-Stage Build

The Dockerfile uses a two-stage build to keep the final image small (~15MB vs ~400MB):

Stage 1 (builder)         Stage 2 (runtime)
─────────────────         ─────────────────
golang:1.26-alpine   →    alpine:3.21
Full Go toolchain         Compiled binary only
Source code               ca-certificates
go mod download           migrations/
go build                  ~15MB total
~400MB

Benefits:

  • Smaller attack surface in production
  • Faster image pulls
  • No source code or build tools in production image

Infrastructure

Resource Details
Cloud Provider AWS (eu-west-1 — Ireland)
Instance Type t3.micro (1 vCPU, 1GB RAM)
OS Ubuntu 24.04 LTS
Elastic IP Static public IP (survives instance stop/start)
Storage 20GB gp3 EBS
Security Group Ports 22, 80, 443 open

Cloudflare Setup

  • Proxy: ON (orange cloud) — real server IP is hidden
  • SSL Mode: Full Strict — HTTPS encrypted end to end
  • Certificate: Cloudflare Origin Certificate (15 year validity)
  • Bot Fight Mode: OFF (API endpoints — JS challenges break API clients)

Local Development

# Clone the repo
git clone https://github.com/pixprocoder/book-review-backend.git
cd book-review-backend

# Copy environment variables
cp .env.example .env
# Fill in your DATABASE_URL and other vars

# Run in development mode (hot reload)
make dev

# Run tests
make test

# Run linter
make lint

Database Migrations

# Apply migrations
make migrate-up

# Rollback last migration
make migrate-down

# Create new migration
make migrate-create

Deployment

Deployments are fully automated via GitHub Actions on push to main.

For manual deployment or first-time server setup:

# SSH into server
ssh -i your-key.pem devops@<EC2_IP>

# Navigate to app
cd /opt/apps/book-review-backend

# Pull latest code
git fetch origin main && git reset --hard origin/main

# Build and restart container
docker build -t book-review-backend:latest .
docker stop book-review && docker rm book-review
docker run -d \
  --name book-review \
  --restart unless-stopped \
  -p 8080:8080 \
  --env-file /opt/apps/book-review-backend/.env \
  book-review-backend:latest

Running Migrations on Server

Migrations are NOT run automatically on deploy. Run manually when schema changes:

ssh -i your-key.pem devops@<EC2_IP>
cd /opt/apps/book-review-backend
make migrate-up

API Endpoints

Base URL: https://book-review.pixprocoder.com

Method Endpoint Description
GET /health Health check
... /api/v1/... Application routes

Environment Variables

DATABASE_URL=postgres://...    # NeonDB connection string
# add other required vars from .env.example

GitHub Actions Secrets Required

Secret Value
EC2_HOST EC2 Elastic IP
EC2_USER devops
EC2_SSH_KEY Contents of your .pem private key

Releases

Packages

Used by

Contributors

Languages