diff --git a/.env.example b/.env.example index e8cb3dc3..5a8197a6 100644 --- a/.env.example +++ b/.env.example @@ -21,8 +21,8 @@ LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql -DB_HOST=mysql -DB_PORT=3306 +DB_HOST=127.0.0.1 +DB_PORT=3307 DB_DATABASE=whisper_money DB_USERNAME=root DB_PASSWORD= @@ -42,13 +42,13 @@ CACHE_STORE=database MEMCACHED_HOST=127.0.0.1 -REDIS_HOST=redis +REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null -REDIS_PORT=6379 +REDIS_PORT=6380 -MAIL_MAILER=log +MAIL_MAILER=smtp MAIL_HOST=127.0.0.1 -MAIL_PORT=2525 +MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_FROM_ADDRESS="hi@whisper.money" @@ -94,6 +94,15 @@ SENTRY_LARAVEL_DSN= SENTRY_TRACES_SAMPLE_RATE=1.0 SENTRY_PROFILES_SAMPLE_RATE=0 +# Docker Service Ports (forwarded to host) +FORWARD_DB_PORT=3307 +FORWARD_REDIS_PORT=6380 +FORWARD_MAILHOG_PORT=1025 +FORWARD_MAILHOG_DASHBOARD_PORT=8025 + +# Dev Mode (set to false for full Docker deployment via setup.sh) +DEV_MODE=true + # Demo Account Configuration DEMO_EMAIL=demo@whisper.money DEMO_PASSWORD=demo diff --git a/.gitignore b/.gitignore index 04f57d47..b9a61eb0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ yarn-error.log /.vscode /.zed .php-cs-fixer.cache -/traefik/certs/*.pem /docker/caddy/certs/*.pem /docker/caddy/certs/*-key.pem .claude/settings.local.json diff --git a/Caddyfile b/Caddyfile index 76b2d84d..d1ccce6a 100644 --- a/Caddyfile +++ b/Caddyfile @@ -3,7 +3,7 @@ whisper.money.local { # These certificates are automatically trusted by browsers tls /etc/caddy/certs/whisper.money.local.pem /etc/caddy/certs/whisper.money.local-key.pem - reverse_proxy php:8000 + reverse_proxy host.docker.internal:8000 header { -Server diff --git a/compose.yaml b/compose.yaml index 56c828a2..693a3a7a 100644 --- a/compose.yaml +++ b/compose.yaml @@ -62,6 +62,8 @@ services: networks: - sail php: + profiles: + - full build: context: . dockerfile: Dockerfile diff --git a/composer.json b/composer.json index eba9ba63..10e4b0d7 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ ], "dev": [ "Composer\\Config::disableProcessTimeout", - "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --queue=default,emails\" \"php artisan pail --timeout=0\" \"bun run dev\" \"stripe listen --forward-to https://whispermoney.test/stripe/webhook\" --names=server,queue,logs,vite --kill-others" + "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --queue=default,emails\" \"php artisan pail --timeout=0\" \"bun run dev\" \"stripe listen --forward-to https://whisper.money.local/stripe/webhook\" --names=server,queue,logs,vite --kill-others" ], "dev:ssr": [ "bun run build:ssr", diff --git a/public/setup.sh b/public/setup.sh index 089cf1ae..f582a3d6 100755 --- a/public/setup.sh +++ b/public/setup.sh @@ -790,7 +790,7 @@ start_services() { fi echo -e "${BLUE}Starting Docker services...${NC}" - docker compose up -d + docker compose --profile full up -d wait_for_service "mysql" wait_for_service "redis" @@ -939,7 +939,7 @@ install() { # Now start PHP service (after dependencies are installed) echo -e "${BLUE}Starting PHP service...${NC}" - if ! docker compose up -d php; then + if ! docker compose --profile full up -d php; then echo -e "${RED}Failed to start PHP service!${NC}" echo -e "${YELLOW}Checking logs...${NC}" docker compose logs php 2>&1 | tail -20 @@ -1217,7 +1217,7 @@ upgrade() { # Restart services echo -e "${BLUE}Restarting services...${NC}" - docker compose restart + docker compose --profile full restart echo -e "${GREEN}Services restarted.${NC}" echo "" diff --git a/resources/js/components/transactions/import-step-preview.tsx b/resources/js/components/transactions/import-step-preview.tsx index ed8243f0..4f8a17d6 100644 --- a/resources/js/components/transactions/import-step-preview.tsx +++ b/resources/js/components/transactions/import-step-preview.tsx @@ -19,8 +19,8 @@ import { import { useEncryptionKey } from '@/contexts/encryption-key-context'; import { useLocale } from '@/hooks/use-locale'; import { transactionSyncService } from '@/services/transaction-sync'; -import { type Transaction } from '@/types/transaction'; import { type ParsedTransaction } from '@/types/import'; +import { type Transaction } from '@/types/transaction'; import { formatDateMedium } from '@/utils/date'; import { __ } from '@/utils/i18n'; import { ChevronDown } from 'lucide-react'; diff --git a/traefik/certs/.gitkeep b/traefik/certs/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/traefik/dynamic/whispermoney.yml b/traefik/dynamic/whispermoney.yml deleted file mode 100644 index 72c430df..00000000 --- a/traefik/dynamic/whispermoney.yml +++ /dev/null @@ -1,41 +0,0 @@ -http: - routers: - whispermoney-http: - rule: Host(`whispermoney.test`) - entryPoints: - - web - middlewares: - - redirect-to-https - service: whispermoney - whispermoney-https: - rule: Host(`whispermoney.test`) - entryPoints: - - websecure - service: whispermoney - middlewares: - - headers-secure - tls: {} - - middlewares: - redirect-to-https: - redirectScheme: - scheme: https - permanent: true - headers-secure: - headers: - customRequestHeaders: - X-Forwarded-Proto: https - customResponseHeaders: - X-Forwarded-Proto: https - - services: - whispermoney: - loadBalancer: - servers: - - url: http://host.docker.internal:8000 - passHostHeader: true - -tls: - certificates: - - certFile: /etc/traefik/certs/whispermoney.test.pem - keyFile: /etc/traefik/certs/whispermoney.test-key.pem diff --git a/traefik/generate-certs.sh b/traefik/generate-certs.sh deleted file mode 100755 index 391cd654..00000000 --- a/traefik/generate-certs.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -set -e - -if ! command -v mkcert &> /dev/null; then - echo "mkcert is not installed. Installing..." - - if [[ "$OSTYPE" == "darwin"* ]]; then - if command -v brew &> /dev/null; then - brew install mkcert - brew install nss - else - echo "Please install Homebrew first, then run: brew install mkcert nss" - exit 1 - fi - else - echo "Please install mkcert manually. Visit: https://github.com/FiloSottile/mkcert" - exit 1 - fi -fi - -if [ ! -f "$(mkcert -CAROOT)/rootCA.pem" ]; then - echo "Installing local CA..." - mkcert -install -fi - -echo "Generating certificates for whispermoney.test..." -cd "$(dirname "$0")/certs" -mkcert -key-file whispermoney.test-key.pem -cert-file whispermoney.test.pem whispermoney.test - -echo "Certificates generated successfully!" -echo "Files created:" -echo " - traefik/certs/whispermoney.test.pem" -echo " - traefik/certs/whispermoney.test-key.pem" diff --git a/vite.config.ts b/vite.config.ts index 50f5fdfe..789cc98d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,3 +1,6 @@ +import fs from 'fs'; +import path from 'path'; + import { wayfinder } from '@laravel/vite-plugin-wayfinder'; import { sentryVitePlugin } from '@sentry/vite-plugin'; import tailwindcss from '@tailwindcss/vite'; @@ -9,6 +12,18 @@ export default defineConfig({ build: { sourcemap: true, }, + server: (() => { + const certPath = path.resolve(__dirname, 'docker/caddy/certs/whisper.money.local.pem'); + const keyPath = path.resolve(__dirname, 'docker/caddy/certs/whisper.money.local-key.pem'); + if (fs.existsSync(certPath) && fs.existsSync(keyPath)) { + return { + https: { cert: certPath, key: keyPath }, + host: '0.0.0.0', + hmr: { host: 'whisper.money.local' }, + }; + } + return {}; + })(), plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.tsx'],