iSecure360
September 15, 2024
Web

iSecure360

iSecure360 simplifies security workforce and operations management with an intuitive interface, available on both mobile and web platforms. Its multi-tenant setup ensures isolated data for each client while maintaining a single codebase for efficient maintenance.

Laravel PHPMySQLBootstrap 4jQueryFlutter (Mobile App)

Overview

iSecure360 is a comprehensive security management platform designed to streamline guard attendance, patrol monitoring, incident reporting, and visitor tracking. It replaces manual logbooks with real-time insights, automated workflows, and customizable reports—empowering organizations to improve safety, compliance, and operational efficiency. With both web and mobile support, iSecure360 ensures seamless communication and accountability across security teams.

Key Achievements

  • Deployed across multiple client sites with 500+ active security staff managed daily
  • Reduced incident reporting time by 40% through real-time mobile app submissions
  • Enabled offline guard tour logging with auto-sync, ensuring 100% data accuracy even in low-connectivity environments
  • Improved visitor management efficiency by 60% using QR-based check-in and pre-registration workflows

iSecure360: Multi-Tenant Security Solution with Laravel

iSecure360 is a comprehensive security management application designed to protect businesses, institutions, and homes. Built on the Laravel framework, it supports a multi-tenant architecture, allowing multiple subdomains (e.g., client1.example.com, client2.example.com) to share a single codebase while using separate databases. This guide covers the deployment, multi-subdomain hosting, and tenant management for iSecure360 on an Ubuntu server with Nginx and MariaDB.

📖 Overview

iSecure360 simplifies security management with an intuitive interface, available on both mobile and web platforms. Its multi-tenant setup enables isolated data for each client (tenant) while maintaining a single codebase for efficient maintenance.

