diff --git a/.env.example b/.env.example
index c0660ea..307d198 100644
--- a/.env.example
+++ b/.env.example
@@ -1,17 +1,14 @@
-APP_NAME=Laravel
+APP_NAME=RetroHub
APP_ENV=local
APP_KEY=
APP_DEBUG=true
-APP_URL=http://localhost
+APP_URL=http://localhost:8000
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
-# APP_MAINTENANCE_STORE=database
-
-# PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
@@ -20,14 +17,14 @@ LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
-DB_CONNECTION=sqlite
-# DB_HOST=127.0.0.1
-# DB_PORT=3306
-# DB_DATABASE=laravel
-# DB_USERNAME=root
-# DB_PASSWORD=
+DB_CONNECTION=pgsql
+DB_HOST=pgsql
+DB_PORT=5432
+DB_DATABASE=retrohub
+DB_USERNAME=sail
+DB_PASSWORD=password
-SESSION_DRIVER=database
+SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
@@ -35,31 +32,25 @@ SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
-QUEUE_CONNECTION=database
+QUEUE_CONNECTION=redis
-CACHE_STORE=database
-# CACHE_PREFIX=
-
-MEMCACHED_HOST=127.0.0.1
+CACHE_STORE=redis
REDIS_CLIENT=phpredis
-REDIS_HOST=127.0.0.1
+REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
-MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
-MAIL_FROM_ADDRESS="hello@example.com"
+MAIL_FROM_ADDRESS="hello@retrohub.local"
MAIL_FROM_NAME="${APP_NAME}"
-AWS_ACCESS_KEY_ID=
-AWS_SECRET_ACCESS_KEY=
-AWS_DEFAULT_REGION=us-east-1
-AWS_BUCKET=
-AWS_USE_PATH_STYLE_ENDPOINT=false
-
VITE_APP_NAME="${APP_NAME}"
+
+IGDB_CLIENT_ID=
+IGDB_CLIENT_SECRET=
+TGDB_API_KEY=
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 647e8a7..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,68 +0,0 @@
-FROM php:8.4-fpm-alpine
-
-# System dependencies
-RUN apk add --no-cache \
- nginx \
- supervisor \
- libpng-dev \
- libjpeg-turbo-dev \
- freetype-dev \
- libzip-dev \
- icu-dev \
- oniguruma-dev \
- libxml2-dev \
- zip \
- unzip \
- git \
- nodejs \
- npm
-
-# PHP extensions
-RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
- && docker-php-ext-install \
- pdo_pgsql \
- mbstring \
- exif \
- bcmath \
- gd \
- zip \
- intl \
- opcache
-
-# Composer
-COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
-
-# PHP config
-RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
-COPY docker/php.ini /usr/local/etc/php/conf.d/retrohub.ini
-
-# Working directory
-WORKDIR /var/www/retrohub
-
-# Copy application
-COPY . .
-
-# Install dependencies
-RUN composer install --no-dev --optimize-autoloader --no-interaction --no-scripts \
- && npm ci --omit=dev \
- && npm run build
-
-# Generate key and optimize
-RUN php artisan key:generate --force \
- && php artisan optimize:clear \
- && php artisan optimize
-
-# Permissions
-RUN chown -R www-data:www-data /var/www/retrohub \
- && chmod -R 755 /var/www/retrohub/storage \
- && chmod -R 755 /var/www/retrohub/bootstrap/cache
-
-# Nginx config
-COPY docker/nginx.conf /etc/nginx/http.d/default.conf
-
-# Supervisor
-COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
-
-EXPOSE 80
-
-CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
diff --git a/compose.yaml b/compose.yaml
new file mode 100644
index 0000000..b4cace6
--- /dev/null
+++ b/compose.yaml
@@ -0,0 +1,74 @@
+services:
+ laravel.test:
+ build:
+ context: ./vendor/laravel/sail/runtimes/8.4
+ dockerfile: Dockerfile
+ args:
+ WWWGROUP: '${WWWGROUP}'
+ image: sail-8.4/app
+ extra_hosts:
+ - 'host.docker.internal:host-gateway'
+ ports:
+ - '${APP_PORT:-80}:80'
+ - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
+ environment:
+ WWWUSER: '${WWWUSER}'
+ LARAVEL_SAIL: 1
+ XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
+ XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
+ IGNITION_LOCAL_SITES_PATH: '${PWD}'
+ volumes:
+ - '.:/var/www/html'
+ networks:
+ - sail
+ depends_on:
+ - redis
+ - pgsql
+ redis:
+ image: 'redis:alpine'
+ ports:
+ - '${FORWARD_REDIS_PORT:-6379}:6379'
+ volumes:
+ - 'sail-redis:/data'
+ networks:
+ - sail
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ retries: 3
+ timeout: 5s
+ pgsql:
+ image: 'postgres:18-alpine'
+ ports:
+ - '${FORWARD_DB_PORT:-5432}:5432'
+ environment:
+ PGPASSWORD: '${DB_PASSWORD:-secret}'
+ POSTGRES_DB: '${DB_DATABASE}'
+ POSTGRES_USER: '${DB_USERNAME}'
+ POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
+ volumes:
+ - 'sail-pgsql:/var/lib/postgresql'
+ - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
+ networks:
+ - sail
+ healthcheck:
+ test:
+ - CMD
+ - pg_isready
+ - '-q'
+ - '-d'
+ - '${DB_DATABASE}'
+ - '-U'
+ - '${DB_USERNAME}'
+ retries: 3
+ timeout: 5s
+networks:
+ sail:
+ driver: bridge
+volumes:
+ sail-redis:
+ driver: local
+ sail-pgsql:
+ driver: local
diff --git a/composer.json b/composer.json
index 9d8194b..84a79cf 100644
--- a/composer.json
+++ b/composer.json
@@ -24,6 +24,7 @@
"laravel/pail": "^1.2.5",
"laravel/pao": "^1.0.6",
"laravel/pint": "^1.27",
+ "laravel/sail": "^1.65",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6",
"phpunit/phpunit": "^12.5.12"
@@ -51,7 +52,7 @@
],
"dev": [
"Composer\\Config::disableProcessTimeout",
- "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
+ "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"./vendor/bin/sail up\" \"./vendor/bin/sail artisan queue:listen --tries=1 --timeout=0\" \"./vendor/bin/sail artisan pail --timeout=0\" \"npm run dev\" --names=sail,queue,logs,vite --kill-others"
],
"test": [
"@php artisan config:clear --ansi @no_additional_args",
diff --git a/composer.lock b/composer.lock
index c6da6b2..eb95943 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "e961b6bd629cc65fd5af967461bbad11",
+ "content-hash": "f382f92fb3a10d59a1cf9177199a5968",
"packages": [
{
"name": "brick/math",
@@ -8648,6 +8648,69 @@
},
"time": "2026-07-18T17:53:15+00:00"
},
+ {
+ "name": "laravel/sail",
+ "version": "v1.65.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/sail.git",
+ "reference": "d4b92139858d2a189a6302ca133e494f58afe20b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/sail/zipball/d4b92139858d2a189a6302ca133e494f58afe20b",
+ "reference": "d4b92139858d2a189a6302ca133e494f58afe20b",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/console": "^9.52.16|^10.0|^11.0|^12.0|^13.0",
+ "illuminate/contracts": "^9.52.16|^10.0|^11.0|^12.0|^13.0",
+ "illuminate/support": "^9.52.16|^10.0|^11.0|^12.0|^13.0",
+ "php": "^8.0",
+ "symfony/console": "^6.0|^7.0|^8.0",
+ "symfony/yaml": "^6.0|^7.0|^8.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0|^11.0",
+ "phpstan/phpstan": "^2.0"
+ },
+ "bin": [
+ "bin/sail"
+ ],
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Laravel\\Sail\\SailServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Sail\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Docker files for running a basic Laravel application.",
+ "keywords": [
+ "docker",
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/sail/issues",
+ "source": "https://github.com/laravel/sail"
+ },
+ "time": "2026-08-03T18:00:17+00:00"
+ },
{
"name": "mockery/mockery",
"version": "1.6.12",
diff --git a/database/migrations/2026_08_10_111315_create_users_table.php b/database/migrations/2026_08_10_000000_create_users_table.php
similarity index 100%
rename from database/migrations/2026_08_10_111315_create_users_table.php
rename to database/migrations/2026_08_10_000000_create_users_table.php
diff --git a/database/migrations/2026_08_10_111316_create_password_reset_tokens_table.php b/database/migrations/2026_08_10_000001_create_password_reset_tokens_table.php
similarity index 100%
rename from database/migrations/2026_08_10_111316_create_password_reset_tokens_table.php
rename to database/migrations/2026_08_10_000001_create_password_reset_tokens_table.php
diff --git a/database/migrations/2026_08_10_111317_create_sessions_table.php b/database/migrations/2026_08_10_000002_create_sessions_table.php
similarity index 100%
rename from database/migrations/2026_08_10_111317_create_sessions_table.php
rename to database/migrations/2026_08_10_000002_create_sessions_table.php
diff --git a/database/seeders/ConsoleSeeder.php b/database/seeders/ConsoleSeeder.php
index 702bcf2..04a4b33 100644
--- a/database/seeders/ConsoleSeeder.php
+++ b/database/seeders/ConsoleSeeder.php
@@ -2,7 +2,7 @@
namespace Database\Seeders;
-use App\Models\Console;
+use App\Features\Consoles\Models\Console;
use Illuminate\Database\Seeder;
class ConsoleSeeder extends Seeder
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index c790d9b..ee0af6b 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -2,12 +2,18 @@
namespace Database\Seeders;
+use App\Models\User;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
+ User::factory()->create([
+ 'email' => 'test@example.com',
+ 'password' => bcrypt('password'),
+ ]);
+
$this->call([
ConsoleSeeder::class,
]);
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
deleted file mode 100644
index 0e13407..0000000
--- a/docker-compose.dev.yml
+++ /dev/null
@@ -1,104 +0,0 @@
-services:
- app:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: retrohub-dev-app
- ports:
- - "8000:80"
- volumes:
- - .:/var/www/retrohub
- - retrohub-dev-roms:/var/www/retrohub/storage/app/roms
- - retrohub-dev-saves:/var/www/retrohub/storage/app/saves
- - retrohub-dev-covers:/var/www/retrohub/storage/app/covers
- environment:
- - APP_ENV=local
- - APP_DEBUG=true
- - APP_URL=http://localhost:8000
- - DB_CONNECTION=pgsql
- - DB_HOST=db
- - DB_PORT=5432
- - DB_DATABASE=retrohub
- - DB_USERNAME=retrohub
- - DB_PASSWORD=secret
- - REDIS_HOST=redis
- - CACHE_DRIVER=redis
- - SESSION_DRIVER=redis
- - QUEUE_CONNECTION=redis
- depends_on:
- db:
- condition: service_healthy
- redis:
- condition: service_healthy
- command: >
- sh -c "php artisan migrate --force &&
- php artisan db:seed --force &&
- php artisan serve --host=0.0.0.0 --port=80"
-
- db:
- image: pgvector/pgvector:pg16
- container_name: retrohub-dev-db
- ports:
- - "5432:5432"
- volumes:
- - retrohub-dev-db:/var/lib/postgresql/data
- environment:
- - POSTGRES_DB=retrohub
- - POSTGRES_USER=retrohub
- - POSTGRES_PASSWORD=secret
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U retrohub"]
- interval: 10s
- timeout: 5s
- retries: 5
-
- redis:
- image: redis:7-alpine
- container_name: retrohub-dev-redis
- ports:
- - "6379:6379"
- volumes:
- - retrohub-dev-redis:/data
- healthcheck:
- test: ["CMD", "redis-cli", "ping"]
- interval: 10s
- timeout: 5s
- retries: 5
-
- worker:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: retrohub-dev-worker
- command: php artisan horizon
- volumes:
- - .:/var/www/retrohub
- - retrohub-dev-roms:/var/www/retrohub/storage/app/roms
- - retrohub-dev-saves:/var/www/retrohub/storage/app/saves
- - retrohub-dev-covers:/var/www/retrohub/storage/app/covers
- environment:
- - APP_ENV=local
- - APP_DEBUG=true
- - APP_URL=http://localhost:8000
- - DB_CONNECTION=pgsql
- - DB_HOST=db
- - DB_PORT=5432
- - DB_DATABASE=retrohub
- - DB_USERNAME=retrohub
- - DB_PASSWORD=secret
- - REDIS_HOST=redis
- - CACHE_DRIVER=redis
- - SESSION_DRIVER=redis
- - QUEUE_CONNECTION=redis
- depends_on:
- db:
- condition: service_healthy
- redis:
- condition: service_healthy
-
-volumes:
- retrohub-dev-db:
- retrohub-dev-redis:
- retrohub-dev-roms:
- retrohub-dev-saves:
- retrohub-dev-covers:
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index 772b58b..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,102 +0,0 @@
-services:
- app:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: retrohub-app
- restart: unless-stopped
- ports:
- - "8080:80"
- volumes:
- - retrohub-roms:/var/www/retrohub/storage/app/roms
- - retrohub-saves:/var/www/retrohub/storage/app/saves
- - retrohub-covers:/var/www/retrohub/storage/app/covers
- environment:
- - APP_URL=${APP_URL:-http://localhost:8080}
- - APP_KEY=${APP_KEY}
- - DB_CONNECTION=pgsql
- - DB_HOST=db
- - DB_PORT=5432
- - DB_DATABASE=retrohub
- - DB_USERNAME=retrohub
- - DB_PASSWORD=${DB_PASSWORD}
- - REDIS_HOST=redis
- - CACHE_DRIVER=redis
- - SESSION_DRIVER=redis
- - QUEUE_CONNECTION=redis
- - IGDB_CLIENT_ID=${IGDB_CLIENT_ID}
- - IGDB_CLIENT_SECRET=${IGDB_CLIENT_SECRET}
- - TGDB_API_KEY=${TGDB_API_KEY}
- depends_on:
- db:
- condition: service_healthy
- redis:
- condition: service_healthy
-
- db:
- image: pgvector/pgvector:pg16
- container_name: retrohub-db
- restart: unless-stopped
- volumes:
- - retrohub-db:/var/lib/postgresql/data
- environment:
- - POSTGRES_DB=retrohub
- - POSTGRES_USER=retrohub
- - POSTGRES_PASSWORD=${DB_PASSWORD}
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U retrohub"]
- interval: 10s
- timeout: 5s
- retries: 5
-
- redis:
- image: redis:7-alpine
- container_name: retrohub-redis
- restart: unless-stopped
- volumes:
- - retrohub-redis:/data
- healthcheck:
- test: ["CMD", "redis-cli", "ping"]
- interval: 10s
- timeout: 5s
- retries: 5
-
- worker:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: retrohub-worker
- restart: unless-stopped
- command: php artisan horizon
- volumes:
- - retrohub-roms:/var/www/retrohub/storage/app/roms
- - retrohub-saves:/var/www/retrohub/storage/app/saves
- - retrohub-covers:/var/www/retrohub/storage/app/covers
- environment:
- - APP_URL=${APP_URL:-http://localhost:8080}
- - APP_KEY=${APP_KEY}
- - DB_CONNECTION=pgsql
- - DB_HOST=db
- - DB_PORT=5432
- - DB_DATABASE=retrohub
- - DB_USERNAME=retrohub
- - DB_PASSWORD=${DB_PASSWORD}
- - REDIS_HOST=redis
- - CACHE_DRIVER=redis
- - SESSION_DRIVER=redis
- - QUEUE_CONNECTION=redis
- - IGDB_CLIENT_ID=${IGDB_CLIENT_ID}
- - IGDB_CLIENT_SECRET=${IGDB_CLIENT_SECRET}
- - TGDB_API_KEY=${TGDB_API_KEY}
- depends_on:
- db:
- condition: service_healthy
- redis:
- condition: service_healthy
-
-volumes:
- retrohub-db:
- retrohub-redis:
- retrohub-roms:
- retrohub-saves:
- retrohub-covers:
diff --git a/docker/nginx.conf b/docker/nginx.conf
deleted file mode 100644
index 920ea8f..0000000
--- a/docker/nginx.conf
+++ /dev/null
@@ -1,37 +0,0 @@
-server {
- listen 80;
- server_name localhost;
- root /var/www/retrohub/public;
-
- 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 127.0.0.1:9000;
- fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
- include fastcgi_params;
- fastcgi_hide_header X-Powered-By;
- }
-
- location ~ /\.(?!well-known).* {
- deny all;
- }
-
- # WebDAV support
- location /webdav {
- try_files $uri $uri/ /index.php?$query_string;
- }
-}
diff --git a/docker/php.ini b/docker/php.ini
deleted file mode 100644
index 1dcd424..0000000
--- a/docker/php.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-memory_limit = 256M
-upload_max_filesize = 512M
-post_max_size = 512M
-max_execution_time = 300
-max_input_time = 300
-opcache.enable = 1
-opcache.memory_consumption = 128
-opcache.interned_strings_buffer = 8
-opcache.max_accelerated_files = 10000
-opcache.revalidate_freq = 0
-opcache.validate_timestamps = 0
diff --git a/docker/supervisord.conf b/docker/supervisord.conf
deleted file mode 100644
index 8a80833..0000000
--- a/docker/supervisord.conf
+++ /dev/null
@@ -1,32 +0,0 @@
-[supervisord]
-nodaemon=true
-user=root
-logfile=/var/log/supervisor/supervisord.log
-pidfile=/var/run/supervisord.pid
-
-[program:php-fpm]
-command=php-fpm
-autostart=true
-autorestart=true
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-
-[program:nginx]
-command=nginx -g "daemon off;"
-autostart=true
-autorestart=true
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-
-[program:horizon]
-command=php /var/www/retrohub/artisan horizon
-autostart=true
-autorestart=true
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
diff --git a/phpunit.xml b/phpunit.xml
index e7f0a48..a85936a 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -23,8 +23,7 @@
-
-
+