FastAPI Book Project – Deployment Documentation

Introduction

The FastAPI Book Project is a RESTful API built using FastAPI that allows users to manage book records. This documentation covers the steps taken to fork, set up, develop, test, and deploy the project using GitHub Actions (CI/CD), Docker, and Nginx on an AWS instance.


Project Setup

1. Fork and Clone Repository

  • Fork the template repository from: hng12-devbot/fastapi-book-project
  • Clone it to your local machine: git clone https://github.com/your-username/fastapi-book-project.git cd fastapi-book-project
  • Open the project in VS Code: code .

2. Create a Virtual Environment and Install Dependencies

  • Create and activate a virtual environment: python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
  • Install dependencies: pip install -r requirements.txt

3. Create “Get a Book” Endpoint

Edit api/routes/books.py and add the following:

#get a book
@router.get("/{book_id}", response_model=Book, status_code=status.HTTP_200_OK)
async def get_book(book_id: int) -> Book:
    book = db.get_book(book_id)
    if not book:
        return JSONResponse(
            status_code=status.HTTP_404_NOT_FOUND, content={"detail": "Book not found"}
        )
    return book

4. Run the Server and Test API


CI/CD Pipeline Configuration

5. Add GitHub Actions for CI

Create .github/workflows/ci.yml and add:

name: CI Pipeline

on:
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
      
      - name: Set up Python
        uses: actions/setup-python@v3
        with:
          python-version: "3.9"
      
      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: Run tests
        run: pytest

6. Add GitHub Actions for CD

Create .github/workflows/cd.yml:

name: CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Docker
        run: |
          sudo apt update
          sudo apt install -y docker-ce docker-ce-cli containerd.io

      - name: Log in to Docker Hub
        run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

      - name: Build and push Docker image
        run: |
          docker build -t aiyus1/fastapi-app .
          docker push aiyus1/fastapi-app

      - name: Deploy to server
        run: |
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > private_key && chmod 600 private_key
          ssh -o StrictHostKeyChecking=no -i private_key ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} << 'EOF'
            docker pull aiyus1/fastapi-app:latest
            docker stop fastapi-app || true
            docker rm fastapi-app || true
            docker run -d -p 8000:8000 --name fastapi-app aiyus1/fastapi-app:latest
          EOF
          rm -f private_key

7. Create and Add Secrets in GitHub

Go to GitHub Settings โ†’ Secrets and Variables โ†’ Actions and add:

  • DOCKER_USERNAME: Your DockerHub username
  • DOCKER_PASSWORD: Your DockerHub password
  • SERVER_IP: Your instance IP
  • SERVER_USER: ubuntu
  • SSH_PRIVATE_KEY: Contents of the SSH key file

8. Create a Dockerfile

FROM python:3.9.21-slim

WORKDIR /app

COPY . /app

RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

9. Push and Merge to Main

Create a new branch, push changes, and merge to main to trigger the workflow:

git checkout -b deploy-setup
git add .
git commit -m "Added CI/CD pipeline"
git push origin deploy-setup

Then, create a pull request and merge it into main.


Server Setup

10. Install Docker on the Server

SSH into your server and run:

sudo apt-get update -y
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER

11. Install and Configure Nginx

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

12. Configure Reverse Proxy

Create a new Nginx config file:

sudo vi /etc/nginx/sites-available/fastapi

Paste the following:

server {
    listen 80;
    server_name YOUR_SERVER_IP;

    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable the configuration and restart Nginx:

sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo nginx -t  # Test configuration
sudo systemctl restart nginx

13. Access the API

Copy your server IP and paste it into the browser:

http://YOUR_SERVER_IP

Your FastAPI app should now be live! ๐Ÿš€