FROM crystallang/crystal:1.14.0-alpine AS builder # Install build dependencies RUN apk add --no-cache \ yaml-dev \ openssl-dev \ zlib-dev \ sqlite-dev \ postgresql-dev \ bind-tools \ git \ curl # Set build arguments ARG APP_NAME=dns-manager WORKDIR /build # Copy the entire project for proper relative imports COPY . . # Install dependencies RUN shards install # Build the binary with standalone flag RUN cd src/dns-manager && crystal build --release --static src/main.cr -o "${APP_NAME}" -D standalone # Runtime stage FROM alpine:3.19 # Install runtime dependencies RUN apk add --no-cache \ ca-certificates \ tzdata \ openssl \ yaml \ bind-tools \ bind-libs WORKDIR /app # Copy the binary from builder COPY --from=builder /build/src/dns-manager/"${APP_NAME}" . # Create non-root user and set permissions RUN adduser -D appuser && \ chown -R appuser:appuser /app && \ find /app -type f -exec chmod 500 {} \; && \ find /app -type d -exec chmod 755 {} \; && \ chmod 550 /app/"${APP_NAME}" USER appuser # Set environment variables ENV PORT=8081 ENV KEMAL_ENV=production # Expose port EXPOSE 8081 ENTRYPOINT ["/app/dns-manager"]