feat: Automated setup script for local deployment (#58)

This PR adds a comprehensive setup script that automates the entire
local development setup process.

<img width="1470" height="932" alt="image"
src="https://github.com/user-attachments/assets/b173333a-6605-4fd9-b2e4-4c62d164d048"
/>

### Key Features

- **Automated Setup Script** (`setup.sh`): One-command installation that
handles everything
- **Caddy Integration**: Replaced Traefik with Caddy for simpler SSL
certificate management
- **Automatic Repository Cloning**: Script can be run remotely and will
clone the repo automatically
- **SSL Certificate Management**: Uses mkcert for trusted local
certificates
- **Automatic Hosts Configuration**: Configures /etc/hosts automatically
- **Version Checking**: Warns users when their local copy is outdated
- **Service Management**: Easy commands to start/stop/upgrade services

### Improvements

- Simplified local development setup
- Better SSL certificate handling (no browser warnings with mkcert)
- Updated README with quick start instructions
- Updated environment configuration for Docker
- Added production Dockerfile for CI/CD builds

### Usage

```bash
bash <(curl -fsSL https://whisper.money/setup.sh)
```

After installation, visit https://whisper.money.local
This commit is contained in:
Víctor Falcón 2026-01-16 15:57:12 +01:00 committed by GitHub
parent 253fe447bd
commit 819bea1922
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 1197 additions and 98 deletions

View File

@ -2,7 +2,7 @@ APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=https://whispermoney.test
APP_URL=https://whisper.money.local
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
@ -21,7 +21,7 @@ LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=whisper_money
DB_USERNAME=root
@ -43,7 +43,7 @@ CACHE_STORE=database
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

2
.gitignore vendored
View File

@ -28,4 +28,6 @@ yarn-error.log
/.zed
.php-cs-fixer.cache
/traefik/certs/*.pem
/docker/caddy/certs/*.pem
/docker/caddy/certs/*-key.pem
.claude/settings.local.json

16
Caddyfile Normal file
View File

@ -0,0 +1,16 @@
whisper.money.local {
# Use mkcert certificates (generated by setup script)
# 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
header {
-Server
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
}
encode zstd gzip
}

View File

@ -1,7 +1,5 @@
# Use the official PHP 8.4 FPM image
FROM php:8.4-fpm
FROM php:8.4-cli
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
@ -12,71 +10,17 @@ RUN apt-get update && apt-get install -y \
libicu-dev \
zip \
unzip \
nginx \
supervisor \
libmemcached-dev \
zlib1g-dev \
procps \
net-tools \
netcat-openbsd \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip intl
RUN pecl install memcached redis \
&& docker-php-ext-enable memcached redis
RUN pecl install redis \
&& docker-php-ext-enable redis
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
# Install Bun
RUN curl -fsSL https://bun.com/install | bash
ENV PATH="/root/.bun/bin:${PATH}"
# Install memcached and redis servers
RUN apt-get update && apt-get install -y memcached redis-server && rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy application files
COPY . /app/.
# Create necessary directories
RUN mkdir -p /var/log/nginx && mkdir -p /var/cache/nginx
# Install PHP dependencies
RUN composer install --no-dev --optimize-autoloader
# Install Node.js dependencies
RUN bun install --frozen-lockfile
# Build assets with HIDE_AUTH_BUTTONS=false so Wayfinder generates all routes
# (HIDE_AUTH_BUTTONS will be set to true at runtime via .env)
RUN HIDE_AUTH_BUTTONS=false bun run build:ssr
# Copy supervisor configuration
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy nginx configuration
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
# Set permissions
RUN chown -R www-data:www-data /app \
&& chmod -R 755 /app/storage \
&& chmod -R 755 /app/bootstrap/cache
# Expose port
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost/up || exit 1
# Copy entrypoint script
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Run entrypoint script (handles migrations, caching, then starts supervisor)
CMD ["/entrypoint.sh"]
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]

82
Dockerfile.production Normal file
View File

@ -0,0 +1,82 @@
# Use the official PHP 8.4 FPM image
FROM php:8.4-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
libicu-dev \
zip \
unzip \
nginx \
supervisor \
libmemcached-dev \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip intl
RUN pecl install memcached redis \
&& docker-php-ext-enable memcached redis
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
# Install Bun
RUN curl -fsSL https://bun.com/install | bash
ENV PATH="/root/.bun/bin:${PATH}"
# Install memcached and redis servers
RUN apt-get update && apt-get install -y memcached redis-server && rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy application files
COPY . /app/.
# Create necessary directories
RUN mkdir -p /var/log/nginx && mkdir -p /var/cache/nginx
# Install PHP dependencies
RUN composer install --no-dev --optimize-autoloader
# Install Node.js dependencies
RUN bun install --frozen-lockfile
# Build assets with HIDE_AUTH_BUTTONS=false so Wayfinder generates all routes
# (HIDE_AUTH_BUTTONS will be set to true at runtime via .env)
RUN HIDE_AUTH_BUTTONS=false bun run build:ssr
# Copy supervisor configuration
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy nginx configuration
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
# Set permissions
RUN chown -R www-data:www-data /app \
&& chmod -R 755 /app/storage \
&& chmod -R 755 /app/bootstrap/cache
# Expose port
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost/up || exit 1
# Copy entrypoint script
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Run entrypoint script (handles migrations, caching, then starts supervisor)
CMD ["/entrypoint.sh"]

View File

@ -44,40 +44,54 @@ Whisper Money is a privacy-first personal finance application that helps you tra
## Running Locally
### Prerequisites
### Quick Start (Recommended)
- Docker & Docker Compose
- Composer
- Node.js / Bun
The easiest way to get started is using our automated setup script:
### Setup
```bash
bash <(curl -fsSL https://whisper.money/setup.sh)
```
After installation, just visit **https://whisper.money.local** in your browser.
### Manual Setup
If you prefer to set up manually:
1. **Clone the repository:**
```bash
git clone https://github.com/whisper-money/whisper-money.git
cd whisper_money
cd whisper-money
```
2. **Copy the environment file:**
2. **Run the setup script:**
```bash
cp .env.example .env
./setup.sh install
```
3. **Start the Docker services:**
### Available Commands
Once installed, you can use the setup script for common tasks:
```bash
docker compose up -d
# Start all services
./setup.sh start
# Stop all services
./setup.sh stop
# Upgrade to latest version
./setup.sh upgrade
# Interactive menu
./setup.sh
```
4. **Install dependencies and setup the application:**
### Development Server
```bash
composer setup
```
5. **Start the development server:**
For active development with hot reloading:
```bash
composer run dev
@ -90,7 +104,7 @@ This will concurrently start:
- Log viewer (Pail)
- Vite dev server
The application will be available at `https://whispermoney.test`.
The application will be available at **https://whisper.money.local** (via Caddy) or **http://localhost:8000** (direct PHP server).
## Running with Docker (Production Image)

View File

@ -1,27 +1,20 @@
services:
traefik:
image: 'traefik:v3.0'
command:
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
- '--providers.file.directory=/etc/traefik/dynamic'
- '--providers.file.watch=true'
- '--entrypoints.web.address=:80'
- '--entrypoints.websecure.address=:443'
- '--log.level=INFO'
caddy:
image: 'caddy:latest'
ports:
- '80:80'
- '443:443'
- '8080:8080'
- '443:443/udp'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
- './traefik/dynamic:/etc/traefik/dynamic:ro'
- './traefik/certs:/etc/traefik/certs:ro'
- './Caddyfile:/etc/caddy/Caddyfile:ro'
- './docker/caddy/certs:/etc/caddy/certs:ro'
- 'caddy_data:/data'
- 'caddy_config:/config'
networks:
- sail
extra_hosts:
- 'host.docker.internal:host-gateway'
restart: unless-stopped
mysql:
image: 'mysql/mysql-server:8.0'
ports:
@ -69,6 +62,32 @@ services:
- '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
php:
build:
context: .
dockerfile: Dockerfile
ports:
- '8000:8000'
volumes:
- '.:/app'
- './vendor:/app/vendor'
- './node_modules:/app/node_modules'
env_file:
- .env
environment:
- DB_HOST=mysql
- DB_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
networks:
- sail
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
command: php artisan serve --host=0.0.0.0 --port=8000
networks:
sail:
driver: bridge
@ -77,3 +96,7 @@ volumes:
driver: local
sail-redis:
driver: local
caddy_data:
driver: local
caddy_config:
driver: local

1018
setup.sh Executable file

File diff suppressed because it is too large Load Diff