A modern, multi-tenant clinic management system built with Laravel 11, Vue 3, and TailwindCSS. Designed for touch-optimized interfaces with per-tenant theming and database isolation.
- Backend: Laravel 11.x
- Frontend: Vue 3 + Inertia.js
- Styling: TailwindCSS (with dark mode support)
- Multi-tenancy: stancl/tenancy (database-per-tenant)
- Authentication: Laravel Breeze (Fortify)
- Permissions: Spatie Laravel Permission
- Database: MySQL 8.0
- Cache/Queue: Redis + Laravel Horizon
- Deployment: Docker (Nginx + PHP-FPM + MySQL + Redis)
- Database-per-tenant isolation using stancl/tenancy
- Subdomain-based tenant identification
- Per-tenant theming (logo, colors, clinic name)
- Central admin panel for tenant management
- Laravel Breeze authentication
- Role-based access control (RBAC)
- Pre-configured roles:
- Admin: Full system access
- Doctor: Patient management, encounters, prescriptions
- Nurse: Patient care, encounters, appointments
- Receptionist: Appointments, patient registration
Modular architecture for scalability:
app/Modules/Patient/- Patient managementapp/Modules/Encounter/- Clinical encountersapp/Modules/Prescription/- Prescription handlingapp/Modules/Appointment/- Appointment schedulingapp/Modules/Shared/- Shared utilities
- Touch-optimized interface (large buttons, spacious layout)
- Dark mode support
- Responsive design (mobile, tablet, desktop)
- Modern TailwindCSS styling
- PrescriptionGateway adapter for external pharmacy systems
- Interface-based design for easy integration
- Dummy implementation included
- PHP 8.2+
- MySQL 8.0
- Composer
- Node.js 18+ & NPM
- XAMPP installed
- Clone/Navigate to project
cd c:\xampp\htdocs\phongkham- Install PHP dependencies
c:\xampp\php\php.exe c:\xampp\php\composer install- Install Node dependencies
npm install- Configure environment
cp .env.example .envEdit .env:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=phongkham
DB_USERNAME=root
DB_PASSWORD=
REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1- Generate application key
c:\xampp\php\php.exe artisan key:generate- Run migrations
c:\xampp\php\php.exe artisan migrate --seed- Create storage link
c:\xampp\php\php.exe artisan storage:link- Build frontend assets
npm run build
# or for development with hot reload
npm run dev- Start XAMPP
- Start Apache
- Start MySQL
- Access application
- Main site:
http://localhost/phongkham/public - Configure virtual host for cleaner URLs (see below)
- Docker Engine 20.10+
- Docker Compose 2.0+
- Clone repository on VPS
git clone <repository-url> /var/www/phongkham
cd /var/www/phongkham- Copy environment file
cp .env.example .env- Update .env for Docker
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=phongkham
DB_USERNAME=phongkham
DB_PASSWORD=secret
REDIS_CLIENT=predis
REDIS_HOST=redis
QUEUE_CONNECTION=redis- Build and start containers
docker-compose up -d --build- Run migrations inside container
docker-compose exec php php artisan migrate --seed- Generate key
docker-compose exec php php artisan key:generate- Build assets
docker-compose exec node npm install
docker-compose exec node npm run build- Access application
- Main site:
http://your-vps-ip - Configure domain/DNS for production
- Login as admin (default after seeding)
- Navigate to
/central/tenants - Click "Create New Tenant"
- Fill in:
- Subdomain (e.g.,
clinic1) - Clinic name
- Primary color
- Logo (optional)
- Admin user details
- Subdomain (e.g.,
- Submit - Tenant will be created with isolated database
Each tenant is accessible via subdomain:
http://clinic1.localhost/(local)http://clinic1.yourdomain.com/(production)
Seed includes default roles. Assign roles to users:
$user->assignRole('doctor');Check permissions in views:
<template v-if="$page.props.auth.user.roles.includes('admin')">
<!-- Admin only content -->
</template>Edit config/tenancy.php:
'tenant_model' => \App\Models\Tenant::class,
'central_domains' => [
'localhost',
'yourdomain.com',
],Themes stored in tenant_themes table:
clinic_name: Display namelogo_path: Logo file pathprimary_color: Hex color codesecondary_color: Hex color code
Edit C:\xampp\apache\conf\extra\httpd-vhosts.conf:
<VirtualHost *:80>
DocumentRoot "C:/xampp/htdocs/phongkham/public"
ServerName phongkham.test
ServerAlias *.phongkham.test
<Directory "C:/xampp/htdocs/phongkham/public">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>Add to C:\Windows\System32\drivers\etc\hosts:
127.0.0.1 phongkham.test
127.0.0.1 clinic1.phongkham.test
php artisan queue:workdocker-compose exec horizon php artisan horizonnpm run dev # Development with hot reload
npm run build # Production buildphp artisan testphongkham/
├── app/
│ ├── Http/
│ │ └── Controllers/
│ │ └── CentralAdmin/
│ │ └── TenantController.php
│ ├── Models/
│ │ ├── Tenant.php
│ │ ├── TenantTheme.php
│ │ └── User.php
│ ├── Modules/
│ │ ├── Patient/
│ │ ├── Encounter/
│ │ ├── Prescription/
│ │ ├── Appointment/
│ │ └── Shared/
│ └── Services/
│ └── PrescriptionGateway/
│ ├── PrescriptionGatewayInterface.php
│ └── DummyPrescriptionGateway.php
├── database/
│ ├── migrations/
│ │ ├── tenant/ # Tenant-specific migrations
│ │ └── *.php # Central migrations
│ └── seeders/
│ └── RoleSeeder.php
├── docker/
│ ├── nginx/
│ ├── php/
│ └── mysql/
├── resources/
│ ├── js/
│ │ ├── Pages/
│ │ │ ├── CentralAdmin/
│ │ │ │ └── Tenants/
│ │ │ │ ├── Index.vue
│ │ │ │ └── Create.vue
│ │ │ └── Dashboard.vue
│ │ └── Components/
│ └── views/
├── routes/
│ ├── web.php
│ └── tenant.php # Tenant-specific routes
└── docker-compose.yml
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Install Docker Compose
sudo apt install docker-compose -y
# Add user to docker group
sudo usermod -aG docker $USER# Clone repository
git clone <repo> /var/www/phongkham
cd /var/www/phongkham
# Copy and configure .env
cp .env.example .env
nano .env
# Start services
docker-compose up -d --build
# Run migrations
docker-compose exec php php artisan migrate --seed
# Set permissions
sudo chown -R www-data:www-data storage bootstrap/cacheFor SSL and domain routing, install Nginx on host:
sudo apt install nginx certbot python3-certbot-nginx -yCreate /etc/nginx/sites-available/phongkham:
server {
listen 80;
server_name yourdomain.com *.yourdomain.com;
location / {
proxy_pass http://localhost:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable site and SSL:
sudo ln -s /etc/nginx/sites-available/phongkham /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d yourdomain.com -d *.yourdomain.comchmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cachephp artisan cache:clear
php artisan config:clear
php artisan view:clear
php artisan route:clearcomposer dump-autoload- Implement Patient module
- Implement Encounter module
- Implement Prescription module with external gateway
- Implement Appointment module
- Add reporting dashboard
- Add multi-language support
- Add audit logs
- Add backup automation
Proprietary - All rights reserved
For support, contact: [[email protected]]