Saltar al contenido
← Volver a proyectos

Absensi Karyawan Gps Barcode

The skeleton application for the Laravel framework.

#Aplikasi Web Absensi Karyawan QR Code GPS

Continuous Integration GitHub Repo stars GitHub Contributors GitHub forks GitHub watchers Laravel PHP
Aplikasi Web Absensi Karyawan QR Code GPS

Aplikasi web absensi karyawan menggunakan QR Code dan GPS.

#Teknologi yang Digunakan

#Cara Menjalankan

Aplikasi ini tidak mewajibkan Docker. Tersedia dua cara yang setara, pilih salah satu:

  1. Instalasi tradisional: PHP, Composer, Node.js/Bun, dan MySQL dipasang langsung di mesin. Lihat bagian Instalasi.
  2. Docker Compose: seluruh stack berjalan di dalam container tanpa perlu tool apa pun di host. Lihat bagian Menjalankan dengan Docker dan Menjalankan di Produksi (Docker).

Perubahan kode aplikasi tidak membedakan kedua mode; file-file Docker (Dockerfile, folder docker/, docker-compose*.yml) hanya digunakan saat menjalankan lewat Docker.

#Instalasi

#Prasyarat


  1. Clone/download repository ini

  2. Buat database (jika tidak menggunakan SQLite)

    -- nama database sesuaikan dengan yang ada di .env
    CREATE DATABASE db_absensi_karyawan;
    
  3. Jalankan perintah

    # untuk membuat file `.env`
    composer run-script post-root-package-install # atau cp .env.example .env
    
    # untuk instalasi dependency php
    composer install
    
    # untuk instalasi dependency javascript
    npm install # atau bun install
    
    # untuk membuat key aplikasi
    php artisan key:generate --ansi --force
    
    # untuk menghubungkan storage ke public
    php artisan storage:link
    
    # untuk membuat tabel database [BUAT DATABASE DAHULU]
    php artisan migrate
    
    # untuk membuat file css dan javascript yang diperlukan
    npm run build # atau bun run build
    

    Menjalankan aplikasi (local)

    php artisan serve
    

#Seeder

Pilih salah satu opsi berikut:

  1. Jalankan perintah berikut untuk menyiapkan data awal

    php artisan db:seed DatabaseSeeder
    
  2. (Recommended untuk development) Jalankan perintah berikut untuk menyiapkan data awal beserta data dummy (absensi & karyawan)

    php artisan db:seed FakeDataSeeder
    

Akun default hasil seeder:

Role Email Password
Super Admin superadmin@example.com superadmin
Admin admin@example.com admin

#Menjalankan dengan Docker

Cara ini tidak membutuhkan PHP, Composer, Node.js/Bun, maupun MySQL di mesin host. Semuanya berjalan di dalam container.

#Prasyarat

#Menjalankan

  1. Clone/download repository ini

  2. Siapkan file .env. Jika belum ada, salin dari contoh:

    cp .env.example .env
    

    Nilai DB_HOST, DB_PORT, DB_PASSWORD, dan APP_URL akan ditimpa oleh environment di docker-compose.yml, jadi .env bawaan aman digunakan.

  3. Build dan jalankan stack (aplikasi + MySQL):

    docker compose up -d
    
  4. Tunggu sampai container absensi-app selesai inisialisasi. Pantau dengan:

    docker compose logs -f app
    

    Saat pertama kali dijalankan, container secara otomatis melakukan:

    • setup permission storage/ dan bootstrap/cache
    • menunggu database siap
    • generate APP_KEY (jika belum ada)
    • migrate
    • seeder dasar (DatabaseSeeder) hanya saat database masih kosong dan APP_ENV=local
  5. Aplikasi bisa diakses di http://localhost:8000, login dengan akun hasil seeder pada tabel di atas.

#Seeder Data Dummy (FakeDataSeeder) di Docker

Seeder otomatis hanya menjalankan DatabaseSeeder. Untuk mengisi data dummy absensi dan karyawan:

