An e-commerce (fruits & vegetables) build using Laravel, Filament, Inertia.js, React.js, Shadcn/ui, Midtrans, RajaOngkir, Google SSO
- Modern E-Commerce: Seamless shopping experience for fruits and vegetables.
- Payment Gateway: Secure transactions integrated with Midtrans.
- Shipping Integration: Real-time shipping cost calculations via RajaOngkir.
- Secure Auth: One-tap login using Google SSO (Socialite).
- Admin Dashboard: Powerful resource management with Filament PHP.
- Fast Frontend: Reactive UI powered by React.js, Inertia.js, and Shadcn/ui.
- Docker Ready: Optimized multi-stage builds and container orchestration.
- Automated CI/CD: Seamless deployment to servers behind NAT using Cloudflare Tunnel.
Ensure you have PHP 8.2+, Composer, Node.js, and MySQL installed.
# Clone the repository
git clone https://github.com/armandwipangestu/freshbite.git
cd freshbite
# Install PHP dependencies
composer install
# Install JS dependencies
npm install
# Setup environment
cp .env.example .env
php artisan key:generateUpdate your .env with your database credentials, then run:
php artisan migrate --seedYou will need two terminals running:
Terminal A (Vite):
npm run devTerminal B (Laravel):
php artisan serveThis project includes a fully containerized setup with Nginx, PHP-FPM, Queue Workers, and a Scheduler.
Create a .env.docker file or use your existing .env. Ensure DB_HOST is set to your database service name if using a shared network. Create a .env.freshbite-db file for the database service.
Here an example of .env.freshbite-db:
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_DATABASE=freshbite
MYSQL_USER=your_database_user
MYSQL_PASSWORD=your_database_passwordUse the following example as a guide for your docker-compose.yml:
services:
db:
image: mariadb:12.0.2-noble
container_name: freshbite-db
restart: unless-stopped
env_file: .env.freshbite-db
volumes:
- ./docker-data/freshbite-db:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 3s
retries: 5
start_period: 5s
logging:
driver: "json-file"
options:
max-size: "500M"
max-file: "3"
ports:
- "3309:3306"
app:
image: ghcr.io/armandwipangestu/freshbite:latest
container_name: freshbite-app
restart: unless-stopped
env_file: .env.production
environment:
- RUN_MIGRATIONS=true
volumes:
- ./storage:/var/www/html/storage
logging:
driver: "json-file"
options:
max-size: "500M"
max-file: "3"
depends_on:
db:
condition: service_healthy
networks:
- app-network
proxy:
image: ghcr.io/armandwipangestu/freshbite-proxy:latest
container_name: freshbite-proxy
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./storage/app/public:/var/www/html/public/storage
logging:
driver: "json-file"
options:
max-size: "500M"
max-file: "3"
depends_on:
- app
networks:
- app-network
queue:
image: ghcr.io/armandwipangestu/freshbite:latest
container_name: freshbite-queue
restart: unless-stopped
env_file: .env.production
environment:
- RUN_MIGRATIONS=false
volumes:
- ./storage:/var/www/html/storage
command: php artisan queue:work --verbose --tries=3 --timeout=90
logging:
driver: "json-file"
options:
max-size: "500M"
max-file: "3"
depends_on:
- app
networks:
- app-network
scheduler:
image: ghcr.io/armandwipangestu/freshbite:latest
container_name: freshbite-scheduler
restart: unless-stopped
env_file: .env.production
environment:
- RUN_MIGRATIONS=false
volumes:
- ./storage:/var/www/html/storage
command: php artisan schedule:run
logging:
driver: "json-file"
options:
max-size: "500M"
max-file: "3"
depends_on:
- app
networks:
- app-network
networks:
app-network:
driver: bridgeRun the stack:
docker compose up -d- Optimization: Uses a custom base image for PHP dependencies to reduce build times by >70%.
- Reverse Proxy: Nginx is configured to serve static assets and proxy PHP requests to the FPM container.
- Workers: A dedicated queue worker handles background jobs (emails, etc.).
- Scheduler: A lightweight cron-like service runs Laravel schedule commands.
- Saweria: https://saweria.co/armandwipangestu