This project uses:
- Backend: Node.js + Express + MongoDB
- Frontend: Static HTML/CSS/JS (served via Nginx)
- Infra: Docker Compose (3 services: backend, frontend, mongodb)
1. Add Docker Hub secrets to your repo:
Go to Settings → Secrets and variables → Actions and add:
DOCKER_USERNAME— your Docker Hub usernameDOCKER_PASSWORD— Docker Hub access tokenMONGO_URI— your production MongoDB connection stringJWT_SECRET— your production JWT secret
2. Create the workflow file:
mkdir -p .github/workflowsCreate .github/workflows/ci-cd.yml (see workflow template below).
3. Push to main or develop branch — the pipeline triggers automatically.
| Stage | Description |
|---|---|
| Lint | Run ESLint on backend code |
| Build | Build Docker images for backend + frontend |
| Test | Run any defined tests (currently placeholder) |
| Push | Push images to Docker Hub (tagged with commit SHA + latest) |
| Deploy | SSH into your server, pull images, restart via docker compose up -d |
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
DOCKER_IMAGE_BACKEND: ${{ secrets.DOCKER_USERNAME }}/logitrack-backend
DOCKER_IMAGE_FRONTEND: ${{ secrets.DOCKER_USERNAME }}/logitrack-frontend
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
working-directory: ./backend
run: npm ci
- name: Run lint (optional — add ESLint if desired)
working-directory: ./backend
run: npm run test || true
build-and-push:
needs: lint-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build & push backend
uses: docker/build-push-action@v5
with:
context: ./backend
push: true
tags: |
${{ env.DOCKER_IMAGE_BACKEND }}:latest
${{ env.DOCKER_IMAGE_BACKEND }}:${{ github.sha }}
- name: Build & push frontend
uses: docker/build-push-action@v5
with:
context: ./frontend
push: true
tags: |
${{ env.DOCKER_IMAGE_FRONTEND }}:latest
${{ env.DOCKER_IMAGE_FRONTEND }}:${{ github.sha }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Deploy to server
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/logitrack
docker compose pull
docker compose up -d
docker system prune -f- Connect your GitHub repo
- Create Web Service → point to
backend/ - Set env vars:
MONGO_URI,JWT_SECRET - Deploy (auto-deploys on push)
- Connect repo → Railway auto-detects Docker Compose
- Add env vars in dashboard
- Deploy
fly launch # auto-generates fly.toml
fly secrets set MONGO_URI=xxx JWT_SECRET=xxx
fly deploy# On your server:
git clone <repo-url> /opt/logitrack
cd /opt/logitrack
# Create .env file
cat > .env <<EOF
MONGO_URI=your_mongodb_uri
JWT_SECRET=your_jwt_secret
EOF
# Start everything
docker compose up -d| Secret | Description |
|---|---|
DOCKER_USERNAME |
Docker Hub username |
DOCKER_PASSWORD |
Docker Hub access token |
SERVER_HOST |
Your VPS IP or domain |
SERVER_USER |
SSH username (e.g., root, ubuntu) |
SSH_PRIVATE_KEY |
Private SSH key for passwordless login |
MONGO_URI |
Production MongoDB URI |
JWT_SECRET |
Production JWT secret |
Currently npm test is a placeholder. To enable real tests:
cd backend
npm install --save-dev jest supertestAdd to package.json:
"scripts": {
"test": "jest --forceExit"
}Create backend/tests/api.test.js and the CI pipeline will run them automatically.