2
0
forked from jmug/cactoide

feat: add Github Action to build the image

This commit is contained in:
Levente Orban
2025-08-27 09:36:24 +02:00
parent 9feb3bf64d
commit 1091ffe959
6 changed files with 195 additions and 219 deletions

45
.github/workflows/build-and-push.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Build and Push to GHCR
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/cactoide
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: ${{ github.event_name != 'pull_request' }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
- name: Output image info
if: github.event_name != 'pull_request'
run: |
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"

41
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Test and Build
on:
push:
branches: [main]
pull_request:
branches: ['**']
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run type checking
run: npm run check
- name: Run linting
run: npm run lint
- name: Build application
run: npm run build
- name: Test build output
run: |
if [ ! -d "build" ]; then
echo "Build directory not found!"
exit 1
fi
echo "Build successful! Build directory exists."

View File

@@ -1,218 +0,0 @@
# Docker Setup for Cactoide
This document explains how to run the Cactoide application using Docker containers.
## Prerequisites
- Docker installed on your system
- Docker Compose installed
- Make (optional, but recommended for easier management)
## Quick Start
### 1. Build and Start Everything
```bash
# Build images and start all services
make build-and-up
# Or manually:
docker-compose up -d --build
```
### 2. Access the Application
- **Application**: http://localhost:3000
- **Database**: localhost:5432
## Available Commands
### Using Make (Recommended)
```bash
# Show all available commands
make help
# Start all services
make up
# Stop all services
make down
# Restart all services
make restart
# View logs
make logs
# Check status
make status
# Clean up everything
make clean
```
### Using Docker Compose Directly
```bash
# Start services
docker-compose up -d
# Stop services
docker-compose down
# View logs
docker-compose logs -f
# Check status
docker-compose ps
```
## Development Mode
For development with hot reloading:
```bash
# Start development environment
make dev
# Or manually:
docker-compose -f docker-compose.dev.yml up
```
Development mode runs on port **5173** with hot reloading enabled.
## Individual Services
### Start Only Database
```bash
make db-only
```
### Start Only Application (requires database to be running)
```bash
make app-only
```
## Database Management
### Access Database Shell
```bash
make db-shell
```
### Database Initialization
The database is automatically initialized with the schema from `database/init.sql` when the container starts for the first time.
### Persistent Data
Database data is stored in a Docker volume (`postgres_data`) and persists between container restarts.
## Environment Variables
The following environment variables are automatically set in the containers:
- `DATABASE_URL`: PostgreSQL connection string
- `NODE_ENV`: Environment mode (production/development)
- `POSTGRES_DB`: Database name
- `POSTGRES_USER`: Database user
- `POSTGRES_PASSWORD`: Database password
## Ports
- **3000**: Production application
- **5173**: Development application (with hot reloading)
- **5432**: PostgreSQL database
## Troubleshooting
### Check Service Status
```bash
make status
```
### View Logs
```bash
# All services
make logs
# Specific service
make logs-app
make logs-db
```
### Restart Services
```bash
make restart
```
### Clean Start
```bash
make clean
make build-and-up
```
### Database Connection Issues
1. Ensure the database container is healthy:
```bash
docker-compose ps postgres
```
2. Check database logs:
```bash
make logs-db
```
3. Verify environment variables:
```bash
docker-compose exec app env | grep DATABASE
```
## File Structure
```
.
├── Dockerfile # Production application image
├── Dockerfile.dev # Development application image
├── docker-compose.yml # Production services
├── docker-compose.dev.yml # Development services
├── Makefile # Management commands
├── .dockerignore # Docker build exclusions
└── database/
└── init.sql # Database initialization script
```
## Production Deployment
For production deployment, use the production compose file:
```bash
docker-compose up -d
```
The production setup:
- Runs the built SvelteKit application
- Uses optimized Node.js production image
- Includes health checks and restart policies
- Runs on port 3000
## Development Workflow
1. **Start development environment**: `make dev`
2. **Make code changes** - they will automatically reload
3. **Test your changes** in the browser
4. **Stop development**: `Ctrl+C` or `make down`
5. **Build for production**: `make build`
6. **Deploy**: `make up`

View File

@@ -40,7 +40,45 @@ Your app will be available at `http://localhost:5173`
### 🚀 Self-Host
WIP
#### Using GitHub Container Registry (GHCR)
The application is automatically built and pushed to GitHub Container Registry on every push to main/master branch.
```bash
# Pull the latest image
docker pull ghcr.io/${{ github.repository }}/cactoide:latest
# Or use a specific tag
docker pull ghcr.io/${{ github.repository }}/cactoide:main-abc1234
# Run the container
docker run -p 3000:3000 \
-e DATABASE_URL="your-database-url" \
ghcr.io/${{ github.repository }}/cactoide:latest
```
#### Using Docker Compose with GHCR
```yaml
# docker-compose.prod.yml
version: '3.8'
services:
app:
image: ghcr.io/${{ github.repository }}/cactoide:latest
ports:
- '3000:3000'
environment:
- DATABASE_URL=your-production-database-url
- NODE_ENV=production
restart: unless-stopped
```
#### Available Tags
- `latest` - Latest commit on main branch
- `main-<sha>` - Specific commit on main branch
- `v1.0.0` - Semantic version tags
- `1.0` - Major.minor version tags
### 📄 License

59
docker-compose.prod.yml Normal file
View File

@@ -0,0 +1,59 @@
version: '3.8'
services:
# Database
postgres:
image: postgres:15-alpine
container_name: cactoide-db-prod
environment:
POSTGRES_DB: ${POSTGRES_DB:-cactoied_database}
POSTGRES_USER: ${POSTGRES_USER:-cactoide}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-cactoide_password}
ports:
- '5432:5432'
volumes:
- postgres_data_prod:/var/lib/postgresql/data
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test:
[
'CMD-SHELL',
'pg_isready -U ${POSTGRES_USER:-cactoide} -d ${POSTGRES_DB:-cactoied_database}'
]
interval: 10s
timeout: 5s
retries: 5
networks:
- cactoide-network-prod
restart: unless-stopped
# Application
app:
image: ghcr.io/polaroi8d/cactoide:latest
container_name: cactoide-app-prod
ports:
- '3000:3000'
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-cactoide}:${POSTGRES_PASSWORD:-cactoide_password}@postgres:5432/${POSTGRES_DB:-cactoied_database}
NODE_ENV: production
PORT: 3000
HOSTNAME: 0.0.0.0
depends_on:
postgres:
condition: service_healthy
networks:
- cactoide-network-prod
restart: unless-stopped
healthcheck:
test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:3000/']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
postgres_data_prod:
networks:
cactoide-network-prod:
driver: bridge

11
env.prod.example Normal file
View File

@@ -0,0 +1,11 @@
# Production Environment Variables
# Copy this file to .env.prod and update the values
# Database Configuration
POSTGRES_DB=cactoide_production
POSTGRES_USER=cactoide_prod
POSTGRES_PASSWORD=your_secure_password_here
# App Configuration
NODE_ENV=production
PORT=3000