diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a48068a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,40 @@ +# Dependencies (rebuilt in container) +node_modules/ + +# Git +.git/ +.gitignore + +# Data and databases +data/ +*.db +*.db-journal +*.db-wal + +# Environment and secrets +.env +.env.* +!.env.example + +# Development and testing +test/ +demo-assets/ +docs/ + +# CI/CD +.github/ + +# IDE and editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS files +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..67d94f5 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,62 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + - 'release/**' + - 'dev/**' + tags: + - 'v*' + +env: + REGISTRY: docker.io + IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} + USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Determine Docker Tags + id: docker_tags + run: | + TAGS="" + if [[ "${{ github.ref }}" == refs/tags/v* ]]; then + TAG_VERSION=${GITHUB_REF#refs/tags/} + TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG_VERSION},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" + echo "Building release: $TAG_VERSION" + else + TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:devel" + echo "Building development version" + fi + echo "TAGS=$TAGS" >> $GITHUB_OUTPUT + echo "Docker tags: $TAGS" + + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ env.USERNAME }} + password: ${{ env.TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.docker_tags.outputs.TAGS }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4ac3461 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# Build stage +FROM node:20-alpine AS builder + +WORKDIR /app + +# Install build dependencies for better-sqlite3 +RUN apk add --no-cache python3 make g++ + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm ci --only=production + +# Copy source code +COPY src/ ./src/ +COPY migrations/ ./migrations/ +COPY templates/ ./templates/ +COPY web/ ./web/ + +# Production stage +FROM node:20-alpine + +WORKDIR /app + +# Copy built artifacts from builder +COPY --from=builder /app ./ + +# Create data directory and set ownership +RUN mkdir -p /app/data && chown -R node:node /app + +# Use non-root user +USER node + +ENV NODE_ENV=production +ENV DIGEST_PORT=8767 +ENV DIGEST_HOST=0.0.0.0 + +EXPOSE 8767 + +# Health check for orchestration environments +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget -q --spider http://localhost:8767/ || exit 1 + +CMD ["node", "src/server.mjs"] diff --git a/README.md b/README.md index 2520972..ac22903 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,25 @@ cd clawfeed npm install ``` +### Option 5: Docker +```bash +# Basic usage +docker run -d -p 8767:8767 kevinho/clawfeed + +# With persistent data +docker run -d -p 8767:8767 -v clawfeed-data:/app/data kevinho/clawfeed + +# With environment variables (recommended for production) +docker run -d -p 8767:8767 \ + -v clawfeed-data:/app/data \ + -e ALLOWED_ORIGINS=https://yourdomain.com \ + -e API_KEY=your-api-key \ + -e GOOGLE_CLIENT_ID=your-client-id \ + -e GOOGLE_CLIENT_SECRET=your-client-secret \ + -e SESSION_SECRET=your-session-secret \ + kevinho/clawfeed +``` + ## Quick Start ```bash diff --git a/src/server.mjs b/src/server.mjs index b58abc7..417b579 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -864,6 +864,7 @@ const server = createServer(async (req, res) => { } }); -server.listen(PORT, '127.0.0.1', () => { - console.log(`🚀 ClawFeed API running on http://127.0.0.1:${PORT}`); +const HOST = process.env.DIGEST_HOST || '127.0.0.1'; +server.listen(PORT, HOST, () => { + console.log(`🚀 ClawFeed API running on http://${HOST}:${PORT}`); });