Setup Podman and Podman Compose for local development #3

Open
JMR-dev wants to merge 1 commits from claude/setup-podman-local-dev-A78Yo into main
11 changed files with 563 additions and 18 deletions
+46
View File
@@ -0,0 +1,46 @@
# Dependencies
node_modules
**/node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Build outputs
.next
.turbo
dist
build
out
*.log
# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Git
.git
.gitignore
.gitattributes
# IDE
.vscode
.idea
*.swp
*.swo
*~
.DS_Store
# Testing
coverage
.nyc_output
# Misc
*.md
!README.md
.editorconfig
.prettierrc
.eslintrc*
+19
View File
@@ -0,0 +1,19 @@
# Node Environment
NODE_ENV=development
# PostgreSQL Configuration
POSTGRES_USER=lightsaver
POSTGRES_PASSWORD=lightsaver_dev
POSTGRES_DB=lightsaver
DATABASE_URL=postgresql://lightsaver:lightsaver_dev@localhost:5432/lightsaver
# RabbitMQ Configuration
RABBITMQ_USER=lightsaver
RABBITMQ_PASSWORD=lightsaver_dev
RABBITMQ_URL=amqp://lightsaver:lightsaver_dev@localhost:5672
# API Configuration
API_PORT=4000
# Frontend Configuration
NEXT_PUBLIC_API_URL=http://localhost:4000/graphql
+27 -10
View File
@@ -1,33 +1,50 @@
# Production Build - Podman Compatible
# 1. Build stage
FROM node:22-slim AS builder
FROM docker.io/library/node:22-slim AS builder
ENV NVM_DIR=/root/.nvm
ENV NODE_VERSION=22
# Install dependencies for Node
RUN apt-get update && apt-get dist-upgrade -y && apt-get install -y ca-certificates build-essential
RUN apt-get update && \
apt-get dist-upgrade -y && \
apt-get install -y ca-certificates build-essential && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Enable corepack and prepare pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY . .
# Copy package files first for better layer caching
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
COPY apps/lightsaver_user_client/package.json ./apps/lightsaver_user_client/
COPY packages ./packages
RUN yes | pnpm install
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source code
COPY apps/lightsaver_user_client ./apps/lightsaver_user_client
# Build the application
RUN pnpm turbo run build --filter=lightsaver_user_client...
#debugging
RUN ls -al /app/apps/lightsaver_user_client
# 2. Production stage
FROM node:22-slim
FROM docker.io/library/node:22-slim
WORKDIR /app
COPY --from=builder /app/apps/lightsaver_user_client ./
# Copy built application and dependencies
COPY --from=builder /app/apps/lightsaver_user_client/.next ./apps/lightsaver_user_client/.next
COPY --from=builder /app/apps/lightsaver_user_client/public ./apps/lightsaver_user_client/public
COPY --from=builder /app/apps/lightsaver_user_client/package.json ./apps/lightsaver_user_client/
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/packages ./packages
COPY --from=builder /app/package.json ./
EXPOSE 3000
EXPOSE 3000
# Run the production server
CMD ["node_modules/.bin/next", "start", "apps/lightsaver_user_client"]
+35
View File
@@ -0,0 +1,35 @@
# Backend API Dockerfile for Podman
FROM docker.io/library/node:22-slim
# Install required dependencies
RUN apt-get update && \
apt-get dist-upgrade -y && \
apt-get install -y ca-certificates build-essential && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Enable corepack and prepare pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Set working directory
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY turbo.json ./
# Copy service and package directories
COPY services/package.json ./services/
COPY packages ./packages
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy service source code
COPY services ./services
# Expose API port
EXPOSE 4000
# Default command (can be overridden in docker-compose)
CMD ["pnpm", "--filter", "api", "dev"]
+35
View File
@@ -0,0 +1,35 @@
# Frontend Dockerfile for Podman
FROM docker.io/library/node:22-slim
# Install required dependencies
RUN apt-get update && \
apt-get dist-upgrade -y && \
apt-get install -y ca-certificates build-essential && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Enable corepack and prepare pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Set working directory
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY turbo.json ./
# Copy app and package directories
COPY apps/lightsaver_user_client/package.json ./apps/lightsaver_user_client/
COPY packages ./packages
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy app source code
COPY apps/lightsaver_user_client ./apps/lightsaver_user_client
# Expose Next.js port
EXPOSE 3000
# Default command (can be overridden in docker-compose)
CMD ["pnpm", "--filter", "lightsaver_user_client", "dev", "--", "--turbopack"]
+93
View File
@@ -0,0 +1,93 @@
.PHONY: help dev up down build rebuild logs clean install test
# Default target
help:
@echo "LightSaver - Podman Development Commands"
@echo ""
@echo "Available targets:"
@echo " make dev - Start all services in development mode with hot-reload"
@echo " make up - Start all services in detached mode"
@echo " make down - Stop all services"
@echo " make build - Build all service images"
@echo " make rebuild - Rebuild and restart all services"
@echo " make logs - Follow logs from all services"
@echo " make logs-api - Follow logs from API service"
@echo " make logs-fe - Follow logs from frontend service"
@echo " make clean - Stop services and remove volumes"
@echo " make install - Install dependencies in running containers"
@echo " make shell-api - Open shell in API container"
@echo " make shell-fe - Open shell in frontend container"
@echo " make db-shell - Open PostgreSQL shell"
@echo " make setup - Initial setup (copy .env, install deps)"
# Start services in development mode with hot-reload
dev:
podman-compose -f docker-compose.yml -f docker-compose.dev.yml up
# Start services in detached mode
up:
podman-compose up -d
# Stop all services
down:
podman-compose down
# Build all images
build:
podman-compose build
# Rebuild and restart
rebuild:
podman-compose down
podman-compose build
podman-compose up -d
# View logs
logs:
podman-compose logs -f
logs-api:
podman-compose logs -f api
logs-fe:
podman-compose logs -f frontend
logs-db:
podman-compose logs -f postgres
logs-mq:
podman-compose logs -f rabbitmq
# Stop and remove everything including volumes
clean:
podman-compose down -v
@echo "Cleaned up all containers and volumes"
# Install dependencies
install:
podman-compose exec frontend pnpm install
podman-compose exec api pnpm install
# Open shells
shell-api:
podman-compose exec api sh
shell-fe:
podman-compose exec frontend sh
# Database shell
db-shell:
podman-compose exec postgres psql -U lightsaver -d lightsaver
# Initial setup
setup:
@if [ ! -f .env ]; then cp .env.example .env; echo "Created .env file"; fi
@echo "Setup complete! Run 'make dev' to start development"
# Production build
prod-build:
podman build -t lightsaver-app .
# Run production container
prod-run:
podman run -p 3000:3000 lightsaver-app
+110 -8
View File
@@ -6,20 +6,122 @@
- **GraphQL**: API query language for flexible and efficient data fetching.
- **Express.js**: Fast, unopinionated web framework for Node.js, powering the backend API.
- **PostgreSQL**: Relational database for persistent storage.
- **Docker**: Containerization for consistent deployment.
- **Podman & Podman Compose**: Container orchestration for local development and deployment.
- **Terraform CDKTF**: Infrastructure as Code (IaC) using the Cloud Development Kit for Terraform.
- **RabbitMQ**: Message broker for asynchronous communication and background processing.
## Docker Commands
## Prerequisites
To build the Docker image:
- **Podman**: Install from [podman.io](https://podman.io/getting-started/installation)
- **Podman Compose**: Install via `pip install podman-compose`
- **Node.js**: Version 22.17.0 or higher
- **pnpm**: Package manager (installed via corepack)
## Local Development with Podman
### Quick Start
1. **Clone the repository**
```sh
git clone <repository-url>
cd lightsaver
```
2. **Set up environment variables**
```sh
cp .env.example .env
# Edit .env with your configuration if needed
```
3. **Start all services with Podman Compose**
```sh
# Development mode with hot-reload
podman-compose -f docker-compose.yml -f docker-compose.dev.yml up
# Or use the base configuration only
podman-compose up
```
4. **Access the applications**
- Frontend: http://localhost:3000
- Backend API: http://localhost:4000
- RabbitMQ Management: http://localhost:15672 (user: lightsaver, password: lightsaver_dev)
- PostgreSQL: localhost:5432
### Available Podman Commands
**Start services in detached mode:**
```sh
docker build -t lightsaver-app .
podman-compose up -d
```
To run the container:
**Stop services:**
```sh
docker run -p 3000:3000 lightsaver-app
```
podman-compose down
```
**Stop services and remove volumes:**
```sh
podman-compose down -v
```
**View logs:**
```sh
# All services
podman-compose logs -f
# Specific service
podman-compose logs -f frontend
podman-compose logs -f api
```
**Rebuild services:**
```sh
podman-compose build
podman-compose up --build
```
**Run commands in a service container:**
```sh
# Frontend
podman-compose exec frontend pnpm install
podman-compose exec frontend pnpm build
# API
podman-compose exec api pnpm install
```
### Production Build
Build the production image:
```sh
podman build -t lightsaver-app .
```
Run the production container:
```sh
podman run -p 3000:3000 lightsaver-app
```
### Service Architecture
The project uses the following services:
- **frontend**: Next.js application (port 3000)
- **api**: Express + GraphQL API (port 4000)
- **postgres**: PostgreSQL database (port 5432)
- **rabbitmq**: RabbitMQ message broker (ports 5672, 15672)
### Troubleshooting
**Port conflicts:**
If ports are already in use, modify the port mappings in `docker-compose.yml`.
**Permission issues with volumes:**
Podman runs rootless by default. Add `:z` or `:Z` to volume mounts if you encounter permission issues.
**SELinux issues:**
The dev compose file includes `:z` flags for volume mounts to handle SELinux contexts.
**Container doesn't start:**
Check logs with `podman-compose logs <service-name>` to diagnose issues.
+61
View File
@@ -0,0 +1,61 @@
version: '3.8'
# Development-specific configuration
# Usage: podman-compose -f docker-compose.yml -f docker-compose.dev.yml up
services:
postgres:
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
# Add local SQL scripts for development
- ./scripts/db:/docker-entrypoint-initdb.d
rabbitmq:
ports:
- "5672:5672"
- "15672:15672"
volumes:
- rabbitmq_data:/var/lib/rabbitmq
api:
build:
target: builder
environment:
NODE_ENV: development
DEBUG: "api:*"
volumes:
# Enable hot-reload for development
- ./services:/app/services:z
- ./packages:/app/packages:z
# Prevent overwriting node_modules
- /app/node_modules
- /app/services/node_modules
stdin_open: true
tty: true
frontend:
build:
target: builder
environment:
NODE_ENV: development
NEXT_TELEMETRY_DISABLED: 1
volumes:
# Enable hot-reload for development
- ./apps/lightsaver_user_client:/app/apps/lightsaver_user_client:z
- ./packages:/app/packages:z
# Prevent overwriting node_modules and build artifacts
- /app/node_modules
- /app/apps/lightsaver_user_client/node_modules
- /app/apps/lightsaver_user_client/.next
stdin_open: true
tty: true
volumes:
postgres_data:
rabbitmq_data:
networks:
lightsaver-network:
driver: bridge
+100
View File
@@ -0,0 +1,100 @@
version: '3.8'
services:
# PostgreSQL Database
postgres:
image: docker.io/library/postgres:16-alpine
container_name: lightsaver-postgres
environment:
POSTGRES_USER: ${POSTGRES_USER:-lightsaver}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-lightsaver_dev}
POSTGRES_DB: ${POSTGRES_DB:-lightsaver}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-lightsaver}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightsaver-network
# RabbitMQ Message Broker
rabbitmq:
image: docker.io/library/rabbitmq:3-management-alpine
container_name: lightsaver-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-lightsaver}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-lightsaver_dev}
ports:
- "5672:5672" # AMQP port
- "15672:15672" # Management UI
volumes:
- rabbitmq_data:/var/lib/rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 30s
timeout: 10s
retries: 5
networks:
- lightsaver-network
# Backend API Service
api:
build:
context: .
dockerfile: Dockerfile.api
container_name: lightsaver-api
environment:
NODE_ENV: ${NODE_ENV:-development}
PORT: ${API_PORT:-4000}
DATABASE_URL: postgresql://${POSTGRES_USER:-lightsaver}:${POSTGRES_PASSWORD:-lightsaver_dev}@postgres:5432/${POSTGRES_DB:-lightsaver}
RABBITMQ_URL: amqp://${RABBITMQ_USER:-lightsaver}:${RABBITMQ_PASSWORD:-lightsaver_dev}@rabbitmq:5672
ports:
- "4000:4000"
volumes:
- ./services:/app/services
- ./packages:/app/packages
- /app/node_modules
- /app/services/node_modules
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
networks:
- lightsaver-network
command: sh -c "cd /app && pnpm install && pnpm --filter api dev"
# Frontend Next.js Application
frontend:
build:
context: .
dockerfile: Dockerfile.frontend
container_name: lightsaver-frontend
environment:
NODE_ENV: ${NODE_ENV:-development}
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:4000/graphql}
ports:
- "3000:3000"
volumes:
- ./apps/lightsaver_user_client:/app/apps/lightsaver_user_client
- ./packages:/app/packages
- /app/node_modules
- /app/apps/lightsaver_user_client/node_modules
- /app/apps/lightsaver_user_client/.next
depends_on:
- api
networks:
- lightsaver-network
command: sh -c "cd /app && pnpm install && pnpm --filter lightsaver_user_client dev"
networks:
lightsaver-network:
driver: bridge
volumes:
postgres_data:
rabbitmq_data:
+16
View File
@@ -0,0 +1,16 @@
-- LightSaver Database Initialization Script
-- This script runs automatically when the PostgreSQL container starts for the first time
-- Create extensions if needed
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Add your table definitions here
-- Example:
-- CREATE TABLE IF NOT EXISTS users (
-- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
-- email VARCHAR(255) UNIQUE NOT NULL,
-- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-- );
-- Add initial seed data here if needed
+21
View File
@@ -0,0 +1,21 @@
# Database Initialization Scripts
SQL scripts in this directory are automatically executed when the PostgreSQL container is first initialized.
## Usage
- Scripts are executed in alphabetical order
- Use numbered prefixes (01-, 02-, etc.) to control execution order
- Place schema definitions in early scripts
- Place seed data in later scripts
## Example
- `01-init.sql` - Create extensions and initial schema
- `02-seed.sql` - Insert initial data
- `03-indexes.sql` - Create indexes
## Notes
- These scripts only run on first container creation
- To re-run, you must remove the postgres volume: `make clean` or `podman-compose down -v`