# reset total database, lalu isi data awal + data dummy
docker compose exec app php artisan migrate:fresh --force --seed --seeder=FakeDataSeeder

# atau isi data dummy tanpa mereset data yang sudah ada
docker compose exec app php artisan db:seed FakeDataSeeder --force

Setelah docker compose down -v (hapus volume), langkah up berikutnya akan otomatis migrate lagi dan menjalankan seeder dasar karena database kembali kosong.

#Tools Tambahan (Opsional)

phpMyAdmin dan Redis tersedia sebagai profile tools agar tidak ikut jalan secara default:

docker compose --profile tools up -d
  • phpMyAdmin: http://localhost:8080
  • MySQL juga terekspos ke host di port 3306 (user root, password secret)
  • Redis di port 6379 (belum dipakai aplikasi, disiapkan untuk scaling queue/cache)

#Perintah yang Sering Dipakai

# menjalankan artisan di dalam container
docker compose exec app php artisan <perintah>

# membuka tinker
docker compose exec app php artisan tinker

# melihat log aplikasi
docker compose logs -f app

# me-restart proses setelah mengubah kode PHP
docker compose restart app

# memberhentikan stack, data database tetap tersimpan
docker compose down

# memberhentikan stack sekaligus menghapus volume database/storage
docker compose down -v

Catatan:

  • Kode sumber di-bind-mount ke container sehingga perubahan langsung terlihat. Namun OPcache dikonfigurasi tanpa revalidasi (opcache.validate_timestamps=0 untuk performa produksi), jadi setelah mengedit file PHP jalankan docker compose restart app.
  • Konfigurasi container dibaca dari env_file (docker/dev.env untuk lokal, docker/prod.env untuk produksi), bukan dari file .env. Variabel environment selalu menang atas .env yang mungkin ada di host.
  • Perintah docker compose exec berjalan sebagai root di dalam container. File yang dibuat artisan (misal hasil export XLSX) bisa berpemilik root; perbaiki dengan chown bila diperlukan.

#Menjalankan di Produksi (Docker)

Mode produksi memakai overlay docker-compose.prod.yml yang digabung dengan compose dasar. Kredensial tidak lagi berasal dari docker/dev.env, melainkan dari docker/prod.env yang tidak pernah di-commit (sudah masuk .gitignore).

#Persiapan

  1. Pastikan Docker dan Docker Compose terpasang di server, lalu clone repository.

  2. Buat file environment produksi:

    cp docker/prod.env.example docker/prod.env
    chmod 600 docker/prod.env
    nano docker/prod.env   # isi semua nilai CHANGE_ME
    
  3. Generate APP_KEY sebelum start pertama, lalu tempel ke docker/prod.env:

    echo "APP_KEY=base64:$(openssl rand -base64 32)"
    
  4. Isi kredensial database. Dua aturan penting:

    • DB_PASSWORD harus sama dengan MYSQL_PASSWORD
    • MYSQL_ROOT_PASSWORD wajib berbeda dari keduanya

    Pasangan user MYSQL_USER/MYSQL_PASSWORD hanya dibuat oleh image MySQL saat inisialisasi volume pertama kali. Jika volume sudah terlanjur ada, buat user secara manual atau hapus volume db sebelum start.

#Menjalankan

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

Saat start, entrypoint secara otomatis:

  • menunggu database siap lalu menjalankan migrate
  • membangun ulang cache konfigurasi, route, dan view (config:cache, route:cache, view:cache)
  • menyalakan nginx, php-fpm, queue worker, dan scheduler via supervisord

Seeder tidak dijalankan otomatis di mode produksi. Jalankan manual bila benar-benar dibutuhkan:

docker compose exec app php artisan db:seed FakeDataSeeder --force

#Verifikasi

# health check internal
docker compose exec app curl -f http://localhost:8000/up

# status keempat proses
docker compose exec app supervisorctl -c /etc/supervisor/conf.d/supervisord.conf status

#Reverse Proxy dan HTTPS

