diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..28aa464 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +# Git +.git +.gitignore + +# Binaries +alpenqueue +*.exe +*.dll +*.so +*.dylib + +# Test files +*_test.go + +# Database files +*.db +*.db-shm +*.db-wal + +# Documentation +README.md +*.md + +# Docker files (prevent recursion) +Dockerfile +docker-compose.yml +.dockerignore + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo + +# OS files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..68ec2f9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +# Multi-stage build for smaller final image +FROM golang:1.25-alpine AS builder + +# Install build dependencies for CGO (required for SQLite) +RUN apk add --no-cache gcc musl-dev sqlite-dev + +# Set working directory +WORKDIR /build + +# Copy go mod files +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY . . + +# Build the application with CGO enabled for SQLite +RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o alpenqueue ./cmd/alpenqueue + +# Final stage - minimal image +FROM alpine:latest + +# Install runtime dependencies +RUN apk --no-cache add ca-certificates sqlite-libs + +# Create non-root user +RUN addgroup -g 1001 -S alpenqueue && \ + adduser -u 1001 -S alpenqueue -G alpenqueue + +# Set working directory +WORKDIR /app + +# Copy binary from builder +COPY --from=builder /build/alpenqueue . + +# Create directory for SQLite database +RUN mkdir -p /app/data && chown -R alpenqueue:alpenqueue /app + +# Switch to non-root user +USER alpenqueue + +# Expose port +EXPOSE 8080 + +# Volume for persistent data +VOLUME ["/app/data"] + +# Run the application +CMD ["./alpenqueue"] \ No newline at end of file diff --git a/README.md b/README.md index 14dbdef..a485882 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,39 @@ A simple, self-hosted web scraping task queue with SQLite persistence, flexible ## Quick Start -### Prerequisites +### 🐳 Docker (Recommended) + +The easiest way to run AlpenQueue is with Docker: + +```bash +# Using Docker Compose (recommended) +docker-compose up -d + +# Or build and run manually +docker build -t alpenqueue . +docker run -d -p 8080:8080 -v alpenqueue-data:/app/data alpenqueue +``` + +That's it! AlpenQueue is now running on http://localhost:8080 + +#### Docker Configuration + +- **Port**: 8080 (configurable in docker-compose.yml) +- **Data**: Persisted in Docker volume `alpenqueue-data` +- **Database**: SQLite database stored in `/app/data/` +- **User**: Runs as non-root user for security + +### Manual Installation + +#### Prerequisites - Go 1.25 or later - SQLite (automatically included via go-sqlite3) -### Installation +#### Installation ```bash -git clone https://github.com/yourusername/alpenqueue.git +git clone https://git.maxtheweb.com/maxtheweb/AlpenQueue.git cd AlpenQueue go build -o alpenqueue ./cmd/alpenqueue ``` diff --git a/cmd/alpenqueue/main.go b/cmd/alpenqueue/main.go index 70a8068..e518405 100644 --- a/cmd/alpenqueue/main.go +++ b/cmd/alpenqueue/main.go @@ -8,10 +8,17 @@ import ( "io" "log" "net/http" + "os" ) func main() { - database, err := db.Init("./alpenqueue.db") + // Get database path from environment or use default + dbPath := os.Getenv("DATABASE_PATH") + if dbPath == "" { + dbPath = "./alpenqueue.db" + } + + database, err := db.Init(dbPath) if err != nil { log.Fatal(err) } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d21390a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' + +services: + alpenqueue: + build: . + image: alpenqueue:latest + container_name: alpenqueue + ports: + - "8080:8080" + volumes: + # Persist SQLite database + - alpenqueue-data:/app/data + environment: + # Optional: Override default database location + - DATABASE_PATH=/app/data/alpenqueue.db + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + networks: + - alpenqueue-network + +volumes: + alpenqueue-data: + driver: local + +networks: + alpenqueue-network: + driver: bridge \ No newline at end of file