add workflow
Some checks failed
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Failing after 9s
Build and Deploy Frontend Learner / Deploy Frontend Learner to Server (push) Has been skipped
Build and Deploy Frontend Management / Build Frontend Management Docker Image (push) Failing after 9s
Build and Deploy Backend / Build Backend Docker Image (push) Failing after 9s
Build and Deploy Frontend Management / Deploy Frontend Management to Server (push) Has been skipped
Build and Deploy Backend / Deploy Backend to Server (push) Has been skipped

This commit is contained in:
JakkrapartXD 2026-02-09 16:56:12 +07:00
parent 15794fab16
commit 4ec1d34297
6 changed files with 364 additions and 0 deletions

View file

@ -0,0 +1,64 @@
name: Build and Deploy Backend
on:
push:
branches:
- main
- dev
paths:
- 'Backend/**'
workflow_dispatch:
jobs:
build:
name: Build Backend Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ vars.DOCKER_REGISTRY }}/elearning-backend
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./Backend
file: ./Backend/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
name: Deploy Backend to Server
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
steps:
- name: Remote Deploy
uses: appleboy/ssh-action@v1.2.1
with:
host: ${{ vars.SSH_DEPLOY_HOST }}
port: ${{ vars.SSH_DEPLOY_PORT }}
username: ${{ secrets.SSH_DEPLOY_USER }}
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
script: eval "${{ secrets.SSH_DEPLOY_BACKEND_CMD }}"

View file

@ -0,0 +1,64 @@
name: Build and Deploy Frontend Learner
on:
push:
branches:
- main
- dev
paths:
- 'Frontend-Learner/**'
workflow_dispatch:
jobs:
build:
name: Build Frontend Learner Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ vars.DOCKER_REGISTRY }}/elearning-frontend-learner
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./Frontend-Learner
file: ./Frontend-Learner/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
name: Deploy Frontend Learner to Server
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
steps:
- name: Remote Deploy
uses: appleboy/ssh-action@v1.2.1
with:
host: ${{ vars.SSH_DEPLOY_HOST }}
port: ${{ vars.SSH_DEPLOY_PORT }}
username: ${{ secrets.SSH_DEPLOY_USER }}
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
script: eval "${{ secrets.SSH_DEPLOY_FRONTEND_LEARNER_CMD }}"

View file

@ -0,0 +1,64 @@
name: Build and Deploy Frontend Management
on:
push:
branches:
- main
- dev
paths:
- 'frontend_management/**'
workflow_dispatch:
jobs:
build:
name: Build Frontend Management Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ vars.DOCKER_REGISTRY }}/elearning-frontend-management
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./frontend_management
file: ./frontend_management/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
name: Deploy Frontend Management to Server
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
steps:
- name: Remote Deploy
uses: appleboy/ssh-action@v1.2.1
with:
host: ${{ vars.SSH_DEPLOY_HOST }}
port: ${{ vars.SSH_DEPLOY_PORT }}
username: ${{ secrets.SSH_DEPLOY_USER }}
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
script: eval "${{ secrets.SSH_DEPLOY_FRONTEND_MGMT_CMD }}"

55
Backend/Dockerfile Normal file
View file

@ -0,0 +1,55 @@
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
COPY pnpm-lock.yaml* ./
# Install pnpm and dependencies
RUN npm install -g pnpm && pnpm install --frozen-lockfile
# Copy source code
COPY . .
# Generate Prisma client
RUN pnpm prisma:generate
# Build application
RUN pnpm build
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
# Install pnpm
RUN npm install -g pnpm
# Copy package files
COPY package*.json ./
COPY pnpm-lock.yaml* ./
# Install production dependencies only
RUN pnpm install --prod --frozen-lockfile
# Copy built files from builder
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/public ./public
# Set environment
ENV NODE_ENV=production
ENV PORT=4000
# Expose port
EXPOSE 4000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:4000/health || exit 1
# Start application
CMD ["node", "dist/server.js"]

69
compose.infa.yaml Normal file
View file

@ -0,0 +1,69 @@
services:
# PostgreSQL Database
postgres:
image: postgres:16-alpine
container_name: elearning-postgres
restart: unless-stopped
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=elearning_dev
- POSTGRES_PASSWORD=12345678
- TZ=Asia/Bangkok
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 10s
timeout: 5s
retries: 5
networks:
- elearning-shared
# MinIO - S3 Compatible Storage
minio:
image: minio/minio:latest
container_name: elearning-minio
deploy:
resources:
limits:
memory: 1G
restart: unless-stopped
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio-data:/data
environment:
- TZ=Asia/Bangkok
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=12345678
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
interval: 30s
timeout: 20s
retries: 3
networks:
- elearning-shared
# Mailhog - Email Testing
mailhog:
image: mailhog/mailhog:latest
container_name: elearning-mailhog
restart: unless-stopped
ports:
- "1025:1025"
- "8025:8025"
environment:
- TZ=Asia/Bangkok
networks:
- elearning-shared
volumes:
postgres-data:
minio-data:
networks:
elearning-shared:
external: true

48
compose.yaml Normal file
View file

@ -0,0 +1,48 @@
services:
# ============================================
# Application Services
# ============================================
# Backend API
backend:
image: 192.168.1.60:5000/elearning-backend:latest
container_name: elearning-backend
restart: unless-stopped
ports:
- "4000:4000"
env_file:
- .env
networks:
- elearning-shared
# Frontend Learner
frontend-learner:
image: 192.168.1.60:5000/elearning-frontend-learner:latest
container_name: elearning-frontend-learner
restart: unless-stopped
ports:
- "3000:3000"
env_file:
- .env
depends_on:
- backend
networks:
- elearning-shared
# Frontend Management
frontend-management:
image: 192.168.1.60:5000/elearning-frontend-management:latest
container_name: elearning-frontend-management
restart: unless-stopped
ports:
- "3001:3000"
env_file:
- .env
depends_on:
- backend
networks:
- elearning-shared
networks:
elearning-shared:
external: true