Secara default tidak ada port yang dipublish. Buka komentar pada blok ports di docker-compose.prod.yml agar aplikasi tersedia di 127.0.0.1:8000 host, lalu pasang reverse proxy di depannya untuk terminasi SSL:

server {
    listen 443 ssl;
    server_name absensi.perusahaan.co.id;

    ssl_certificate     /etc/letsencrypt/live/absensi.perusahaan.co.id/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/absensi.perusahaan.co.id/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        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;
    }
}

Header X-Forwarded-Proto https diperlukan agar Laravel menghasilkan URL https.

#Update Aplikasi

git pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

Entrypoint akan migrate skema baru dan membangun ulang semua cache saat boot, jadi tidak ada langkah manual setelah deploy.

#Backup Database

docker compose exec db sh -c 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE"' | gzip > backup-$(date +%F).sql.gz

Restore:

gunzip < backup-2026-08-25.sql.gz | docker compose exec -T db sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE"'

#Ringkasan Variabel Sensitif di docker/prod.env

Variabel Fungsi
APP_KEY Enkripsi session dan data terenkripsi; jangan diubah setelah produksi berjalan
DB_PASSWORD + MYSQL_PASSWORD Password user aplikasi; kedua nilai harus identik
MYSQL_ROOT_PASSWORD Password root MySQL untuk backup/administrasi
MAIL_* Kredensial SMTP untuk email keluar
APP_URL / ASSET_URL Domain publik; wajib benar agar asset dan link valid

#Fitur & Pratinjau

#User/Karyawan

Scan Page Scan Page (Mobile)
Scan Scan mobile
Riwayat Absensi Karyawan Pengajuan Izin Riwayat Pengajuan Izin
Riwayat Absensi Pengajuan Izin Riwayat Pengajuan Izin

#Admin & Superadmin

Dashboard Admin Dashboard Admin Dark
Dashboard Dashboard Dark
Barcode Create/Edit Barcode
Barcode Create Edit Barcode
Absensi Karyawan
Absensi per hari Absensi per minggu Absensi per bulan
Absensi per hari Absensi per minggu Absensi per bulan
Data Karyawan Create/Edit Data Karyawan
Data Karyawan Create Edit Data Karyawan
Export/Import from/to XLSX
Export/Import Data Karyawan & User Export/Import Data Karyawan & User + Preview Data
Export/Import Data Karyawan Export/Import Data Karyawan + Preview
Export/Import Data Absensi & User Export/Import Data Absensi & User + Preview Data
Export/Import Data Absensi Export/Import Data Absensi + Preview
Pengajuan Izin (Admin) Detail Pengajuan Izin
Pengajuan Izin (Admin) Detail Pengajuan Izin

#Device Restriction

Fitur pembatasan login perangkat untuk mencegah titip absen. Device token (UUID) otomatis digenerate dan disimpan di localStorage browser saat login.

  • Login dari perangkat berbeda ditolak

  • Admin dapat mereset perangkat dari menu Employee

  • Admin & superadmin tidak terpengaruh

  • Dapat dinonaktifkan via .env:

    DEVICE_RESTRICTION_ENABLED=false
    

#Status Incomplete

Karyawan yang absen masuk tapi pulang sebelum jam shift berakhir akan mendapatkan status 'Tidak Tuntas' (incomplete), bukan 'Hadir'. Deteksi otomatis saat scan keluar.

#Alur Pengajuan Izin

Pengajuan izin tidak langsung disetujui, melainkan melalui proses approval:

  1. Karyawan mengajukan izin/sakit via form
  2. Status pengajuan: Menunggu (pending)
  3. Admin menyetujui atau menolak pengajuan
  4. Jika disetujui, data absensi otomatis terisi untuk rentang tanggal tersebut
  5. Karyawan dapat melihat status pengajuannya di halaman Riwayat Izin

#Donasi ❤

Donate trakteer Donate saweria

Atau, beri star...⭐⭐⭐⭐

Nueva versión disponible.