Continuous Integration and Deployment #
NewsFeed includes a GitHub Actions workflow for continuous integration and deployment. This workflow automatically builds and publishes Docker images for the NewsFeed application.
GitHub Actions Workflow #
The GitHub Actions workflow is defined in .github/workflows/docker-publish.yml
and performs the following tasks:
- Builds the Docker images for all services (including documentation in the Nginx image)
- Pushes the images to Docker Hub with appropriate tags
Image Tags #
The workflow generates the following tags for each image:
latest
: Always points to the most recent build from the main branch<branch-name>
: The name of the branch that triggered the build<commit-sha>
: The first 7 characters of the commit SHA
Docker Images #
The following Docker images are built and published:
beardedtek/newsfeed-nginx
: The Nginx container that serves the documentation and acts as a reverse proxybeardedtek/newsfeed
: The frontend Next.js applicationbeardedtek/newsfeed-backend
: The backend FastAPI application (used for both the API and worker containers)
Documentation Deployment #
In addition to the Docker image workflow, there is also a GitHub Actions workflow for deploying the documentation to GitHub Pages. This workflow is defined in .github/workflows/deploy-docs.yml
and is triggered when changes are made to the docs/
directory.
The documentation is deployed to GitHub Pages at: https://beardedtek.github.io/newsfeed/
Skipping CI/CD Workflows #
You can control CI/CD workflows by including specific phrases in your commit messages:
Skip All Workflows #
NO_CICD
: Skips all CI/CD workflows
Skip Specific Workflows #
NO_CICD_DOCKER
: Skips only the Docker build and publish workflowNO_CICD_DOCS
: Skips only the documentation deployment workflowNO_CICD_FRONTEND
: Skips only the frontend Docker build/pushNO_CICD_BACKEND
: Skips only the backend Docker build/pushNO_CICD_NGINX
: Skips only the nginx Docker build/push
Run Only Specific Workflows #
CICD_ONLY_FRONTEND
: Only runs the frontend Docker build/pushCICD_ONLY_BACKEND
: Only runs the backend Docker build/pushCICD_ONLY_NGINX
: Only runs the nginx Docker build/pushCICD_ONLY_DOCS
: Only runs the GitHub Pages documentation deployment
Examples:
git commit -m "Update README [NO_CICD]" # Skips all workflows
git commit -m "Fix typo in docs [NO_CICD_DOCKER]" # Only skips Docker workflow
git commit -m "Update Docker config [NO_CICD_DOCS]" # Only skips docs workflow
git commit -m "Update frontend only [CICD_ONLY_FRONTEND]" # Only builds frontend
git commit -m "Fix backend bug [NO_CICD_FRONTEND]" # Skips frontend build
This feature is useful when:
- Making minor documentation changes without triggering a full Docker build
- Testing changes to Docker configurations without triggering documentation deployment
- Skipping all CI/CD for very minor changes or work-in-progress commits
- Building only the components that have changed to save CI/CD time and resources
Build Process #
The build process uses Docker’s multi-stage builds to simplify deployment:
- The Nginx container uses a multi-stage build to generate documentation with Hugo and then serve it with Nginx
- The frontend and backend containers use their respective Dockerfiles for building
- All containers can be built together using
docker compose build
Simplified Nginx Build #
The Nginx image now uses a multi-stage build defined in nginx/Dockerfile
:
- First stage uses Hugo to build the documentation
- Second stage uses Nginx to serve the application and documentation
- No separate build scripts are needed
Local Development #
For local development, use Docker Compose:
# Build all images
docker compose build
# Start all services
docker compose up -d
# Build and start a specific service
docker compose up -d --build nginx
Production Deployment #
For production deployment, you can use the pre-built images from Docker Hub:
# In docker-compose.yml
services:
nginx:
image: beardedtek/newsfeed-nginx:latest
# ...
frontend:
image: beardedtek/newsfeed:latest
# ...
backend:
image: beardedtek/newsfeed-backend:latest
# ...
For production environments, it’s recommended to use specific version tags instead of latest
to ensure consistency:
services:
nginx:
image: beardedtek/newsfeed-nginx:v1.0.0
# ...
Setting Up CI/CD for Your Fork #
If you fork the NewsFeed repository, you’ll need to set up the following secrets in your GitHub repository to enable the CI/CD workflow:
DOCKERHUB_USERNAME
- Your Docker Hub usernameDOCKERHUB_TOKEN
- A Docker Hub access token (not your password)
Creating a Docker Hub Access Token #
- Log in to Docker Hub
- Go to Account Settings > Security
- Click “New Access Token”
- Give it a name (e.g., “GitHub Actions”)
- Copy the token and add it as a secret in your GitHub repository
Adding Secrets to GitHub #
- Go to your GitHub repository
- Click on “Settings” > “Secrets and variables” > “Actions”
- Click “New repository secret”
- Add the following secrets:
- Name:
DOCKERHUB_USERNAME
, Value: Your Docker Hub username - Name:
DOCKERHUB_TOKEN
, Value: Your Docker Hub access token
- Name:
Customizing the CI/CD Workflow #
The CI/CD workflow is defined in the .github/workflows/docker-publish.yml
file. You can customize it to suit your needs, such as:
- Adding more branches to the trigger list
- Changing the tag format
- Adding more Docker images
- Adding build arguments
- Configuring additional platforms (e.g., for multi-architecture builds)
Automated Deployments #
Currently, the CI/CD workflow only builds and publishes Docker images. It does not automatically deploy them to any environment. You can extend the workflow to deploy to your environment by adding additional steps to the workflow.
For example, to deploy to a server using SSH:
- name: Deploy to production
if: github.ref == 'refs/heads/main'
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /path/to/newsfeed
docker-compose pull
docker-compose up -d
This would require additional secrets:
SSH_HOST
- The hostname or IP address of your serverSSH_USERNAME
- The username to use for SSHSSH_PRIVATE_KEY
- The private key to use for SSH authentication