Kara Plus is a Laravel-based operations platform for managing the end‑to‑end car‑rental workflow: rental requests, vehicles, customers, payments, approvals, and operational tasks. It ships with a production Docker stack and a single CI/CD workflow that runs tests and deploys on master.
Core workflows (from routes & Livewire pages)
- Rental requests: create/edit, detail, history, payment, reserved, pickup/return docs, inspections, approvals
- Cars & brands: list/detail/create/edit
- Customers: list/detail/history/debts/documents
- Payments: confirmation, processed list, edit
- Cashier dashboard
- Insurance management
- Agents & location costs
- Users & roles (Spatie Permission)
- Reports (user request stats)
Stack
- PHP 8.2, Laravel 11, Livewire 3
- MySQL 8, Redis
- Vite + Tailwind CSS
- Docker + Nginx
- GitHub Actions (CI/CD)
# Build and start services
docker compose --env-file .env.docker up -d --build
# App initialization
docker compose exec app php artisan key:generate
docker compose exec app php artisan migrate --forcePorts (from .env.docker)
- HTTP:
18000 - HTTPS:
18001 - phpMyAdmin:
18002 - Elasticsearch:
19200 - Kibana:
15601
Notes
- App config is in
.env; Docker config in.env.docker. - Ensure DB credentials in
.envmatch.env.docker.
composer install
npm install
php artisan key:generate
php artisan migrate
php artisan serve
npm run devphp artisan test
# or
vendor/bin/phpunitThis project includes a dual-layer audit pipeline:
- Canonical audit events in MySQL (
audit_eventstable) - Asynchronous export to Elasticsearch for Kibana-style querying
Required Docker env values for ELK:
ELASTICSEARCH_PASSWORD=your_password
KIBANA_SYSTEM_PASSWORD=your_password
KIBANA_LOGIN_USERNAME=kibana_admin
KIBANA_LOGIN_PASSWORD=your_password
KIBANA_BOOTSTRAP_URL=http://kibana:5601
KIBANA_DASHBOARD_URL=http://localhost:15601
AUDIT_RETENTION_DAYS=30After bringing Docker up, bootstrap Elasticsearch index lifecycle/template:
docker compose exec app php artisan audit:es-bootstrap
docker compose exec app php artisan audit:kibana-bootstrapUseful audit commands:
docker compose exec app php artisan audit:retry-export
docker compose exec app php artisan audit:health
docker compose exec app php artisan audit:prunePanel route (super-admin only):
/expert/reports/audit-center
Public endpoints are available under:
/api/public/reservations
Routes:
GET /bootstrapGET /brandsGET /models?brand=...GET /cars?model_id=...&pickup_date=...&return_date=...POST /quotePOST /
Rate limit:
120 requests / minute / IP(limiter key:reservation-public)
CORS:
- Controlled by
config/cors.php - Allowed origins from env:
CORS_ALLOWED_ORIGINS=*(comma separated for multiple origins)
Workflow file: .github/workflows/ci-cd.yml
Behavior:
- Pull Request → run tests only
- Push to master → run tests, then deploy if successful
Deploy script: deploy.sh
Main steps:
- Fetch + hard reset to
origin/master - Build & start Docker services
- Install Composer deps (no-dev)
- Create storage link
- Run migrations
- Normalize runtime permissions + rebuild Laravel caches as
www-data - Restart queue workers
The deploy script runs on the server and uses
git reset --hard. To avoid500 Permission deniedinstorage/framework/views, do not runartisanas root inside the app container.
Local backup script: scripts/backup-mysql-local.sh
Features:
- Dumps MySQL from the container and compresses output
- Keeps local backups in
backups/mysql - Retains only the last 10 days
Google Drive backup script: scripts/backup-mysql-to-gdrive.sh
Features:
- Dumps MySQL from the container, compresses output
- Uploads to Google Drive via
rclone - Applies retention (remote & local)
Required config:
.env(DB credentials)/etc/kara-plus/backup.env(rclone + retention settings)
Example cron (twice daily):
15 0,12 * * * /bin/bash /opt/apps/kara-plus/scripts/backup-mysql-local.sh >> /opt/apps/kara-plus/tmp/mysql-backup.log 2>&1
app/application logic (Livewire, Models, Controllers)routes/web routesresources/views and stylesdatabase/migrations and factoriesdocker/Docker and Nginx configurationscripts/operational scripts
- Keep secrets only in env files.
- Do not commit credentials.
- Restrict access to the self-hosted runner and server.