DONE: update to use ip for the api in frontend
Build Docker Image / build-backend (push) Successful in 6s
Build Docker Image / build-admin (push) Successful in 7s
Build Docker Image / build-teller (push) Successful in 5s
Build Docker Image / build-customer (push) Successful in 12s

This commit is contained in:
ISMAIL MASSERAN
2026-07-26 14:08:13 +08:00
parent 8fd3dbe393
commit d0f5d4c979
13 changed files with 97 additions and 22 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ jobs:
IMAGE_TAG="${{ inputs.image_tag }}" IMAGE_TAG="${{ inputs.image_tag }}"
mkdir -p "${DEPLOY_DIR}" mkdir -p "${DEPLOY_DIR}"
cp be/docker-compose.yml "${DEPLOY_DIR}/docker-compose.yml" cp be/prod-compose.yml "${DEPLOY_DIR}/docker-compose.yml"
cd "${DEPLOY_DIR}" cd "${DEPLOY_DIR}"
+10 -3
View File
@@ -64,9 +64,14 @@ jobs:
IMAGE="git.koppkb.com/kopkb/qms-fe-admin" IMAGE="git.koppkb.com/kopkb/qms-fe-admin"
TAGS="-t ${IMAGE}:${{ gitea.sha }}" TAGS="-t ${IMAGE}:${{ gitea.sha }}"
API_URL="${{ secrets.VITE_API_URL }}" API_URL="${{ secrets.VITE_API_URL }}"
# Branch QR display URL only (public domain via nginx)
BRANCH_QR_BASE_URL="${{ secrets.VITE_BRANCH_QR_BASE_URL }}"
if [ -z "${BRANCH_QR_BASE_URL}" ]; then
BRANCH_QR_BASE_URL="https://qms-customer.erahn.com.my"
fi
if [ -z "${API_URL}" ]; then if [ -z "${API_URL}" ]; then
echo "ERROR: Set Gitea secret VITE_API_URL (e.g. https://qms-api.erahn.com.my)" echo "ERROR: Set Gitea secret VITE_API_URL (e.g. http://172.16.6.200:8080)"
exit 1 exit 1
fi fi
@@ -76,9 +81,11 @@ jobs:
echo "Building and pushing admin: ${TAGS}" echo "Building and pushing admin: ${TAGS}"
echo "VITE_API_URL=${API_URL}" echo "VITE_API_URL=${API_URL}"
echo "VITE_BRANCH_QR_BASE_URL=${BRANCH_QR_BASE_URL}"
docker buildx build \ docker buildx build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg VITE_API_URL="${API_URL}" \ --build-arg VITE_API_URL="${API_URL}" \
--build-arg VITE_BRANCH_QR_BASE_URL="${BRANCH_QR_BASE_URL}" \
--cache-from type=registry,ref=${IMAGE}:buildcache,ignore-error=true \ --cache-from type=registry,ref=${IMAGE}:buildcache,ignore-error=true \
--cache-to type=registry,ref=${IMAGE}:buildcache,mode=max \ --cache-to type=registry,ref=${IMAGE}:buildcache,mode=max \
-f fe/web/admin-app/Dockerfile \ -f fe/web/admin-app/Dockerfile \
@@ -109,7 +116,7 @@ jobs:
API_URL="${{ secrets.VITE_API_URL }}" API_URL="${{ secrets.VITE_API_URL }}"
if [ -z "${API_URL}" ]; then if [ -z "${API_URL}" ]; then
echo "ERROR: Set Gitea secret VITE_API_URL (e.g. https://qms-api.erahn.com.my)" echo "ERROR: Set Gitea secret VITE_API_URL (e.g. http://172.16.6.200:8080)"
exit 1 exit 1
fi fi
@@ -154,7 +161,7 @@ jobs:
fi fi
if [ -z "${API_URL}" ]; then if [ -z "${API_URL}" ]; then
echo "ERROR: Set Gitea secret NEXT_PUBLIC_API_URL or VITE_API_URL (e.g. https://qms-api.erahn.com.my)" echo "ERROR: Set Gitea secret NEXT_PUBLIC_API_URL or VITE_API_URL (e.g. http://172.16.6.200:8080)"
exit 1 exit 1
fi fi
+7
View File
@@ -51,3 +51,10 @@ The backend of the queue management system will be developed using Java's Spring
- [Ahmed Ljubuncic](https://github.com/aljubuncic) - [Ahmed Ljubuncic](https://github.com/aljubuncic)
- [Vedran Mujic](https://github.com/vmujic1) - [Vedran Mujic](https://github.com/vmujic1)
- [Amar Tahirovic](https://github.com/amarderschrecklicher) - [Amar Tahirovic](https://github.com/amarderschrecklicher)
## API ENV GUIDE
VITE_API_URL: API for teller and admin (also customer fallback in CI)
NEXT_PUBLIC_API_URL: API for customer
VITE_BRANCH_QR_BASE_URL: public customer base URL encoded into admin branch QR
Match these in Gitea secrets and in `fe/web/.env` on the deploy host (ports/images only matter at deploy; API URLs matter at image build).
+64
View File
@@ -0,0 +1,64 @@
services:
mysql:
image: mysql:8
container_name: qms-mysql
restart: unless-stopped
ports:
- "${MYSQL_HOST_PORT:-3307}:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-password}
MYSQL_DATABASE: ${MYSQL_DATABASE:-qms}
volumes:
- qms-mysql-data:/var/lib/mysql
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"localhost",
"-p${MYSQL_ROOT_PASSWORD:-password}",
]
interval: 5s
timeout: 5s
retries: 20
start_period: 20s
networks:
- qms-net
backend:
image: ${BACKEND_IMAGE:-qms-backend}:${IMAGE_TAG:-local}
build:
context: .
dockerfile: Dockerfile
container_name: qms-backend
restart: unless-stopped
ports:
# Host port can be changed via BACKEND_HOST_PORT in .env (default 8080)
- "${BACKEND_HOST_PORT:-8080}:8080"
environment:
SERVER_PORT: 8080
# Use Docker service name "mysql", not localhost
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/${MYSQL_DATABASE:-qms}?allowPublicKeyRetrieval=true&useSSL=false
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PASSWORD:-password}
JWT_SECRET_KEY: ${JWT_SECRET_KEY:-a68uiaDQ0V3iLjF4DqMuS13GAVwkut55dlFbGCLyXTF}
ADS_UPLOAD_DIR: /app/uploads/ads
NOTIFICATIONS_MOCK: ${NOTIFICATIONS_MOCK:-true}
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-dummy-google-client-id}
volumes:
- qms-uploads:/app/uploads
depends_on:
mysql:
condition: service_healthy
networks:
- qms-net
volumes:
qms-mysql-data:
qms-uploads:
networks:
qms-net:
driver: bridge
+2 -13
View File
@@ -1,25 +1,14 @@
# Host ports (used until nginx terminates TLS on 443) # Host ports (nginx terminates TLS on 443 and proxies to these)
ADMIN_HOST_PORT=5000 ADMIN_HOST_PORT=5000
TELLER_HOST_PORT=3001 TELLER_HOST_PORT=3001
CUSTOMER_HOST_PORT=3000 CUSTOMER_HOST_PORT=3000
# Domains — also set these as Gitea secrets, then rebuild FE images
# VITE_API_URL / NEXT_PUBLIC_API_URL = https://qms-api.erahn.com.my
# VITE_CUSTOMER_APP_URL = https://qms-customer.erahn.com.my
VITE_API_URL=https://qms-api.erahn.com.my VITE_API_URL=https://qms-api.erahn.com.my
VITE_CUSTOMER_APP_URL=https://qms-customer.erahn.com.my
NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my
VITE_BRANCH_QR_BASE_URL=https://qms-customer.erahn.com.my
# Public app URLs (reference for nginx / bookmarks)
# ADMIN: https://qms-admin.erahn.com.my
# TELLER: https://qms-teller.erahn.com.my
# CUSTOMER: https://qms-customer.erahn.com.my
# API: https://qms-api.erahn.com.my
# Runtime (customer Next.js server)
QR_TOKEN_SECRET=qms-branch-qr-v1 QR_TOKEN_SECRET=qms-branch-qr-v1
# Registry images (used by compose / deploy)
ADMIN_IMAGE=git.koppkb.com/kopkb/qms-fe-admin ADMIN_IMAGE=git.koppkb.com/kopkb/qms-fe-admin
TELLER_IMAGE=git.koppkb.com/kopkb/qms-fe-teller TELLER_IMAGE=git.koppkb.com/kopkb/qms-fe-teller
CUSTOMER_IMAGE=git.koppkb.com/kopkb/qms-fe-customer CUSTOMER_IMAGE=git.koppkb.com/kopkb/qms-fe-customer
+1
View File
@@ -4,6 +4,7 @@ CUSTOMER_HOST_PORT=3000
VITE_API_URL=https://qms-api.erahn.com.my VITE_API_URL=https://qms-api.erahn.com.my
NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my
VITE_BRANCH_QR_BASE_URL=https://qms-customer.erahn.com.my
QR_TOKEN_SECRET=qms-branch-qr-v1 QR_TOKEN_SECRET=qms-branch-qr-v1
+1
View File
@@ -4,6 +4,7 @@ CUSTOMER_HOST_PORT=3000
VITE_API_URL=https://qms-api.erahn.com.my VITE_API_URL=https://qms-api.erahn.com.my
NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my NEXT_PUBLIC_API_URL=https://qms-api.erahn.com.my
VITE_BRANCH_QR_BASE_URL=https://qms-customer.erahn.com.my
QR_TOKEN_SECRET=qms-branch-qr-v1 QR_TOKEN_SECRET=qms-branch-qr-v1
+1
View File
@@ -1 +1,2 @@
VITE_API_URL=https://qms-api.erahn.com.my VITE_API_URL=https://qms-api.erahn.com.my
VITE_BRANCH_QR_BASE_URL=https://qms-customer.erahn.com.my
+1 -1
View File
@@ -1,2 +1,2 @@
# Baked into the admin image at build time (Gitea secret VITE_API_URL)
VITE_API_URL=https://qms-api.erahn.com.my VITE_API_URL=https://qms-api.erahn.com.my
VITE_BRANCH_QR_BASE_URL=https://qms-customer.erahn.com.my
+2
View File
@@ -3,7 +3,9 @@ FROM node:20-bookworm AS build
WORKDIR /app WORKDIR /app
ARG VITE_API_URL=http://localhost:8080 ARG VITE_API_URL=http://localhost:8080
ARG VITE_BRANCH_QR_BASE_URL=http://localhost:3000
ENV VITE_API_URL=$VITE_API_URL ENV VITE_API_URL=$VITE_API_URL
ENV VITE_BRANCH_QR_BASE_URL=$VITE_BRANCH_QR_BASE_URL
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci RUN npm ci
+3 -1
View File
@@ -1,6 +1,8 @@
export const SERVER_URL = import.meta.env.VITE_API_URL; export const SERVER_URL = import.meta.env.VITE_API_URL;
export const CUSTOMER_APP_URL = 'https://qms-customer.erahn.com.my'; /** Public base URL encoded into branch QR codes (ManageBranchesScreen only). */
export const BRANCH_QR_BASE_URL =
import.meta.env.VITE_BRANCH_QR_BASE_URL ?? 'http://localhost:3000';
export const ROLES = { export const ROLES = {
ROLE_SUPER_ADMIN: 'ROLE_SUPER_ADMIN', ROLE_SUPER_ADMIN: 'ROLE_SUPER_ADMIN',
+2 -2
View File
@@ -1,5 +1,5 @@
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import { CUSTOMER_APP_URL } from '../constants.js'; import { BRANCH_QR_BASE_URL } from '../constants.js';
const DEFAULT_QR_SECRET = 'qms-branch-qr-v1'; const DEFAULT_QR_SECRET = 'qms-branch-qr-v1';
@@ -54,7 +54,7 @@ export function decodeBranchQrToken(token, secret = getQrSecret()) {
} }
export function getBranchTicketUrl(tenantCode, branchId) { export function getBranchTicketUrl(tenantCode, branchId) {
const base = CUSTOMER_APP_URL.replace(/\/$/, ''); const base = BRANCH_QR_BASE_URL.replace(/\/$/, '');
const token = encodeBranchQrToken(tenantCode, branchId); const token = encodeBranchQrToken(tenantCode, branchId);
return `${base}/q/${token}`; return `${base}/q/${token}`;
} }
+1
View File
@@ -6,6 +6,7 @@ services:
dockerfile: Dockerfile dockerfile: Dockerfile
args: args:
VITE_API_URL: ${VITE_API_URL:-http://localhost:8080} VITE_API_URL: ${VITE_API_URL:-http://localhost:8080}
VITE_BRANCH_QR_BASE_URL: ${VITE_BRANCH_QR_BASE_URL:-http://localhost:3000}
container_name: qms-fe-admin container_name: qms-fe-admin
restart: unless-stopped restart: unless-stopped
ports: ports: