DONE: add cicd for api_arrahn
Build Docker Image / build-backend (push) Successful in 1m21s

This commit is contained in:
ISMAIL MASSERAN
2026-08-26 11:51:41 +08:00
parent f1618c1ffd
commit 38f0546685
34 changed files with 923 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
.git
.gitea
node_modules
vendor
.env
.env.*
!.env.example
storage/logs
storage/framework/cache
storage/framework/sessions
storage/framework/views
storage/debugbar
npm-debug.log
Dockerfile
docker-compose.yml
docker-compose.staging.yml
+84
View File
@@ -0,0 +1,84 @@
APP_NAME=Lumen
APP_ENV=staging
APP_KEY=WbPGkYNmXZ6ZQplGlvl0iZ7zyW1b09xa
APP_DEBUG=true
APP_URL=http://127.0.0.1:8090
APP_TIMEZONE=Asia/Kuala_Lumpur
# Unique host ports — change these if they collide with other containers on the server.
# Host nginx should proxy the staging domain to 127.0.0.1:${HTTP_PORT}
HTTP_PORT=8090
MYSQL_PUBLISH_PORT=3308
LOG_CHANNEL=stack
LOG_LEVEL=debug
LOG_SLACK_WEBHOOK_URL=
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=erahn_xtra
DB_USERNAME=root
DB_PASSWORD=root
DB_CONNECTION_7=mysql
DB_HOST_7=mysql
DB_PORT_7=3306
DB_DATABASE_7=master_erahn
DB_USERNAME_7=root
DB_PASSWORD_7=root
DB_CONNECTION_2=mysql
DB_HOST_2=mysql
DB_PORT_2=3306
DB_DATABASE_2=erahn_xtra
DB_USERNAME_2=root
DB_PASSWORD_2=root
DB_CONNECTION_3=mysql
DB_HOST_3=mysql
DB_PORT_3=3306
DB_DATABASE_3=erahn_baling
DB_USERNAME_3=root
DB_PASSWORD_3=root
DB_CONNECTION_4=mysql
DB_HOST_4=mysql
DB_PORT_4=3306
DB_DATABASE_4=arrahn_ld
DB_USERNAME_4=root
DB_PASSWORD_4=root
DB_CONNECTION_5=mysql
DB_HOST_5=mysql
DB_PORT_5=3306
DB_DATABASE_5=erahn_segamat
DB_USERNAME_5=root
DB_PASSWORD_5=root
DB_CONNECTION_7=mysql
DB_HOST_7=mysql
DB_PORT_7=3306
DB_DATABASE_7=master_erahn
DB_USERNAME_7=root
DB_PASSWORD_7=root
DB_CONNECTION_6=mysql
DB_HOST_6=mysql
DB_PORT_6=3306
DB_DATABASE_6=erahn_test
DB_USERNAME_6=root
DB_PASSWORD_6=root
# DB_CONNECTION_8=mysql
# DB_HOST_8=mysql
# DB_PORT_8=3306
# DB_DATABASE_8=arrahn_klanas
# DB_USERNAME_8=spider
# DB_PASSWORD_8=G0dz!ll42020
TENNANT_MASTER_DB=master_erahn
TENNANT_KAUNTER_DB=kaunter_erahn
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
+49
View File
@@ -0,0 +1,49 @@
name: Build Docker Image
on:
push:
branches:
- staging
tags:
- "v*"
workflow_dispatch:
jobs:
build-backend:
runs-on: docker
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to Docker registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | \
docker login git.koppkb.com \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build & push backend image
run: |
set -e
IMAGE="git.koppkb.com/kopkb/api_arrahn"
TAGS="-t ${IMAGE}:${{ gitea.sha }}"
if [ "${{ gitea.ref_type }}" = "tag" ] && echo "${{ gitea.ref_name }}" | grep -q '^v'; then
TAGS="${TAGS} -t ${IMAGE}:${{ gitea.ref_name }}"
fi
if [ "${{ gitea.ref_name }}" = "staging" ]; then
TAGS="${TAGS} -t ${IMAGE}:staging"
fi
echo "Building and pushing backend: ${TAGS}"
docker buildx build \
--target staging \
--platform linux/amd64 \
--cache-from type=registry,ref=${IMAGE}:buildcache,ignore-error=true \
--cache-to type=registry,ref=${IMAGE}:buildcache,mode=max \
-f docker/php/Dockerfile \
${TAGS} \
--push .
+122
View File
@@ -0,0 +1,122 @@
name: Deploy to Staging
on:
workflow_dispatch:
inputs:
image_tag:
description: "Docker image tag to deploy (commit SHA, staging, or v*)"
required: true
default: "staging"
type: string
env:
APP_IMAGE: git.koppkb.com/KoPKB/api_arrahn
DEPLOY_DIR: /home/arrahn/Project/api_arrahn
jobs:
deploy:
runs-on: host
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.image_tag }}
- name: Login to Docker registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | \
docker login git.koppkb.com \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Verify image exists in registry
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
IMAGE="${APP_IMAGE}:${IMAGE_TAG}"
echo "Checking if image exists: ${IMAGE}"
if ! docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then
echo "ERROR: Image ${IMAGE} does not exist in registry!"
echo "Run the Build Docker Image workflow first."
exit 1
fi
echo "✓ ${IMAGE} found"
- name: Pull Docker image
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
docker pull "${APP_IMAGE}:${IMAGE_TAG}"
echo "✓ Image pulled successfully"
- name: Sync compose file and deploy
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
mkdir -p "${DEPLOY_DIR}/docker/nginx" "${DEPLOY_DIR}/docker/mysql"
cp docker-compose.staging.yml "${DEPLOY_DIR}/docker-compose.yml"
cp docker/nginx/default.conf "${DEPLOY_DIR}/docker/nginx/default.conf"
cp -R docker/mysql/init "${DEPLOY_DIR}/docker/mysql/"
if [ ! -f "${DEPLOY_DIR}/.env.staging" ]; then
if [ -f .env.staging ]; then
cp .env.staging "${DEPLOY_DIR}/.env.staging"
echo "Copied .env.staging from repo (first deploy). Edit ${DEPLOY_DIR}/.env.staging on the server if needed."
else
echo "ERROR: ${DEPLOY_DIR}/.env.staging is missing on the server"
exit 1
fi
fi
cd "${DEPLOY_DIR}"
export APP_IMAGE
export IMAGE_TAG
docker compose --env-file .env.staging -f docker-compose.yml pull app
docker compose --env-file .env.staging -f docker-compose.yml up -d --no-build --remove-orphans
echo "✓ Deployed IMAGE_TAG=${IMAGE_TAG}"
- name: Verify deployment
run: |
set -e
cd "${DEPLOY_DIR}"
echo "Waiting for services to start..."
sleep 10
for SERVICE in app web mysql; do
STATUS=$(docker compose --env-file .env.staging -f docker-compose.yml ps --status running --format '{{.Name}}' "$SERVICE" 2>/dev/null || true)
if [ -z "$STATUS" ]; then
echo "ERROR: ${SERVICE} is not running"
docker compose --env-file .env.staging -f docker-compose.yml ps
docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 "$SERVICE" || true
exit 1
fi
echo "✓ ${SERVICE} is running (${STATUS})"
done
HTTP_PORT=$(grep -E '^HTTP_PORT=' .env.staging 2>/dev/null | cut -d= -f2- | tr -d '"' || true)
HTTP_PORT=${HTTP_PORT:-8090}
check_health() {
NAME=$1
URL=$2
for i in 1 2 3 4 5 6; do
if curl -sf "$URL" > /dev/null; then
echo "✓ ${NAME} health check passed (${URL})"
return 0
fi
echo "Waiting for ${NAME}... attempt ${i}/6"
sleep 5
done
echo "ERROR: ${NAME} health check failed (${URL})"
docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 app web || true
return 1
}
check_health "api" "http://127.0.0.1:${HTTP_PORT}/health"
Vendored Executable
+143
View File
@@ -0,0 +1,143 @@
<?php return array (
'barryvdh/laravel-debugbar' =>
array (
'providers' =>
array (
0 => 'Barryvdh\\Debugbar\\ServiceProvider',
),
'aliases' =>
array (
'Debugbar' => 'Barryvdh\\Debugbar\\Facades\\Debugbar',
),
),
'barryvdh/laravel-dompdf' =>
array (
'providers' =>
array (
0 => 'Barryvdh\\DomPDF\\ServiceProvider',
),
'aliases' =>
array (
'PDF' => 'Barryvdh\\DomPDF\\Facade',
),
),
'facade/ignition' =>
array (
'providers' =>
array (
0 => 'Facade\\Ignition\\IgnitionServiceProvider',
),
'aliases' =>
array (
'Flare' => 'Facade\\Ignition\\Facades\\Flare',
),
),
'fideloper/proxy' =>
array (
'providers' =>
array (
0 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
),
),
'fruitcake/laravel-cors' =>
array (
'providers' =>
array (
0 => 'Fruitcake\\Cors\\CorsServiceProvider',
),
),
'intervention/image' =>
array (
'providers' =>
array (
0 => 'Intervention\\Image\\ImageServiceProvider',
),
'aliases' =>
array (
'Image' => 'Intervention\\Image\\Facades\\Image',
),
),
'jeroennoten/laravel-adminlte' =>
array (
'providers' =>
array (
0 => 'JeroenNoten\\LaravelAdminLte\\AdminLteServiceProvider',
),
),
'laravel/tinker' =>
array (
'providers' =>
array (
0 => 'Laravel\\Tinker\\TinkerServiceProvider',
),
),
'laravel/ui' =>
array (
'providers' =>
array (
0 => 'Laravel\\Ui\\UiServiceProvider',
),
),
'milon/barcode' =>
array (
'providers' =>
array (
0 => 'Milon\\Barcode\\BarcodeServiceProvider',
),
'aliases' =>
array (
'DNS1D' => 'Milon\\Barcode\\Facades\\DNS1DFacade',
'DNS2D' => 'Milon\\Barcode\\Facades\\DNS2DFacade',
),
),
'nesbot/carbon' =>
array (
'providers' =>
array (
0 => 'Carbon\\Laravel\\ServiceProvider',
),
),
'nunomaduro/collision' =>
array (
'providers' =>
array (
0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
),
),
'rap2hpoutre/laravel-log-viewer' =>
array (
'providers' =>
array (
0 => 'Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider',
),
),
'simplesoftwareio/simple-qrcode' =>
array (
'providers' =>
array (
0 => 'SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider',
),
'aliases' =>
array (
'QrCode' => 'SimpleSoftwareIO\\QrCode\\Facades\\QrCode',
),
),
'spatie/laravel-medialibrary' =>
array (
'providers' =>
array (
0 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider',
),
),
'yajra/laravel-datatables-oracle' =>
array (
'providers' =>
array (
0 => 'Yajra\\DataTables\\DataTablesServiceProvider',
),
'aliases' =>
array (
'DataTables' => 'Yajra\\DataTables\\Facades\\DataTables',
),
),
);
Vendored Executable
+238
View File
@@ -0,0 +1,238 @@
<?php return array (
'providers' =>
array (
0 => 'Illuminate\\Auth\\AuthServiceProvider',
1 => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
2 => 'Illuminate\\Bus\\BusServiceProvider',
3 => 'Illuminate\\Cache\\CacheServiceProvider',
4 => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
5 => 'Illuminate\\Cookie\\CookieServiceProvider',
6 => 'Illuminate\\Database\\DatabaseServiceProvider',
7 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
8 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
9 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
10 => 'Illuminate\\Hashing\\HashServiceProvider',
11 => 'Illuminate\\Mail\\MailServiceProvider',
12 => 'Illuminate\\Notifications\\NotificationServiceProvider',
13 => 'Illuminate\\Pagination\\PaginationServiceProvider',
14 => 'Illuminate\\Pipeline\\PipelineServiceProvider',
15 => 'Illuminate\\Queue\\QueueServiceProvider',
16 => 'Illuminate\\Redis\\RedisServiceProvider',
17 => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
18 => 'Illuminate\\Session\\SessionServiceProvider',
19 => 'Illuminate\\Translation\\TranslationServiceProvider',
20 => 'Illuminate\\Validation\\ValidationServiceProvider',
21 => 'Illuminate\\View\\ViewServiceProvider',
22 => 'Barryvdh\\Debugbar\\ServiceProvider',
23 => 'Barryvdh\\DomPDF\\ServiceProvider',
24 => 'Facade\\Ignition\\IgnitionServiceProvider',
25 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
26 => 'Fruitcake\\Cors\\CorsServiceProvider',
27 => 'Intervention\\Image\\ImageServiceProvider',
28 => 'JeroenNoten\\LaravelAdminLte\\AdminLteServiceProvider',
29 => 'Laravel\\Tinker\\TinkerServiceProvider',
30 => 'Laravel\\Ui\\UiServiceProvider',
31 => 'Milon\\Barcode\\BarcodeServiceProvider',
32 => 'Carbon\\Laravel\\ServiceProvider',
33 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
34 => 'Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider',
35 => 'SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider',
36 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider',
37 => 'Yajra\\DataTables\\DataTablesServiceProvider',
38 => 'App\\Providers\\AppServiceProvider',
39 => 'App\\Providers\\AuthServiceProvider',
40 => 'App\\Providers\\EventServiceProvider',
41 => 'App\\Providers\\RouteServiceProvider',
42 => 'Yajra\\DataTables\\DataTablesServiceProvider',
43 => 'Barryvdh\\DomPDF\\ServiceProvider',
44 => 'Milon\\Barcode\\BarcodeServiceProvider',
45 => 'Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider',
),
'eager' =>
array (
0 => 'Illuminate\\Auth\\AuthServiceProvider',
1 => 'Illuminate\\Cookie\\CookieServiceProvider',
2 => 'Illuminate\\Database\\DatabaseServiceProvider',
3 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
4 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
5 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
6 => 'Illuminate\\Notifications\\NotificationServiceProvider',
7 => 'Illuminate\\Pagination\\PaginationServiceProvider',
8 => 'Illuminate\\Session\\SessionServiceProvider',
9 => 'Illuminate\\View\\ViewServiceProvider',
10 => 'Barryvdh\\Debugbar\\ServiceProvider',
11 => 'Barryvdh\\DomPDF\\ServiceProvider',
12 => 'Facade\\Ignition\\IgnitionServiceProvider',
13 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
14 => 'Fruitcake\\Cors\\CorsServiceProvider',
15 => 'Intervention\\Image\\ImageServiceProvider',
16 => 'JeroenNoten\\LaravelAdminLte\\AdminLteServiceProvider',
17 => 'Laravel\\Ui\\UiServiceProvider',
18 => 'Milon\\Barcode\\BarcodeServiceProvider',
19 => 'Carbon\\Laravel\\ServiceProvider',
20 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
21 => 'Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider',
22 => 'SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider',
23 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider',
24 => 'Yajra\\DataTables\\DataTablesServiceProvider',
25 => 'App\\Providers\\AppServiceProvider',
26 => 'App\\Providers\\AuthServiceProvider',
27 => 'App\\Providers\\EventServiceProvider',
28 => 'App\\Providers\\RouteServiceProvider',
29 => 'Yajra\\DataTables\\DataTablesServiceProvider',
30 => 'Barryvdh\\DomPDF\\ServiceProvider',
31 => 'Milon\\Barcode\\BarcodeServiceProvider',
32 => 'Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider',
),
'deferred' =>
array (
'Illuminate\\Broadcasting\\BroadcastManager' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
'Illuminate\\Contracts\\Broadcasting\\Factory' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
'Illuminate\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
'Illuminate\\Contracts\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
'cache' => 'Illuminate\\Cache\\CacheServiceProvider',
'cache.store' => 'Illuminate\\Cache\\CacheServiceProvider',
'cache.psr6' => 'Illuminate\\Cache\\CacheServiceProvider',
'memcached.connector' => 'Illuminate\\Cache\\CacheServiceProvider',
'command.cache.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.cache.forget' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.clear-compiled' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.auth.resets.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.config.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.config.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.db.wipe' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.down' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.environment' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.event.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.event.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.event.list' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.key.generate' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.optimize' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.optimize.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.package.discover' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.failed' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.flush' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.forget' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.listen' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.restart' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.retry' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.work' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.route.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.route.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.route.list' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.seed' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'Illuminate\\Console\\Scheduling\\ScheduleFinishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'Illuminate\\Console\\Scheduling\\ScheduleRunCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.storage.link' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.up' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.view.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.view.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.cache.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.cast.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.channel.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.component.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.console.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.controller.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.event.generate' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.event.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.exception.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.factory.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.job.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.listener.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.mail.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.middleware.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.model.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.notification.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.notification.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.observer.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.policy.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.provider.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.failed-table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.queue.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.request.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.resource.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.rule.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.seeder.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.session.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.serve' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.stub.publish' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.test.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.vendor.publish' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'migration.repository' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'migration.creator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.fresh' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.install' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.refresh' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.reset' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.rollback' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.status' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'command.migrate.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'composer' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
'hash' => 'Illuminate\\Hashing\\HashServiceProvider',
'hash.driver' => 'Illuminate\\Hashing\\HashServiceProvider',
'mail.manager' => 'Illuminate\\Mail\\MailServiceProvider',
'mailer' => 'Illuminate\\Mail\\MailServiceProvider',
'Illuminate\\Mail\\Markdown' => 'Illuminate\\Mail\\MailServiceProvider',
'Illuminate\\Contracts\\Pipeline\\Hub' => 'Illuminate\\Pipeline\\PipelineServiceProvider',
'queue' => 'Illuminate\\Queue\\QueueServiceProvider',
'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider',
'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider',
'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider',
'queue.connection' => 'Illuminate\\Queue\\QueueServiceProvider',
'redis' => 'Illuminate\\Redis\\RedisServiceProvider',
'redis.connection' => 'Illuminate\\Redis\\RedisServiceProvider',
'auth.password' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
'auth.password.broker' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
'translator' => 'Illuminate\\Translation\\TranslationServiceProvider',
'translation.loader' => 'Illuminate\\Translation\\TranslationServiceProvider',
'validator' => 'Illuminate\\Validation\\ValidationServiceProvider',
'validation.presence' => 'Illuminate\\Validation\\ValidationServiceProvider',
'command.tinker' => 'Laravel\\Tinker\\TinkerServiceProvider',
),
'when' =>
array (
'Illuminate\\Broadcasting\\BroadcastServiceProvider' =>
array (
),
'Illuminate\\Bus\\BusServiceProvider' =>
array (
),
'Illuminate\\Cache\\CacheServiceProvider' =>
array (
),
'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider' =>
array (
),
'Illuminate\\Hashing\\HashServiceProvider' =>
array (
),
'Illuminate\\Mail\\MailServiceProvider' =>
array (
),
'Illuminate\\Pipeline\\PipelineServiceProvider' =>
array (
),
'Illuminate\\Queue\\QueueServiceProvider' =>
array (
),
'Illuminate\\Redis\\RedisServiceProvider' =>
array (
),
'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider' =>
array (
),
'Illuminate\\Translation\\TranslationServiceProvider' =>
array (
),
'Illuminate\\Validation\\ValidationServiceProvider' =>
array (
),
'Laravel\\Tinker\\TinkerServiceProvider' =>
array (
),
),
);
+77
View File
@@ -0,0 +1,77 @@
# Staging stack — isolated from local docker-compose.yml (8080 / 3306)
# and from other apps on the server (unique project name + host ports).
#
# Local:
# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --build
#
# CI (image already in registry):
# APP_IMAGE=git.koppkb.com/KoPKB/api_arrahn IMAGE_TAG=<sha> \
# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --no-build
#
# Host nginx reverse-proxies the public domain to 127.0.0.1:${HTTP_PORT}.
# See docker/nginx/host-proxy.example.conf
#
# If 8090 or 3308 is already taken, set HTTP_PORT / MYSQL_PUBLISH_PORT in .env.staging.
name: api_arrahn_staging
services:
app:
image: ${APP_IMAGE:-api_arrahn}:${IMAGE_TAG:-staging}
build:
context: .
dockerfile: docker/php/Dockerfile
target: staging
container_name: api_arrahn_staging_app
working_dir: /var/www/html
volumes:
- storage_staging:/var/www/html/storage
- ./.env.staging:/var/www/html/.env.staging:ro
env_file:
- .env.staging
environment:
APP_ENV: staging
USE_STAGING_ENV: "true"
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
mysql:
condition: service_healthy
restart: unless-stopped
web:
image: nginx:1.25-alpine
container_name: api_arrahn_staging_web
ports:
- "${HTTP_PORT:-8090}:80"
volumes:
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
restart: unless-stopped
mysql:
image: mysql:8.0
container_name: api_arrahn_staging_mysql
command: --default-authentication-plugin=mysql_native_password
ports:
- "127.0.0.1:${MYSQL_PUBLISH_PORT:-3308}:3306"
environment:
MYSQL_DATABASE: erahn_xtra
MYSQL_USER: xtrauser
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
volumes:
- mysql_staging_data:/var/lib/mysql
- ./docker/mysql/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
interval: 5s
timeout: 5s
retries: 30
start_period: 20s
restart: unless-stopped
volumes:
mysql_staging_data:
storage_staging:
+40
View File
@@ -0,0 +1,40 @@
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
target: development
working_dir: /var/www/html
volumes:
- ./:/var/www/html:cached
environment:
APP_ENV: local
APP_DEBUG: "true"
depends_on:
- mysql
web:
image: nginx:1.25-alpine
ports:
- "8080:80"
volumes:
- ./:/var/www/html:cached
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: erahn_xtra
MYSQL_USER: xtrauser
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
@@ -0,0 +1,7 @@
CREATE DATABASE IF NOT EXISTS master_erahn;
CREATE DATABASE IF NOT EXISTS kaunter_erahn;
GRANT ALL PRIVILEGES ON master_erahn.* TO 'xtrauser'@'%';
GRANT ALL PRIVILEGES ON kaunter_erahn.* TO 'xtrauser'@'%';
GRANT ALL PRIVILEGES ON erahn_xtra.* TO 'xtrauser'@'%';
FLUSH PRIVILEGES;
+36
View File
@@ -0,0 +1,36 @@
server {
listen 80;
server_name _;
root /var/www/html/public;
index index.php index.html;
charset utf-8;
client_max_body_size 50M;
location / {
try_files $uri $uri/ @php;
}
location @php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/html/public/index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_read_timeout 120s;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_read_timeout 120s;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
+51
View File
@@ -0,0 +1,51 @@
FROM php:7.4-fpm AS base
WORKDIR /var/www/html
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git \
pkg-config \
unzip \
libonig-dev \
libzip-dev \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j"$(nproc)" \
pdo_mysql \
mbstring \
bcmath \
zip \
exif \
gd \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
COPY docker/php/php.ini /usr/local/etc/php/conf.d/app.ini
COPY docker/php/zz-clear-env.conf /usr/local/etc/php-fpm.d/zz-clear-env.conf
COPY docker/php/entrypoint.sh /usr/local/bin/app-entrypoint.sh
RUN chmod +x /usr/local/bin/app-entrypoint.sh \
&& usermod -u 1000 www-data && groupmod -g 1000 www-data
ENTRYPOINT ["app-entrypoint.sh"]
CMD ["php-fpm"]
FROM base AS staging
COPY --chown=www-data:www-data . /var/www/html
RUN composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader \
&& mkdir -p \
storage/logs \
storage/framework/cache/data \
storage/framework/views \
storage/framework/sessions \
storage/app/public \
bootstrap/cache \
&& chown -R www-data:www-data storage bootstrap/cache vendor
FROM base AS development
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
set -e
cd /var/www/html
if [ "${USE_STAGING_ENV:-false}" = "true" ] && [ -f .env.staging ]; then
cp .env.staging .env
fi
if [ -f composer.json ]; then
if [ -f vendor/autoload.php ] && [ "${USE_STAGING_ENV:-false}" = "true" ]; then
: # vendor is baked into the staging image
elif [ "${USE_STAGING_ENV:-false}" = "true" ]; then
composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader
else
composer install --no-interaction --prefer-dist
fi
fi
mkdir -p \
storage/logs \
storage/framework/cache/data \
storage/framework/views \
storage/framework/sessions \
storage/app/public \
bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
exec docker-php-entrypoint "$@"
+4
View File
@@ -0,0 +1,4 @@
memory_limit=512M
upload_max_filesize=50M
post_max_size=50M
max_execution_time=120
+3
View File
@@ -0,0 +1,3 @@
[www]
; Pass container env vars (from compose env_file) through to PHP workers.
clear_env = no
+4
View File
@@ -21,6 +21,10 @@ use App\Http\Controllers\TransactionOnlineTrailController;
use App\Http\Controllers\Reports\RingkasanHarianController;
use App\Transaction;
$router->get('/health', function () {
return response()->json(['status' => 'ok']);
});
$router->group(['namespace' => '\Rap2hpoutre\LaravelLogViewer'], function() use ($router) {
$router->get('logs', 'LogViewerController@index');
});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"pPCoNelToRSPVvcOpFJ9UPNL4OPbg1mOw5w7XFbk";s:9:"_previous";a:1:{s:3:"url";s:45:"http://host.docker.internal:8080/api/cawangan";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"APKROssit2tVHiUufjaxls9uiE2T3ApfYTis9uCN";s:9:"_previous";a:1:{s:3:"url";s:51:"http://host.docker.internal:8080/api/cawangan/admin";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"hSeaZ7y2zh6WA9ccSR7VnNQu5BkUJj0Cw7DlZwAK";s:9:"_previous";a:1:{s:3:"url";s:34:"http://localhost:8080/api/cawangan";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"X9i69jljkVUOXP3PDfjYRIjn8fuNAPqY5n7Ac06R";s:9:"_previous";a:1:{s:3:"url";s:51:"http://host.docker.internal:8080/api/cawangan/admin";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"E9RodkVq3TqEaBdhJ4x3VuQpCM8loXLJdsDpFWw2";s:9:"_previous";a:1:{s:3:"url";s:45:"http://host.docker.internal:8080/api/cawangan";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
@@ -0,0 +1 @@
a:3:{s:6:"_token";s:40:"xJQ7j1HbsW9UweaiBBAhMPjXcIh4JyY5rkrjLMZY";s:9:"_previous";a:1:{s:3:"url";s:51:"http://host.docker.internal:8080/api/cawangan/admin";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}