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
|
- **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.
|
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": {
|
"devDependencies": {
|
||||||
"laravel-vite-plugin": "^1.0",
|
"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 { defineConfig } from 'vite';
|
||||||
import laravel from 'laravel-vite-plugin';
|
import laravel from 'laravel-vite-plugin';
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
|
tailwindcss(),
|
||||||
laravel({
|
laravel({
|
||||||
input: [
|
input: [
|
||||||
'resources/css/app.css',
|
'resources/css/app.css',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue