add docker

This commit is contained in:
arifal hidayat
2025-06-06 22:42:41 +07:00
parent 6f77120c33
commit 9437eb949f
16 changed files with 305 additions and 24 deletions

56
Dockerfile Normal file
View File

@@ -0,0 +1,56 @@
FROM node:18 AS node-base
# Development stage
FROM node-base AS development
WORKDIR /var/www
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
# Production stage
FROM php:8.2-fpm AS production
WORKDIR /var/www
# Install PHP extensions
RUN apt-get update && apt-get install -y \
git curl zip unzip libpng-dev libonig-dev libxml2-dev libzip-dev \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Copy application files
COPY . .
# Install dependencies
RUN composer install --no-dev --optimize-autoloader
# Install and build frontend assets
RUN npm install \
&& npm run build \
&& ls -la public/build \
&& mkdir -p public/assets \
&& cp -r public/build/* public/assets/ \
&& ls -la public/assets \
&& rm -rf node_modules \
&& rm -rf public/build
# Laravel caches
RUN php artisan config:clear \
&& php artisan route:clear \
&& php artisan view:clear \
&& php artisan optimize
RUN php artisan storage:link
# Permissions
RUN chown -R www-data:www-data /var/www && chmod -R 755 /var/www/storage /var/www/public
EXPOSE 9000
CMD ["php-fpm"]

View File

@@ -68,9 +68,9 @@ class UsersRoleMenuSeeder extends Seeder
// Attach User to role super admin
$accountSuperadmin = User::where('email', 'superadmin@sibedas.com')->first();
$accountUser = User::where('email', 'user@sibedas.com')->first();
$accountDefault = User::where('email','user@demo.com')->first();
// $accountDefault = User::where('email','user@demo.com')->first();
$accountSuperadmin->roles()->sync([$roles['superadmin']->id]);
$accountUser->roles()->sync([$roles['user']->id]);
$accountDefault->roles()->sync([$roles['user']->id]);
// $accountDefault->roles()->sync([$roles['user']->id]);
}
}

82
docker-compose.yml Normal file
View File

@@ -0,0 +1,82 @@
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
target: production
container_name: sibedas_app
restart: unless-stopped
environment:
APP_ENV: local
APP_DEBUG: true
APP_URL: http://localhost
VITE_APP_URL: http://localhost
DB_CONNECTION: mariadb
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: sibedas_db
DB_USERNAME: root
DB_PASSWORD: root
volumes:
- .:/var/www
depends_on:
- db
networks:
- sibedas_net
nginx:
image: nginx:alpine
container_name: sibedas_nginx
restart: unless-stopped
ports:
- "8000:80"
volumes:
- .:/var/www
- ./docker/nginx/conf.d/app.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- sibedas_net
db:
image: mariadb:10.6
container_name: sibedas_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: sibedas_db
MYSQL_USER: root
MYSQL_PASSWORD: root
ports:
- "3306:3306"
volumes:
- dbdata:/var/lib/mysql
- ./sibedas.sql:/docker-entrypoint-initdb.d/sibedas.sql
networks:
- sibedas_net
vite:
build:
context: .
dockerfile: Dockerfile
target: development
container_name: sibedas_vite
restart: unless-stopped
environment:
VITE_APP_URL: http://localhost
volumes:
- .:/var/www
- /var/www/node_modules
ports:
- "5173:5173"
networks:
- sibedas_net
volumes:
dbdata:
networks:
sibedas_net:
driver: bridge

View File

@@ -0,0 +1,50 @@
server {
listen 80;
index index.php index.html;
server_name localhost;
root /var/www/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Proxy Vite requests in development
location /@vite {
proxy_pass http://vite:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /build/ {
alias /var/www/public/build/;
access_log off;
expires max;
}
location /assets/ {
alias /var/www/public/assets/;
access_log off;
expires max;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ /\.ht {
deny all;
}
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot|otf)$ {
expires max;
log_not_found off;
}
}

59
docker/startup.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
# Enable error reporting
set -e
set -x
# Create necessary directories with proper permissions as root
mkdir -p /var/log/supervisor
mkdir -p /var/run/supervisor
chown -R www-data:www-data /var/log/supervisor
chown -R www-data:www-data /var/run/supervisor
chmod -R 775 /var/log/supervisor
chmod -R 775 /var/run/supervisor
# Create storage directories with proper permissions
mkdir -p /var/www/storage/logs
chown -R www-data:www-data /var/www/storage
chmod -R 775 /var/www/storage
# Ensure Laravel storage and cache directories are writable
chown -R www-data:www-data /var/www/bootstrap/cache
chmod -R 775 /var/www/bootstrap/cache
# Wait for database to be ready (with increased timeout and better error handling)
max_tries=30
count=0
echo "Waiting for database connection..."
# First, wait a bit for the database container to fully initialize
sleep 10
while ! php artisan db:monitor > /dev/null 2>&1; do
count=$((count + 1))
if [ $count -gt $max_tries ]; then
echo "Database connection timeout after $max_tries attempts"
echo "Checking database container status..."
# Try to connect directly to MySQL to get more detailed error
mysql -h db -u admindb_arifal -parifal201 -e "SELECT 1" || true
exit 1
fi
echo "Waiting for database... ($count/$max_tries)"
sleep 5
done
echo "Database connection established!"
# Run database-dependent commands
echo "Running database migrations..."
php artisan migrate --force
echo "Running database seeders..."
php artisan db:seed --force
echo "Optimizing Laravel..."
php artisan optimize:clear
php artisan optimize
# Start supervisor (which will manage PHP-FPM)
exec /usr/bin/supervisord -n -c /etc/supervisor/conf.d/supervisord.conf

View File

@@ -0,0 +1,18 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work --queue=default --timeout=82800 --tries=1
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/storage/logs/worker.log
stopasgroup=true
killasgroup=true
user=www-data
priority=10

2
package-lock.json generated
View File

@@ -1,5 +1,5 @@
{
"name": "sibedas-pbg-web",
"name": "www",
"lockfileVersion": 3,
"requires": true,
"packages": {

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

View File

@@ -5,6 +5,11 @@
@yield('css')
@if (app()->environment('production'))
<link rel="stylesheet" href="{{ asset('assets/icons-CHxf0fE3.css') }}">
<link rel="stylesheet" href="{{ asset('assets/style-Rwrkwlmx.css') }}">
<script src="{{ asset('assets/config-DqV4EBmE.js') }}"></script>
@else
@vite([ 'resources/scss/icons.scss', 'resources/scss/style.scss'])
@vite([ 'resources/js/config.js'])
@endif

View File

@@ -1,6 +1,10 @@
@yield('script-bottom')
@if (app()->environment('production'))
<script src="{{ asset('assets/app-DRUGm0ZO.js') }}"></script>
@else
@vite('resources/js/app.js')
@endif
@yield('scripts')

View File

@@ -56,8 +56,8 @@ Route::group(['middleware' => 'auth:sanctum'], function (){
// request assignments
Route::apiResource('request-assignments',RequestAssignmentController::class);
Route::get('/report-payment-recaps',[RequestAssignmentController::class, 'report_payment_recaps'])->name('report-payment-recaps');
Route::get('/report-pbg-ptsp',[RequestAssignmentController::class, 'report_pbg_ptsp'])->name('report-pbg-ptsp');
Route::get('/report-payment-recaps',[RequestAssignmentController::class, 'report_payment_recaps'])->name('api.report-payment-recaps');
Route::get('/report-pbg-ptsp',[RequestAssignmentController::class, 'report_pbg_ptsp'])->name('api.report-pbg-ptsp');
Route::controller(RequestAssignmentController::class)->group( function (){
Route::get('/district-payment-report/excel', 'export_excel_district_payment_recaps')->name('api.district-payment-report.excel');
Route::get('/district-payment-report/pdf', 'export_pdf_district_payment_recaps')->name('api.district-payment-report.pdf');

View File

@@ -3,6 +3,28 @@ import laravel from "laravel-vite-plugin";
import path from "path";
export default defineConfig({
server: {
host: '0.0.0.0',
hmr: {
host: 'localhost'
},
watch: {
usePolling: true
}
},
build: {
outDir: 'public/build',
assetsDir: 'assets',
manifest: true,
rollupOptions: {
output: {
manualChunks: undefined,
entryFileNames: 'assets/[name].js',
chunkFileNames: 'assets/[name].js',
assetFileNames: 'assets/[name].[ext]'
}
}
},
resolve: {
alias: {
"@": path.resolve(__dirname, "resources/js"),