diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c8fde07 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,38 @@ +# Dependencies +node_modules/ +npm-debug.log* + +# Logs +logs/ +*.log + +# Data +data/ + +# Configuration +config.json +.env + +# Git +.git/ +.gitignore + +# Documentation +docs/ +README.md + +# Docker +Dockerfile +docker-compose.yml +.dockerignore + +# CI/CD +.github/ + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml new file mode 100644 index 0000000..88a7ec7 --- /dev/null +++ b/.github/workflows/docker-build-push.yml @@ -0,0 +1,50 @@ +name: Build and Push Docker Image + +on: + push: + branches: [ main ] + tags: + - 'v*' + workflow_dispatch: + +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 GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..78c2e78 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM node:24-alpine + +# Install netcat for healthcheck +RUN apk add --no-cache netcat-openbsd + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm ci --only=production + +# Copy application files +COPY src/ ./src/ + +# Create directories for logs and data +RUN mkdir -p /app/logs /app/data + +# Expose SMTP port +EXPOSE 2525 + +# Set environment variable for config path +ENV CONFIG_PATH=/app/config/config.json + +# Run the application +CMD ["node", "src/index.js"] diff --git a/README.md b/README.md index 415b374..b99924a 100644 --- a/README.md +++ b/README.md @@ -44,24 +44,27 @@ For deployment: ## Installation -TODO: Docker support -### Using Docker (Recommended) TODO +### Using Docker (Recommended) -1. Clone the repository: +1. Create a directory for your configuration: ```bash - git clone https://github.com/ovosimpatico/smtp-loadbalancer.git - cd smtp-loadbalancer + mkdir smtp-loadbalancer && cd smtp-loadbalancer ``` -2. Make your `config.json` file based on the [example file](config.example.json) +2. Download the example configuration and docker-compose file: + ```bash + curl -O https://raw.githubusercontent.com/ovosimpatico/smtp-loadbalancer/main/config.example.json + curl -O https://raw.githubusercontent.com/ovosimpatico/smtp-loadbalancer/main/docker-compose.yml + ``` +3. Create your `config.json` file: ```bash cp config.example.json config.json nano config.json ``` -3. Run the application: +4. Run the application: ```bash docker compose up -d ``` -4. The SMTP server will be listening on port `2525`. +5. The SMTP server will be listening on port `2525`. ### Native Node.js Installation diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b5dc9ee --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +services: + smtp-loadbalancer: + container_name: smtp-loadbalancer + image: ghcr.io/ovosimpatico/smtp-loadbalancer:latest + # build: + # context: . + # dockerfile: Dockerfile + + volumes: + # Config file + - ./config.json:/app/config/config.json:ro + # Logs + - ./logs:/app/logs + # Email queue DB + - ./data:/app/data + environment: + - NODE_ENV=production + - CONFIG_PATH=/app/config/config.json + ports: + - "2525:2525" + restart: unless-stopped + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "2525"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s