Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions docker-compose.cluster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Links Queue - Multi-Node Cluster Setup
#
# This docker-compose file provides a multi-node cluster setup
# for Links Queue, demonstrating distributed operation.
#
# Usage:
# docker-compose -f docker-compose.cluster.yml up -d
# docker-compose -f docker-compose.cluster.yml logs -f
# docker-compose -f docker-compose.cluster.yml down
#
# Access nodes at:
# - Node 1: tcp://localhost:5001
# - Node 2: tcp://localhost:5002
# - Node 3: tcp://localhost:5003

services:
# ==========================================================================
# Node 1 - Primary seed node
# ==========================================================================
links-queue-node1:
build:
context: .
dockerfile: docker/Dockerfile.js
container_name: links-queue-node1
hostname: node1
restart: unless-stopped
ports:
- "5001:5000"
environment:
- NODE_ENV=production
- LINKS_QUEUE_HOST=0.0.0.0
- LINKS_QUEUE_PORT=5000
- LINKS_QUEUE_NODE_ID=node1
- LINKS_QUEUE_CLUSTER_ENABLED=true
- LINKS_QUEUE_CLUSTER_SEEDS=node1:5000,node2:5000,node3:5000
networks:
- links-queue-cluster
healthcheck:
test: ["CMD", "node", "-e", "require('net').createConnection({port: 5000}).on('connect', () => process.exit(0)).on('error', () => process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M

# ==========================================================================
# Node 2
# ==========================================================================
links-queue-node2:
build:
context: .
dockerfile: docker/Dockerfile.js
container_name: links-queue-node2
hostname: node2
restart: unless-stopped
ports:
- "5002:5000"
environment:
- NODE_ENV=production
- LINKS_QUEUE_HOST=0.0.0.0
- LINKS_QUEUE_PORT=5000
- LINKS_QUEUE_NODE_ID=node2
- LINKS_QUEUE_CLUSTER_ENABLED=true
- LINKS_QUEUE_CLUSTER_SEEDS=node1:5000,node2:5000,node3:5000
networks:
- links-queue-cluster
depends_on:
links-queue-node1:
condition: service_healthy
healthcheck:
test: ["CMD", "node", "-e", "require('net').createConnection({port: 5000}).on('connect', () => process.exit(0)).on('error', () => process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M

# ==========================================================================
# Node 3
# ==========================================================================
links-queue-node3:
build:
context: .
dockerfile: docker/Dockerfile.js
container_name: links-queue-node3
hostname: node3
restart: unless-stopped
ports:
- "5003:5000"
environment:
- NODE_ENV=production
- LINKS_QUEUE_HOST=0.0.0.0
- LINKS_QUEUE_PORT=5000
- LINKS_QUEUE_NODE_ID=node3
- LINKS_QUEUE_CLUSTER_ENABLED=true
- LINKS_QUEUE_CLUSTER_SEEDS=node1:5000,node2:5000,node3:5000
networks:
- links-queue-cluster
depends_on:
links-queue-node1:
condition: service_healthy
healthcheck:
test: ["CMD", "node", "-e", "require('net').createConnection({port: 5000}).on('connect', () => process.exit(0)).on('error', () => process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M

networks:
links-queue-cluster:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
56 changes: 56 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Links Queue - Single Node Setup
#
# This docker-compose file provides a simple single-node setup
# for Links Queue, suitable for development and testing.
#
# Usage:
# docker-compose up -d
# docker-compose logs -f
# docker-compose down
#
# Access the queue server at: tcp://localhost:5000

services:
links-queue:
build:
context: .
dockerfile: docker/Dockerfile.js
container_name: links-queue
restart: unless-stopped
ports:
- "5000:5000"
environment:
- NODE_ENV=production
- LINKS_QUEUE_HOST=0.0.0.0
- LINKS_QUEUE_PORT=5000
- LINKS_QUEUE_MAX_CONNECTIONS=1000
- LINKS_QUEUE_IDLE_TIMEOUT=60000
healthcheck:
test: ["CMD", "node", "-e", "require('net').createConnection({port: 5000}).on('connect', () => process.exit(0)).on('error', () => process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M

# Optional: Run the Rust version instead
# Uncomment the following and comment out the above service
#
# links-queue-rust:
# build:
# context: .
# dockerfile: docker/Dockerfile.rust
# container_name: links-queue-rust
# restart: unless-stopped
# ports:
# - "5000:5000"
# environment:
# - LINKS_QUEUE_HOST=0.0.0.0
# - LINKS_QUEUE_PORT=5000
145 changes: 145 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Links Queue Docker Image
#
# Multi-stage build for minimal image size.
# Supports both JavaScript and Rust implementations.
#
# Build arguments:
# - RUNTIME: js (default) or rust
#
# Usage:
# docker build -t links-queue .
# docker build -t links-queue-rust --build-arg RUNTIME=rust .

ARG RUNTIME=js

# =============================================================================
# JavaScript Build Stage
# =============================================================================

FROM node:22-alpine AS js-builder

WORKDIR /app

# Copy package files
COPY js/package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy source code
COPY js/src ./src

# =============================================================================
# JavaScript Runtime Stage
# =============================================================================

FROM node:22-alpine AS js-runtime

LABEL org.opencontainers.image.title="Links Queue (JavaScript)"
LABEL org.opencontainers.image.description="Universal queue system using links"
LABEL org.opencontainers.image.vendor="Link Foundation"
LABEL org.opencontainers.image.source="https://github.com/link-foundation/links-queue"
LABEL org.opencontainers.image.licenses="Unlicense"

WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 -S linksqueue && \
adduser -u 1001 -S linksqueue -G linksqueue

# Copy from builder
COPY --from=js-builder --chown=linksqueue:linksqueue /app/node_modules ./node_modules
COPY --from=js-builder --chown=linksqueue:linksqueue /app/src ./src
COPY --chown=linksqueue:linksqueue js/package.json ./

# Set environment
ENV NODE_ENV=production
ENV LINKS_QUEUE_HOST=0.0.0.0
ENV LINKS_QUEUE_PORT=5000

# Expose default port
EXPOSE 5000

# Switch to non-root user
USER linksqueue

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD node -e "require('net').createConnection({port: process.env.LINKS_QUEUE_PORT || 5000}).on('connect', () => process.exit(0)).on('error', () => process.exit(1))"

# Run server
CMD ["node", "src/cli.js", "server"]

# =============================================================================
# Rust Build Stage
# =============================================================================

FROM rust:1.75-alpine AS rust-builder

# Install build dependencies
RUN apk add --no-cache musl-dev

WORKDIR /app

# Copy Cargo files
COPY rust/Cargo.toml rust/Cargo.lock* ./

# Create dummy src to cache dependencies
RUN mkdir -p src && \
echo 'fn main() {}' > src/main.rs && \
echo 'pub fn dummy() {}' > src/lib.rs

# Build dependencies only
RUN cargo build --release && \
rm -rf src

# Copy actual source
COPY rust/src ./src

# Build the actual binary
RUN touch src/main.rs src/lib.rs && \
cargo build --release

# =============================================================================
# Rust Runtime Stage
# =============================================================================

FROM alpine:3.19 AS rust-runtime

LABEL org.opencontainers.image.title="Links Queue (Rust)"
LABEL org.opencontainers.image.description="Universal queue system using links"
LABEL org.opencontainers.image.vendor="Link Foundation"
LABEL org.opencontainers.image.source="https://github.com/link-foundation/links-queue"
LABEL org.opencontainers.image.licenses="Unlicense"

WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 -S linksqueue && \
adduser -u 1001 -S linksqueue -G linksqueue

# Copy binary from builder
COPY --from=rust-builder --chown=linksqueue:linksqueue /app/target/release/links-queue /usr/local/bin/

# Set environment
ENV LINKS_QUEUE_HOST=0.0.0.0
ENV LINKS_QUEUE_PORT=5000

# Expose default port
EXPOSE 5000

# Switch to non-root user
USER linksqueue

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD nc -z localhost ${LINKS_QUEUE_PORT:-5000} || exit 1

# Run server
CMD ["links-queue", "server"]

# =============================================================================
# Final Stage Selection
# =============================================================================

FROM ${RUNTIME}-runtime AS final
Loading
Loading