Add local development images
This commit is contained in:
parent
3e7f8ebe1a
commit
0f041983dd
11 changed files with 445 additions and 1 deletions
58
README.md
58
README.md
|
|
@ -139,3 +139,61 @@ ### Architecture
|
|||
- **mysql**: Database storage for articles, logs, and application data
|
||||
|
||||
Both app containers use the same Docker image but with different commands (`web` or `queue`). Environment variables are passed from your `.env` file to configure database access and Lemmy integration.
|
||||
|
||||
## Development Setup
|
||||
|
||||
For local development with Podman:
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Podman and podman-compose installed
|
||||
- Git
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Clone and start the development environment:**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd ffr
|
||||
./docker/dev/podman/start-dev.sh
|
||||
```
|
||||
|
||||
2. **Access the application:**
|
||||
- **Web interface**: http://localhost:8000
|
||||
- **Vite dev server**: http://localhost:5173
|
||||
- **Database**: localhost:3307
|
||||
- **Redis**: localhost:6380
|
||||
|
||||
### Development Commands
|
||||
|
||||
**Load Sail-compatible aliases:**
|
||||
```bash
|
||||
source docker/dev/podman/podman-sail-alias.sh
|
||||
```
|
||||
|
||||
**Useful commands:**
|
||||
```bash
|
||||
# Run tests
|
||||
ffr-test
|
||||
|
||||
# Execute artisan commands
|
||||
ffr-artisan migrate
|
||||
ffr-artisan tinker
|
||||
|
||||
# View application logs
|
||||
ffr-logs
|
||||
|
||||
# Open container shell
|
||||
ffr-shell
|
||||
|
||||
# Stop environment
|
||||
podman-compose -f docker/dev/podman/docker-compose.yml down
|
||||
```
|
||||
|
||||
### Development Features
|
||||
|
||||
- **Hot reload**: Vite automatically reloads frontend changes
|
||||
- **Database**: Pre-configured MySQL with migrations and seeders
|
||||
- **Redis**: Configured for caching, sessions, and queues
|
||||
- **Laravel Horizon**: Available for queue monitoring
|
||||
- **No configuration needed**: Development environment uses preset configuration
|
||||
|
|
|
|||
42
app/Http/Middleware/HandleInertiaRequests.php
Normal file
42
app/Http/Middleware/HandleInertiaRequests.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
/**
|
||||
* The root template that's loaded on the first page visit.
|
||||
*
|
||||
* @see https://inertiajs.com/server-side-setup#root-template
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rootView = 'app';
|
||||
|
||||
/**
|
||||
* Determines the current asset version.
|
||||
*
|
||||
* @see https://inertiajs.com/asset-versioning
|
||||
*/
|
||||
public function version(Request $request): ?string
|
||||
{
|
||||
return parent::version($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the props that are shared by default.
|
||||
*
|
||||
* @see https://inertiajs.com/shared-data
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
return array_merge(parent::share($request), [
|
||||
//
|
||||
]);
|
||||
}
|
||||
}
|
||||
62
docker/dev/podman/.env.dev
Normal file
62
docker/dev/podman/.env.dev
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
APP_NAME="FFR Development"
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:YOUR_APP_KEY_HERE
|
||||
APP_DEBUG=true
|
||||
APP_TIMEZONE=UTC
|
||||
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
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=ffr_dev
|
||||
DB_USERNAME=ffr_user
|
||||
DB_PASSWORD=ffr_password
|
||||
|
||||
SESSION_DRIVER=redis
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=false
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=redis
|
||||
|
||||
CACHE_STORE=redis
|
||||
CACHE_PREFIX=
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
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}"
|
||||
51
docker/dev/podman/Dockerfile
Normal file
51
docker/dev/podman/Dockerfile
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
FROM docker.io/library/php:8.4-fpm
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git \
|
||||
curl \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
libxml2-dev \
|
||||
zip \
|
||||
unzip \
|
||||
nodejs \
|
||||
npm \
|
||||
default-mysql-client \
|
||||
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd \
|
||||
&& pecl install redis \
|
||||
&& docker-php-ext-enable redis
|
||||
|
||||
# Install Composer
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Install Node.js 20.x (for better compatibility)
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
|
||||
# Copy composer files and install PHP dependencies
|
||||
COPY composer.json ./
|
||||
RUN composer install --optimize-autoloader --no-scripts
|
||||
|
||||
# Copy package.json and install Node dependencies
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set permissions
|
||||
RUN chown -R www-data:www-data /var/www/html \
|
||||
&& chmod -R 755 /var/www/html/storage \
|
||||
&& chmod -R 755 /var/www/html/bootstrap/cache
|
||||
|
||||
# Copy and set up container start script
|
||||
COPY docker/dev/podman/container-start.sh /usr/local/bin/container-start.sh
|
||||
RUN chmod +x /usr/local/bin/container-start.sh
|
||||
|
||||
EXPOSE 8000 5173
|
||||
|
||||
CMD ["/usr/local/bin/container-start.sh"]
|
||||
38
docker/dev/podman/container-start.sh
Executable file
38
docker/dev/podman/container-start.sh
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copy development environment configuration
|
||||
cp /var/www/html/docker/dev/podman/.env.dev /var/www/html/.env
|
||||
|
||||
# Install/update dependencies
|
||||
echo "Installing PHP dependencies..."
|
||||
composer install --no-interaction
|
||||
|
||||
echo "Installing Node dependencies..."
|
||||
npm install
|
||||
|
||||
# Generate app key if not set or empty
|
||||
if grep -q "APP_KEY=base64:YOUR_APP_KEY_HERE" /var/www/html/.env || ! grep -q "APP_KEY=base64:" /var/www/html/.env; then
|
||||
echo "Generating application key..."
|
||||
php artisan key:generate --force
|
||||
fi
|
||||
|
||||
# Wait for database to be ready
|
||||
echo "Waiting for database..."
|
||||
while ! mysql -h db -u ffr_user -pffr_password --connect-timeout=2 -e "SELECT 1" >/dev/null 2>&1; do
|
||||
echo "Database not ready, waiting..."
|
||||
sleep 1
|
||||
done
|
||||
echo "Database connection established!"
|
||||
|
||||
# Run migrations and seeders
|
||||
php artisan migrate --force
|
||||
php artisan db:seed --force
|
||||
|
||||
# Start Laravel development server in background
|
||||
php artisan serve --host=0.0.0.0 --port=8000 &
|
||||
|
||||
# Start Vite development server
|
||||
npm run dev -- --host 0.0.0.0
|
||||
|
||||
# Wait for background processes
|
||||
wait
|
||||
77
docker/dev/podman/docker-compose.yml
Normal file
77
docker/dev/podman/docker-compose.yml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
services:
|
||||
app:
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: docker/dev/podman/Dockerfile
|
||||
container_name: ffr-dev-app
|
||||
restart: unless-stopped
|
||||
working_dir: /var/www/html
|
||||
environment:
|
||||
- APP_ENV=local
|
||||
- APP_DEBUG=true
|
||||
- APP_KEY=base64:YOUR_APP_KEY_HERE
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=db
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=ffr_dev
|
||||
- DB_USERNAME=ffr_user
|
||||
- DB_PASSWORD=ffr_password
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- QUEUE_CONNECTION=redis
|
||||
- CACHE_DRIVER=redis
|
||||
- SESSION_DRIVER=redis
|
||||
- VITE_PORT=5173
|
||||
volumes:
|
||||
- ../../../:/var/www/html:Z
|
||||
- /var/www/html/node_modules
|
||||
- /var/www/html/vendor
|
||||
ports:
|
||||
- "8000:8000"
|
||||
- "5173:5173"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_started
|
||||
networks:
|
||||
- ffr-dev-network
|
||||
|
||||
db:
|
||||
image: docker.io/library/mysql:8.0
|
||||
container_name: ffr-dev-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_DATABASE=ffr_dev
|
||||
- MYSQL_USER=ffr_user
|
||||
- MYSQL_PASSWORD=ffr_password
|
||||
- MYSQL_ROOT_PASSWORD=root_password
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
ports:
|
||||
- "3307:3306"
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "ffr_user", "-pffr_password"]
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
interval: 3s
|
||||
start_period: 30s
|
||||
networks:
|
||||
- ffr-dev-network
|
||||
|
||||
redis:
|
||||
image: docker.io/library/redis:7-alpine
|
||||
container_name: ffr-dev-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6380:6379"
|
||||
networks:
|
||||
- ffr-dev-network
|
||||
|
||||
networks:
|
||||
ffr-dev-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
driver: local
|
||||
52
docker/dev/podman/podman-sail-alias.sh
Executable file
52
docker/dev/podman/podman-sail-alias.sh
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Podman aliases for Laravel Sail compatibility
|
||||
# Source this file to use Sail commands with Podman
|
||||
# Usage: source docker/dev/podman/podman-sail-alias.sh
|
||||
|
||||
# Create docker alias pointing to podman
|
||||
alias docker='podman'
|
||||
|
||||
# Create docker-compose alias pointing to podman-compose
|
||||
alias docker-compose='podman-compose'
|
||||
|
||||
# Sail wrapper function that uses podman-compose
|
||||
sail() {
|
||||
if [[ -f docker/dev/podman/docker-compose.yml ]]; then
|
||||
podman-compose -f docker/dev/podman/docker-compose.yml "$@"
|
||||
else
|
||||
echo "❌ Podman compose file not found at docker/dev/podman/docker-compose.yml"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# FFR-specific helper functions
|
||||
ffr-test() {
|
||||
echo "🧪 Running FFR tests..."
|
||||
podman exec ffr-dev-app php artisan test "$@"
|
||||
}
|
||||
|
||||
ffr-artisan() {
|
||||
echo "🔧 Running artisan command..."
|
||||
podman exec ffr-dev-app php artisan "$@"
|
||||
}
|
||||
|
||||
ffr-logs() {
|
||||
echo "📋 Showing FFR application logs..."
|
||||
podman-compose -f docker/dev/podman/docker-compose.yml logs -f app
|
||||
}
|
||||
|
||||
ffr-shell() {
|
||||
echo "🐚 Opening shell in FFR container..."
|
||||
podman exec -it ffr-dev-app bash
|
||||
}
|
||||
|
||||
echo "✅ FFR Podman aliases set up for Laravel Sail compatibility"
|
||||
echo "🐳 'docker' → 'podman'"
|
||||
echo "🔧 'docker-compose' → 'podman-compose'"
|
||||
echo "⛵ 'sail' → uses podman-compose with dev configuration"
|
||||
echo "🚀 FFR-specific commands:"
|
||||
echo " 'ffr-test' → run tests"
|
||||
echo " 'ffr-artisan' → run artisan commands"
|
||||
echo " 'ffr-logs' → view application logs"
|
||||
echo " 'ffr-shell' → open container shell"
|
||||
58
docker/dev/podman/start-dev.sh
Executable file
58
docker/dev/podman/start-dev.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Podman development environment startup script for FFR
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting FFR development environment with Podman..."
|
||||
|
||||
# Check if .env exists
|
||||
if [ ! -f .env ]; then
|
||||
echo "📋 Creating .env file from .env.example..."
|
||||
cp .env.example .env
|
||||
echo "⚠️ Please update your .env file with appropriate values, especially APP_KEY"
|
||||
fi
|
||||
|
||||
# Check if podman-compose is available
|
||||
if ! command -v podman-compose &> /dev/null; then
|
||||
echo "❌ podman-compose not found. Installing..."
|
||||
pip3 install --user podman-compose
|
||||
echo "✅ podman-compose installed"
|
||||
fi
|
||||
|
||||
# Start services
|
||||
echo "🔧 Starting services..."
|
||||
podman-compose -f docker/dev/podman/docker-compose.yml up -d
|
||||
|
||||
# Wait for database to be ready
|
||||
echo "⏳ Waiting for database to be ready..."
|
||||
sleep 10
|
||||
|
||||
# Check if APP_KEY is set
|
||||
if grep -q "APP_KEY=base64:YOUR_APP_KEY_HERE" .env || grep -q "APP_KEY=$" .env; then
|
||||
echo "🔑 Generating application key..."
|
||||
podman exec ffr-dev-app php artisan key:generate
|
||||
fi
|
||||
|
||||
# Run migrations and seeders
|
||||
echo "🗃️ Running database migrations..."
|
||||
podman exec ffr-dev-app php artisan migrate --force
|
||||
echo "🌱 Running database seeders..."
|
||||
podman exec ffr-dev-app php artisan db:seed --force
|
||||
|
||||
# Install/update dependencies if needed
|
||||
echo "📦 Installing dependencies..."
|
||||
podman exec ffr-dev-app composer install
|
||||
podman exec ffr-dev-app npm install
|
||||
|
||||
echo "✅ Development environment is ready!"
|
||||
echo "🌐 Application: http://localhost:8000"
|
||||
echo "🔥 Vite dev server: http://localhost:5173"
|
||||
echo "💾 Database: localhost:3307"
|
||||
echo "🔴 Redis: localhost:6380"
|
||||
echo ""
|
||||
echo "📋 Useful commands:"
|
||||
echo " Stop: podman-compose -f docker/dev/podman/docker-compose.yml down"
|
||||
echo " Logs: podman-compose -f docker/dev/podman/docker-compose.yml logs -f"
|
||||
echo " Exec: podman exec -it ffr-dev-app bash"
|
||||
echo " Tests: podman exec ffr-dev-app php artisan test"
|
||||
1
incr-docker
Symbolic link
1
incr-docker
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../incr/docker
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"vite": "^6.0"
|
||||
"vite": "^6.0",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
laravel({
|
||||
input: [
|
||||
'resources/css/app.css',
|
||||
|
|
|
|||
Loading…
Reference in a new issue