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
- Start the FastAPI server:
uvicorn main:app --reload - Open Swagger docs in your browser: http://localhost:8000/docs
- Run tests:
pytest
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 usernameDOCKER_PASSWORD: Your DockerHub passwordSERVER_IP: Your instance IPSERVER_USER:ubuntuSSH_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! ๐


