From 99109c2b9640f55e87db6d895f98468454f02a65 Mon Sep 17 00:00:00 2001 From: Juraldinio Date: Tue, 5 May 2026 21:03:00 +0300 Subject: [PATCH] k8s and slim docker image version --- admin-web/.dockerignore | 5 +++ backend/.dockerignore | 4 +++ docker/admin/Dockerfile | 21 +++++++++++++ docker/admin/nginx-default.conf | 11 +++++++ docker/backend/Dockerfile | 34 ++++++++++++++++++++ scripts/build-k8s-images.sh | 55 +++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+) create mode 100644 admin-web/.dockerignore create mode 100644 backend/.dockerignore create mode 100644 docker/admin/Dockerfile create mode 100644 docker/admin/nginx-default.conf create mode 100644 docker/backend/Dockerfile create mode 100755 scripts/build-k8s-images.sh diff --git a/admin-web/.dockerignore b/admin-web/.dockerignore new file mode 100644 index 0000000..6c3ed97 --- /dev/null +++ b/admin-web/.dockerignore @@ -0,0 +1,5 @@ +node_modules +dist +.git +*.md +.DS_Store diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..3ced957 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,4 @@ +.build +.git +*.md +.DS_Store diff --git a/docker/admin/Dockerfile b/docker/admin/Dockerfile new file mode 100644 index 0000000..80d3581 --- /dev/null +++ b/docker/admin/Dockerfile @@ -0,0 +1,21 @@ +# Multi-stage: Node builds static assets → nginx alpine serves SPA (~minimal footprint). +# Build from repo root: docker build -f docker/admin/Dockerfile . +FROM node:20-bookworm-slim AS builder +WORKDIR /app + +COPY admin-web/package.json admin-web/package-lock.json ./ +RUN npm ci + +COPY admin-web/ ./ + +ARG VITE_ADMIN_API_BASE_URL=http://localhost:8080 +ENV VITE_ADMIN_API_BASE_URL=${VITE_ADMIN_API_BASE_URL} + +RUN npm run build + +FROM nginx:1.27-alpine-slim + +COPY docker/admin/nginx-default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/dist /usr/share/nginx/html + +EXPOSE 80 diff --git a/docker/admin/nginx-default.conf b/docker/admin/nginx-default.conf new file mode 100644 index 0000000..de828c4 --- /dev/null +++ b/docker/admin/nginx-default.conf @@ -0,0 +1,11 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + gzip on; + gzip_types text/css application/javascript application/json image/svg+xml; + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/docker/backend/Dockerfile b/docker/backend/Dockerfile new file mode 100644 index 0000000..72b3c23 --- /dev/null +++ b/docker/backend/Dockerfile @@ -0,0 +1,34 @@ +# Multi-stage: full Swift toolchain → slim Ubuntu 22.04 runtime (Swift shared libs copied from builder). +FROM swift:5.10-jammy AS builder +WORKDIR /build + +COPY Package.swift Package.resolved ./ +RUN swift package resolve + +COPY Sources ./Sources +RUN swift build -c release --product Run \ + && cp "$(swift build -c release --show-bin-path)/Run" /tmp/Run + +# Same glibc family as swift:5.10-jammy (Ubuntu 22.04); official images use 22.04 not "jammy-slim". +FROM ubuntu:22.04 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + libgcc-s1 \ + libstdc++6 \ + zlib1g \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /tmp/Run ./Run +COPY --from=builder /usr/lib/swift/linux /usr/lib/swift/linux + +ENV LD_LIBRARY_PATH=/usr/lib/swift/linux + +RUN useradd --system --uid 10001 --shell /usr/sbin/nologin radiostore +USER radiostore + +EXPOSE 8080 +ENTRYPOINT ["./Run"] diff --git a/scripts/build-k8s-images.sh b/scripts/build-k8s-images.sh new file mode 100755 index 0000000..cb76f54 --- /dev/null +++ b/scripts/build-k8s-images.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Build slim container images for Kubernetes (multi-stage Dockerfiles under docker/). +# +# Backend: compile Swift/Vapor in swift:5.10-jammy; runtime ubuntu:22.04 + Swift libs (~small vs toolchain image). +# Admin: build Vite in node:20-bookworm-slim; runtime nginx:alpine-slim with SPA fallback. +# +# Usage: +# ./scripts/build-k8s-images.sh # load into local docker, tag ...:local +# REGISTRY=ghcr.io/myorg TAG=v1.0.0 ./scripts/build-k8s-images.sh +# PUSH=1 REGISTRY=ghcr.io/myorg TAG=v1 ./scripts/build-k8s-images.sh # buildx --push +# Multi-arch (requires push; cannot --load multi-platform): +# PUSH=1 PLATFORM=linux/amd64,linux/arm64 REGISTRY=... TAG=v1 ./scripts/build-k8s-images.sh +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +REGISTRY="${REGISTRY:-}" +TAG="${TAG:-local}" +PUSH="${PUSH:-0}" +VITE_ADMIN_API_BASE_URL="${VITE_ADMIN_API_BASE_URL:-http://radiostore-backend:8080}" + +_arch="$(uname -m)" +case "$_arch" in + arm64|aarch64) DEFAULT_PLATFORM="linux/arm64" ;; + *) DEFAULT_PLATFORM="linux/amd64" ;; +esac +PLATFORM="${PLATFORM:-$DEFAULT_PLATFORM}" + +backend_image="${REGISTRY:+${REGISTRY}/}radiostore-backend:${TAG}" +admin_image="${REGISTRY:+${REGISTRY}/}radiostore-admin:${TAG}" + +build_args=(docker buildx build --platform "$PLATFORM") + +if [[ "$PUSH" == "1" || "$PUSH" == "true" ]]; then + build_args+=(--push) +else + build_args+=(--load) +fi + +echo "Building backend -> ${backend_image} (platform=${PLATFORM})" +"${build_args[@]}" \ + -f docker/backend/Dockerfile \ + -t "$backend_image" \ + backend + +echo "Building admin -> ${admin_image} (platform=${PLATFORM})" +"${build_args[@]}" \ + -f docker/admin/Dockerfile \ + --build-arg "VITE_ADMIN_API_BASE_URL=${VITE_ADMIN_API_BASE_URL}" \ + -t "$admin_image" \ + . + +echo "Done."