🚀 Key Features

  • Attendance Module: Track attendance efficiently.
  • Guard Tour Module: Monitor guard patrols.
  • Incident Reporting Module: Log and manage incidents.
  • Visitor Management Module: Streamline visitor registration and tracking.
  • Supervisor Checklist Module: Ensure compliance with checklists.
  • Occurrence Module: Record and analyze security events.
  • Employee Leave Module: Manage employee leave requests.
  • Payroll Module: Automate payroll processing for security personnel.
  • Uniform Module: Manage uniform inventory and assignments.
  • Officer Deployment and Roaster Planning Module: Schedule and deploy officers effectively.
  • 🛠️ Server Requirements

    To deploy iSecure360, ensure your server meets the following requirements:

    RequirementDetails
    PHP>= 8.1
    PHP ExtensionsCtype, cURL, DOM, Fileinfo, Filter, Hash, Mbstring, OpenSSL, PCRE, PDO, Session, Tokenizer, XML, MySQL, Zip, Unzip, JSON, BCMath, GD
    DatabaseMariaDB (MySQL-compatible)
    Web ServerNginx
    ComposerRequired for dependency management

    📦 Installation and Setup

    Follow these steps to set up iSecure360 with multi-tenant support on an Ubuntu server.

    1. Install PHP and Extensions

    Add the ppa:ondrej/php repository and install required PHP extensions.

    bash
    sudo add-apt-repository ppa:ondrej/php
    sudo apt update
    sudo apt install php-fpm php-mysql php-mbstring php-zip unzip php-json php-bcmath php-gd php-tokenizer php-xml
    

    Note: The zip and unzip extensions are required for Composer, and php-mysql enables MariaDB connectivity.

    2. Install Composer Dependencies

    Install the application’s Composer dependencies, optimized for production.

    bash
    composer install --optimize-autoloader --no-dev
    composer update
    

    Explanation:

  • --optimize-autoloader: Enhances performance.
  • --no-dev: Excludes development dependencies.
  • 3. Configure the `.env` File

    Set up environment-specific configurations.

    bash
    cp .env.example .env
    php artisan key:generate
    

    Steps:

  • Copy .env.example to .env.
  • Generate a unique APP_KEY.
  • Update .env with database credentials (central database and tenant databases).
  • 4. Set Directory Permissions

    Ensure the storage and bootstrap/cache directories are writable by the web server user (www-data).

    bash
    chown -R www-data:www-data .
    chown -R www-data:www-data storage bootstrap/cache
    chmod -R 775 storage
    chmod -R 775 bootstrap/cache
    

    5. Install and Configure MariaDB

    Install MariaDB for the central and tenant databases.

    bash
    sudo apt update
    sudo apt install mariadb-server
    sudo systemctl start mysql
    

    Secure the MariaDB installation:

    bash
    sudo mysql_secure_installation
    

    Prompt Responses:

  • Current root password: Press Enter (default is empty).
  • Change root password?: Select No.
  • Remove anonymous users?: Select Yes.
  • Disallow root login remotely?: Select Yes.
  • Remove test database?: Select Yes.
  • Reload privilege tables?: Select Yes.
  • 6. Create a Database User

    Create a MySQL user for the central database and grant privileges.

    bash
    sudo mysql -u root
    CREATE USER 'isecure360'@'localhost' IDENTIFIED BY 'your-password-here';
    GRANT ALL PRIVILEGES ON isecure360_central.* TO 'isecure360'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;
    

    Note: Update the .env file with these credentials for the central database.

    🏢 Multi-Subdomain Hosting Setup

    iSecure360 uses a single Laravel codebase to serve multiple subdomains, each with a separate database. This section outlines two approaches: hardcoded mapping and database-driven tenant management.

    Solution 1: Hardcoded Subdomain-to-Database Mapping

    Step 1: Configure Database in `config/database.php`

    Set up a default MySQL connection with dynamic overrides.

    php
    // config/database.php
    'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'isecure360_central'),
        'username' => env('DB_USERNAME', 'isecure360'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],
    

    Step 2: Dynamically Switch Database in `app/Providers/AppServiceProvider.php`

    Switch the database based on the subdomain.

    php
    // app/Providers/AppServiceProvider.php
    use IlluminateSupportFacadesDB;
    use IlluminateSupportFacadesConfig;
    
    public function boot()
    {
        $host = request()->getHost(); // e.g., client1.example.com
        $subdomain = explode('.', $host)[0]; // e.g., client1
    
        $databases = [
            'client1' => 'isecure360_client1',
            'client2' => 'isecure360_client2',
            'client3' => 'isecure360_client3',
        ];
    
        if (array_key_exists($subdomain, $databases)) {
            Config::set('database.connections.mysql.database', $databases[$subdomain]);
            DB::purge('mysql');
            DB::reconnect('mysql');
        }
    }
    

    Step 3: Configure Nginx for Subdomains

    Create an Nginx configuration in /etc/nginx/sites-available/isecure360 to handle multiple subdomains.

    nginx
    server {
        listen 80;
        listen [::]:80;
        server_name example.com client1.example.com client2.example.com client3.example.com;
        root /srv/isecure360/public;
    
        access_log /var/log/nginx/isecure360.access.log;
        error_log /var/log/nginx/isecure360.error.log;
    
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";
    
        index index.php;
    
        charset utf-8;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        error_page 404 /index.php;
    
        location ~ .php$ {
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            include fastcgi_params;
        }
    
        location ~ /.(?!well-known).* {
            deny all;
        }
    }
    
    bash
    sudo ln -s /etc/nginx/sites-available/isecure360 /etc/nginx/sites-enabled
    sudo nginx -t
    sudo systemctl restart nginx
    

    Solution 2: Database-Driven Tenant Management

    Step 1: Configure Database in `config/database.php` - Solution 2

    Use the same configuration as in Solution 1 (see above).

    Step 2: Create a `tenants` Table

    Create a migration for the tenants table to store tenant metadata.

    bash
    php artisan make:migration create_tenants_table
    
    php
    // database/migrations/xxxx_xx_xx_create_tenants_table.php
    use IlluminateDatabaseMigrationsMigration;
    use IlluminateDatabaseSchemaBlueprint;
    use IlluminateSupportFacadesSchema;
    
    return new class extends Migration {
        public function up(): void
        {
            Schema::create('tenants', function (Blueprint $table) {
                $table->id();
                $table->string('subdomain')->unique(); // e.g., client1
                $table->string('db_name'); // e.g., isecure360_client1
                $table->string('db_username');
                $table->string('db_password');
                $table->timestamps();
            });
        }
    
        public function down(): void
        {
            Schema::dropIfExists('tenants');
        }
    };
    

    Step 3: Seed the `tenants` Table (Optional)

    Create a seeder for initial tenant data.

    bash
    php artisan make:seeder TenantSeeder
    
    php
    // database/seeders/TenantSeeder.php
    use IlluminateDatabaseSeeder;
    use IlluminateSupportFacadesDB;
    
    class TenantSeeder extends Seeder
    {
        public function run(): void
        {
            DB::table('tenants')->insert([
                ['subdomain' => 'client1', 'db_name' => 'isecure360_client1', 'db_username' => 'client1_user', 'db_password' => 'secret1'],
                ['subdomain' => 'client2', 'db_name' => 'isecure360_client2', 'db_username' => 'client2_user', 'db_password' => 'secret2'],
                ['subdomain' => 'client3', 'db_name' => 'isecure360_client3', 'db_username' => 'client3_user', 'db_password' => 'secret3'],
            ]);
        }
    }
    

    Run migrations and seeders:

    bash
    php artisan migrate --seed
    

    Step 4: Dynamically Switch Database in `app/Providers/AppServiceProvider.php`

    Use the tenants table to switch databases.

    php
    // app/Providers/AppServiceProvider.php
    use IlluminateSupportFacadesDB;
    use IlluminateSupportFacadesConfig;
    use AppModelsTenant;
    
    public function boot()
    {
        $host = request()->getHost();
        $subdomain = explode('.', $host)[0];
    
        $tenant = Tenant::where('subdomain', $subdomain)->first();
    
        if ($tenant) {
            Config::set('database.connections.mysql.database', $tenant->db_name);
            Config::set('database.connections.mysql.username', $tenant->db_username);
            Config::set('database.connections.mysql.password', $tenant->db_password);
            DB::purge('mysql');
            DB::reconnect('mysql');
        }
    }
    

    Step 5: Configure Nginx for Subdomains

    Use the same Nginx configuration as in Solution 1 (see above).

    Step 6: Clear Config Cache

    Ensure configuration changes take effect.

    bash
    php artisan config:clear
    php artisan cache:clear
    

    🧑‍💼 Tenant Management Commands

    Manage tenants using custom Artisan commands.

    1. Create Central Database

    Initialize the central database for tenant metadata.

    bash
    php artisan db:create isecure360_central
    
    php artisan migrate --path=database/migrations/central
    

    2. Create Tenant

    Create a new tenant with a dedicated database.

    bash
    php artisan tenant:create <subdomain> <database>
    

    Example:

    bash
    php artisan tenant:create client1 isecure360_client1
    

    Description:

  • Registers the tenant with the subdomain.
  • Creates a database named database.
  • Configures the tenant for migrations and seeders.
  • 3. Migrate Tenants

    Run migrations for tenant databases.

    CommandDescription
    php artisan tenant:migrateMigrates all tenant databases.
    php artisan tenant:migrate Migrates a specific tenant’s database.
    php artisan tenant:migrate --freshDrops and recreates all tenant databases, then migrates.
    php artisan tenant:migrate --freshDrops and recreates a specific tenant’s database, then migrates.

    Examples:

    bash
    php artisan tenant:migrate
    php artisan tenant:migrate client1
    php artisan tenant:migrate --fresh
    php artisan tenant:migrate client1 --fresh
    

    4. Migrate and Seed Tenants

    Run migrations and seed tenant databases.

    CommandDescription
    php artisan tenant:migrate --seedMigrates and seeds all tenants with the default seeder.
    php artisan tenant:migrate --seedMigrates and seeds a specific tenant with the default seeder.
    php artisan tenant:migrate --seed --seeder=Migrates and seeds all tenants with a specific seeder.
    php artisan tenant:migrate --seed --seeder=Migrates and seeds a specific tenant with a specific seeder.

    Examples:

    bash
    php artisan tenant:migrate --seed
    php artisan tenant:migrate client1 --seed
    php artisan tenant:migrate --seed --seeder=TenantUserSeeder
    php artisan tenant:migrate client1 --seed --seeder=TenantUserSeeder
    

    🔒 SSL Configuration with Certbot

    Secure subdomains with SSL certificates.

    bash
    sudo apt install python3-certbot-nginx
    sudo certbot --nginx -d example.com -d client1.example.com -d client2.example.com -d client3.example.com
    

    Prompts:

  • Provide an email for renewal notices.
  • Agree to the Terms of Service (Y).
  • Opt out of sharing email with EFF (N).
  • Choose to redirect HTTP to HTTPS.
  • Expected Output:

    bash
    Congratulations! You have successfully enabled https://example.com, https://client1.example.com, ...
    

    Notes:

  • Test SSL at SSL Labs.
  • Certificates are stored in /etc/letsencrypt/live/example.com/.
  • Automate renewals with certbot renew.
  • ⏰ Schedule Laravel Commands

    Automate scheduled tasks using a cron job.

    bash
    crontab -e
    

    Add:

    bash
    * * * * * cd /srv/isecure360 && php artisan schedule:run >> /dev/null 2>&1
    

    Note: Replace /srv/isecure360 with your application’s path.

    🔍 Notes

  • Multi-Tenancy: Solution 1 (hardcoded mapping) is simpler for small setups; Solution 2 (database-driven) is scalable for dynamic tenant management.
  • Database Setup: Ensure each tenant database (e.g., isecure360_client1) exists and is accessible by the specified user.
  • Security: Protect the .env file and back up /etc/letsencrypt and databases regularly.
  • Testing: Verify subdomain routing, database switching, and feature functionality (e.g., Attendance Module) after setup.
  • Cron Jobs: Ensure the cron job runs as the correct user (e.g., www-data) to avoid permission issues.
  • Sathishkumar Ranganathan

    Full-stack Software Developer passionate about creating scalable web applications and smart systems with React.js, Next.js, PHP, and Flutter.

    Connect

    Keyboard Shortcuts

    K
    Search
    T
    Toggle theme
    2026 Sathishkumar Ranganathan. All rights reserved.
    Built withusing Next.js & Tailwind
    Sathishkumar Ranganathan | Portfolio