diff --git a/Dockerfile.multiarch b/Dockerfile.multiarch new file mode 100644 index 0000000..ccb9239 --- /dev/null +++ b/Dockerfile.multiarch @@ -0,0 +1,77 @@ +# HMAC File Server 3.3.0 "Nexus Infinitum" - Multi-Architecture Dockerfile +# Supports: AMD64, ARM64, ARM32v7 + +FROM --platform=$BUILDPLATFORM golang:1.24-alpine AS builder + +# Build arguments for cross-compilation +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT + +WORKDIR /build + +# Install build dependencies +RUN apk add --no-cache git ca-certificates tzdata + +# Copy Go modules first for better caching +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build binary with cross-compilation support +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ + go build -ldflags="-w -s -X main.version=3.3.0" \ + -a -installsuffix cgo \ + -o hmac-file-server ./cmd/server/ + +# Production stage - Multi-arch Alpine +FROM --platform=$TARGETPLATFORM alpine:latest + +# Install runtime dependencies +RUN apk add --no-cache \ + ca-certificates \ + tzdata \ + curl \ + shadow + +# Create non-root user for security +RUN adduser -D -s /bin/sh -u 1011 appuser + +# Create application directories +RUN mkdir -p /opt/hmac-file-server/{data/{uploads,duplicates,temp,logs},config} \ + && chown -R appuser:appuser /opt/hmac-file-server \ + && chmod 750 /opt/hmac-file-server/data/{uploads,duplicates,temp,logs} + +WORKDIR /opt/hmac-file-server + +# Copy binary from builder stage +COPY --from=builder /build/hmac-file-server /usr/local/bin/hmac-file-server +RUN chmod +x /usr/local/bin/hmac-file-server + +# Copy configuration templates +COPY templates/config-docker.toml /opt/hmac-file-server/config/config.toml.example + +# Switch to non-root user +USER appuser + +# Expose ports +EXPOSE 8080 8888 + +# Health check that works across architectures +HEALTHCHECK --interval=30s --timeout=15s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:8888/health || exit 1 + +# Add multi-arch labels +LABEL org.opencontainers.image.title="HMAC File Server" \ + org.opencontainers.image.description="Secure multi-architecture file server with XEP-0363 support" \ + org.opencontainers.image.version="3.3.0" \ + org.opencontainers.image.vendor="UUXO" \ + org.opencontainers.image.source="https://git.uuxo.net/uuxo/hmac-file-server/" \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.architecture="multi" + +# Entry point +ENTRYPOINT ["/usr/local/bin/hmac-file-server"] +CMD ["-config", "/opt/hmac-file-server/config/config.toml"] diff --git a/build-multi-arch.sh b/build-multi-arch.sh new file mode 100755 index 0000000..6aea852 --- /dev/null +++ b/build-multi-arch.sh @@ -0,0 +1,313 @@ +#!/bin/bash +# HMAC File Server 3.3.0 "Nexus Infinitum" - Multi-Architecture Builder +# Builds binaries for multiple architectures and platforms + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +NC='\033[0m' + +# Configuration +VERSION="3.3.0" +PROJECT_NAME="hmac-file-server" +BUILD_DIR="builds" +SOURCE_FILES="./cmd/server/" + +# Supported architectures +declare -A PLATFORMS=( + ["linux/amd64"]="Linux AMD64 (Intel/AMD 64-bit)" + ["linux/arm64"]="Linux ARM64 (Apple Silicon, Raspberry Pi 4+)" + ["linux/arm"]="Linux ARM32v7 (Raspberry Pi 3+)" + ["linux/386"]="Linux 386 (32-bit Intel)" + ["darwin/amd64"]="macOS Intel" + ["darwin/arm64"]="macOS Apple Silicon" + ["windows/amd64"]="Windows 64-bit" + ["windows/386"]="Windows 32-bit" + ["freebsd/amd64"]="FreeBSD AMD64" + ["openbsd/amd64"]="OpenBSD AMD64" +) + +# Functions +print_header() { + echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}" + echo -e "${BLUE}║${NC} ${CYAN}HMAC File Server 3.3.0 'Nexus Infinitum' Multi-Arch Builder${NC} ${BLUE}║${NC}" + echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}" + echo "" +} + +print_info() { + echo -e "${GREEN}✓${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}⚠${NC} $1" +} + +print_error() { + echo -e "${RED}✗${NC} $1" +} + +print_status() { + echo -e "${PURPLE}▶${NC} $1" +} + +build_binary() { + local platform=$1 + local description=$2 + local goos=$(echo $platform | cut -d'/' -f1) + local goarch=$(echo $platform | cut -d'/' -f2) + + local output_name="${PROJECT_NAME}-${goos}-${goarch}" + if [ "$goos" = "windows" ]; then + output_name="${output_name}.exe" + fi + + local output_path="${BUILD_DIR}/${output_name}" + + print_status "Building for ${description} (${platform})..." + + # Set build environment + export GOOS=$goos + export GOARCH=$goarch + export CGO_ENABLED=0 + + # Build with optimizations + if go build -ldflags="-w -s -X main.version=${VERSION}" -o "$output_path" $SOURCE_FILES; then + # Get file size + local size + if command -v stat >/dev/null 2>&1; then + if [[ "$OSTYPE" == "darwin"* ]]; then + size=$(stat -f%z "$output_path" 2>/dev/null | awk '{printf "%.1fMB", $1/1024/1024}') + else + size=$(stat -c%s "$output_path" 2>/dev/null | awk '{printf "%.1fMB", $1/1024/1024}') + fi + else + size="Unknown" + fi + + print_info " ✓ Built ${output_name} (${size})" + return 0 + else + print_error " ✗ Failed to build ${output_name}" + return 1 + fi +} + +show_menu() { + echo -e "${YELLOW}Select build targets:${NC}" + echo "" + echo "1) All supported platforms (recommended)" + echo "2) Linux only (AMD64, ARM64, ARM32v7)" + echo "3) Cross-platform (Linux, macOS, Windows)" + echo "4) Custom selection" + echo "5) Quick build (Linux AMD64 only)" + echo "" + echo "0) Exit" + echo "" +} + +build_all() { + print_status "Building for all supported platforms..." + local success=0 + local total=0 + + for platform in "${!PLATFORMS[@]}"; do + total=$((total + 1)) + if build_binary "$platform" "${PLATFORMS[$platform]}"; then + success=$((success + 1)) + fi + done + + echo "" + print_info "Build summary: $success/$total platforms successful" +} + +build_linux_only() { + print_status "Building for Linux platforms..." + local platforms=("linux/amd64" "linux/arm64" "linux/arm") + local success=0 + + for platform in "${platforms[@]}"; do + if build_binary "$platform" "${PLATFORMS[$platform]}"; then + success=$((success + 1)) + fi + done + + echo "" + print_info "Linux build summary: $success/${#platforms[@]} platforms successful" +} + +build_cross_platform() { + print_status "Building for cross-platform deployment..." + local platforms=("linux/amd64" "darwin/amd64" "darwin/arm64" "windows/amd64") + local success=0 + + for platform in "${platforms[@]}"; do + if build_binary "$platform" "${PLATFORMS[$platform]}"; then + success=$((success + 1)) + fi + done + + echo "" + print_info "Cross-platform build summary: $success/${#platforms[@]} platforms successful" +} + +build_quick() { + print_status "Quick build for Linux AMD64..." + build_binary "linux/amd64" "${PLATFORMS["linux/amd64"]}" +} + +build_custom() { + echo "" + echo -e "${YELLOW}Available platforms:${NC}" + local i=1 + local platform_array=() + + for platform in "${!PLATFORMS[@]}"; do + echo "$i) $platform - ${PLATFORMS[$platform]}" + platform_array+=("$platform") + i=$((i + 1)) + done + + echo "" + echo -n "Enter platform numbers (space-separated): " + read -r selections + + local success=0 + local total=0 + + for selection in $selections; do + if [[ "$selection" =~ ^[0-9]+$ ]] && [ "$selection" -ge 1 ] && [ "$selection" -le "${#platform_array[@]}" ]; then + local platform="${platform_array[$((selection - 1))]}" + total=$((total + 1)) + if build_binary "$platform" "${PLATFORMS[$platform]}"; then + success=$((success + 1)) + fi + else + print_warning "Invalid selection: $selection" + fi + done + + echo "" + print_info "Custom build summary: $success/$total platforms successful" +} + +show_results() { + echo "" + echo -e "${CYAN}Build Results:${NC}" + echo "=============" + + if [ -d "$BUILD_DIR" ] && [ "$(ls -A $BUILD_DIR 2>/dev/null)" ]; then + ls -lh "$BUILD_DIR"/ | tail -n +2 | while read -r line; do + echo " $line" + done + + echo "" + print_info "Binaries available in: $BUILD_DIR/" + echo "" + echo -e "${YELLOW}Usage examples:${NC}" + echo " ./builds/hmac-file-server-linux-amd64 -config config.toml" + echo " ./builds/hmac-file-server-linux-arm64 -genconfig" + echo " ./builds/hmac-file-server-darwin-amd64 -version" + else + print_warning "No binaries were built" + fi +} + +cleanup_builds() { + if [ -d "$BUILD_DIR" ]; then + print_status "Cleaning previous builds..." + rm -rf "$BUILD_DIR" + print_info "Previous builds cleaned" + fi +} + +# Main execution +main() { + print_header + + # Check if Go is installed + if ! command -v go >/dev/null 2>&1; then + print_error "Go is not installed or not in PATH" + exit 1 + fi + + print_info "Go version: $(go version)" + print_info "Building HMAC File Server ${VERSION}" + echo "" + + # Create build directory + mkdir -p "$BUILD_DIR" + + # Check if source files exist + if [ ! -d "$SOURCE_FILES" ]; then + print_error "Source files not found at: $SOURCE_FILES" + exit 1 + fi + + while true; do + show_menu + echo -n "Choose an option [1-5, 0 to exit]: " + read -r choice + + case $choice in + 1) + cleanup_builds + mkdir -p "$BUILD_DIR" + build_all + show_results + break + ;; + 2) + cleanup_builds + mkdir -p "$BUILD_DIR" + build_linux_only + show_results + break + ;; + 3) + cleanup_builds + mkdir -p "$BUILD_DIR" + build_cross_platform + show_results + break + ;; + 4) + cleanup_builds + mkdir -p "$BUILD_DIR" + build_custom + show_results + break + ;; + 5) + cleanup_builds + mkdir -p "$BUILD_DIR" + build_quick + show_results + break + ;; + 0) + print_info "Goodbye!" + exit 0 + ;; + *) + print_error "Invalid option. Please try again." + echo "" + ;; + esac + done + + # Reset environment + unset GOOS GOARCH CGO_ENABLED +} + +# Run if executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi diff --git a/builddebian.sh b/builddebian.sh index 30eb251..b13705e 100755 --- a/builddebian.sh +++ b/builddebian.sh @@ -4,13 +4,7 @@ set -e -# Type=simple -Restart=always -RestartSec=5 -EnvironmentFile=-/etc/default/hmac-file-server -ExecStart=/usr/bin/hmac-file-server -config /etc/hmac-file-server/config.toml -Documentation=https://git.uuxo.net/uuxo/hmac-file-server/ -User=hmac-file-serverutput +# Colors for output GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' diff --git a/builds/hmac-file-server-darwin-amd64 b/builds/hmac-file-server-darwin-amd64 new file mode 100755 index 0000000..542a5df Binary files /dev/null and b/builds/hmac-file-server-darwin-amd64 differ diff --git a/builds/hmac-file-server-darwin-arm64 b/builds/hmac-file-server-darwin-arm64 new file mode 100755 index 0000000..1b4314d Binary files /dev/null and b/builds/hmac-file-server-darwin-arm64 differ diff --git a/builds/hmac-file-server-linux-386 b/builds/hmac-file-server-linux-386 new file mode 100755 index 0000000..5843232 Binary files /dev/null and b/builds/hmac-file-server-linux-386 differ diff --git a/builds/hmac-file-server-linux-amd64 b/builds/hmac-file-server-linux-amd64 new file mode 100755 index 0000000..1d4a4ee Binary files /dev/null and b/builds/hmac-file-server-linux-amd64 differ diff --git a/builds/hmac-file-server-linux-arm b/builds/hmac-file-server-linux-arm new file mode 100755 index 0000000..d9c4201 Binary files /dev/null and b/builds/hmac-file-server-linux-arm differ diff --git a/builds/hmac-file-server-linux-arm64 b/builds/hmac-file-server-linux-arm64 new file mode 100755 index 0000000..9b65ea1 Binary files /dev/null and b/builds/hmac-file-server-linux-arm64 differ diff --git a/docker-multiarch-build.sh b/docker-multiarch-build.sh new file mode 100755 index 0000000..77edd64 --- /dev/null +++ b/docker-multiarch-build.sh @@ -0,0 +1,222 @@ +#!/bin/bash +# HMAC File Server 3.3.0 "Nexus Infinitum" - Docker Multi-Architecture Builder +# Builds multi-arch Docker images using Docker Buildx + +set -euo pipefail + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +NC='\033[0m' + +# Configuration +IMAGE_NAME="hmac-file-server" +VERSION="3.3.0" +REGISTRY="localhost" # Change to your registry +PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7" + +# Functions +print_header() { + echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}" + echo -e "${BLUE}║${NC} ${CYAN}HMAC File Server Docker Multi-Architecture Builder${NC} ${BLUE}║${NC}" + echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}" + echo "" +} + +print_info() { + echo -e "${GREEN}✓${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}⚠${NC} $1" +} + +print_error() { + echo -e "${RED}✗${NC} $1" +} + +print_status() { + echo -e "${PURPLE}▶${NC} $1" +} + +check_requirements() { + print_status "Checking requirements..." + + # Check Docker + if ! command -v docker >/dev/null 2>&1; then + print_error "Docker is not installed or not in PATH" + exit 1 + fi + + # Check Docker Buildx + if ! docker buildx version >/dev/null 2>&1; then + print_error "Docker Buildx is not available" + print_info "Install with: docker buildx install" + exit 1 + fi + + # Check if Docker daemon is running + if ! docker info >/dev/null 2>&1; then + print_error "Docker daemon is not running" + exit 1 + fi + + print_info "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') detected" + print_info "Buildx $(docker buildx version | cut -d' ' -f2) detected" +} + +setup_buildx() { + print_status "Setting up Docker Buildx..." + + # Create builder if it doesn't exist + if ! docker buildx inspect multiarch-builder >/dev/null 2>&1; then + print_status "Creating multiarch builder..." + docker buildx create --name multiarch-builder --use --bootstrap + print_info "Multiarch builder created and activated" + else + print_info "Using existing multiarch builder" + docker buildx use multiarch-builder + fi + + # Verify platforms + print_status "Available platforms:" + docker buildx inspect --bootstrap | grep "Platforms:" | head -1 +} + +build_images() { + local push_flag="" + if [ "${1:-}" = "--push" ]; then + push_flag="--push" + print_warning "Images will be pushed to registry" + else + push_flag="--load" + print_info "Images will be loaded locally (AMD64 only)" + fi + + print_status "Building multi-architecture images..." + + # Build and optionally push + docker buildx build \ + --platform $PLATFORMS \ + --file Dockerfile.multiarch \ + --tag "${REGISTRY}/${IMAGE_NAME}:${VERSION}" \ + --tag "${REGISTRY}/${IMAGE_NAME}:latest" \ + $push_flag \ + . + + if [ "$push_flag" = "--push" ]; then + print_info "Multi-arch images built and pushed successfully" + else + print_info "Multi-arch images built and loaded locally" + fi +} + +test_images() { + print_status "Testing built images..." + + # Test AMD64 image (if loaded locally) + if [ "${1:-}" != "--push" ]; then + print_status "Testing AMD64 image..." + if docker run --rm "${REGISTRY}/${IMAGE_NAME}:${VERSION}" -version 2>/dev/null; then + print_info "AMD64 image test passed" + else + print_warning "AMD64 image test failed (this is normal if image wasn't loaded)" + fi + fi + + # Show image info + print_status "Image information:" + docker images "${REGISTRY}/${IMAGE_NAME}" 2>/dev/null | head -2 || print_warning "Images not found locally (normal if pushed to registry)" +} + +show_usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " --push Build and push to registry (multi-arch)" + echo " --local Build for local use (AMD64 only)" + echo " --registry REG Set registry (default: localhost)" + echo " --help Show this help" + echo "" + echo "Examples:" + echo " $0 --local # Build for local testing" + echo " $0 --push # Build and push multi-arch" + echo " $0 --registry hub.docker.com --push # Push to Docker Hub" +} + +# Main execution +main() { + local push_mode="" + + # Parse arguments + while [[ $# -gt 0 ]]; do + case $1 in + --push) + push_mode="--push" + shift + ;; + --local) + push_mode="--local" + shift + ;; + --registry) + REGISTRY="$2" + shift 2 + ;; + --help) + show_usage + exit 0 + ;; + *) + print_error "Unknown option: $1" + show_usage + exit 1 + ;; + esac + done + + print_header + + print_info "Configuration:" + print_info " Image: ${REGISTRY}/${IMAGE_NAME}:${VERSION}" + print_info " Platforms: ${PLATFORMS}" + print_info " Registry: ${REGISTRY}" + echo "" + + check_requirements + setup_buildx + + echo "" + + if [ "$push_mode" = "--push" ]; then + build_images --push + else + build_images --local + fi + + echo "" + test_images "$push_mode" + + echo "" + print_info "Multi-architecture Docker build complete!" + + if [ "$push_mode" = "--push" ]; then + echo "" + print_info "To use the images:" + echo " docker run -p 8080:8080 ${REGISTRY}/${IMAGE_NAME}:${VERSION}" + echo " docker run --platform linux/arm64 ${REGISTRY}/${IMAGE_NAME}:${VERSION}" + else + echo "" + print_info "To push to registry later:" + echo " $0 --registry YOUR_REGISTRY --push" + fi +} + +# Check if script is executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi