diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index d799006..3a45a12 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: runs-on: [self-hosted, linux] services: postgres: - image: postgres:16-alpine + image: 127.0.0.1:5001/mirror/postgres:16-alpine env: POSTGRES_DB: food_market_test POSTGRES_USER: postgres diff --git a/deploy/Dockerfile.api b/deploy/Dockerfile.api index 5748de7..eed668f 100644 --- a/deploy/Dockerfile.api +++ b/deploy/Dockerfile.api @@ -1,4 +1,5 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG LOCAL_REGISTRY=127.0.0.1:5001 +FROM ${LOCAL_REGISTRY}/mirror/dotnet-sdk:8.0 AS build WORKDIR /src COPY food-market.sln global.json Directory.Build.props Directory.Packages.props ./ @@ -15,7 +16,7 @@ RUN dotnet restore src/food-market.api/food-market.api.csproj COPY src/ src/ RUN dotnet publish src/food-market.api/food-market.api.csproj -c Release -o /app --no-restore -FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime +FROM ${LOCAL_REGISTRY}/mirror/dotnet-aspnet:8.0 AS runtime WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends curl \ diff --git a/deploy/Dockerfile.web b/deploy/Dockerfile.web index 3328024..c2768bb 100644 --- a/deploy/Dockerfile.web +++ b/deploy/Dockerfile.web @@ -1,4 +1,5 @@ -FROM node:20-alpine AS build +ARG LOCAL_REGISTRY=127.0.0.1:5001 +FROM ${LOCAL_REGISTRY}/mirror/node:20-alpine AS build WORKDIR /src RUN corepack enable @@ -9,7 +10,7 @@ RUN pnpm install --frozen-lockfile COPY src/food-market.web/ ./ RUN pnpm build -FROM nginx:1.27-alpine AS runtime +FROM ${LOCAL_REGISTRY}/mirror/nginx:1.27-alpine AS runtime COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf COPY --from=build /src/dist /usr/share/nginx/html diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index b5c7ec3..1657808 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -1,6 +1,6 @@ services: postgres: - image: postgres:16-alpine + image: ${REGISTRY:-127.0.0.1:5001}/mirror/postgres:16-alpine container_name: food-market-postgres restart: unless-stopped environment: diff --git a/deploy/food-market-mirror-base-images.service b/deploy/food-market-mirror-base-images.service new file mode 100644 index 0000000..257cfa9 --- /dev/null +++ b/deploy/food-market-mirror-base-images.service @@ -0,0 +1,11 @@ +[Unit] +Description=Mirror docker base images into local 127.0.0.1:5001 registry +Requires=food-market-registry.service +After=food-market-registry.service docker.service + +[Service] +Type=oneshot +User=nns +ExecStart=/usr/local/bin/food-market-mirror-base-images.sh +StandardOutput=append:/var/log/food-market-mirror-base-images.log +StandardError=append:/var/log/food-market-mirror-base-images.log diff --git a/deploy/food-market-mirror-base-images.timer b/deploy/food-market-mirror-base-images.timer new file mode 100644 index 0000000..296ae8d --- /dev/null +++ b/deploy/food-market-mirror-base-images.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Refresh docker base image mirrors daily + +[Timer] +OnBootSec=10min +OnUnitActiveSec=24h +Unit=food-market-mirror-base-images.service +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/deploy/mirror-base-images.sh b/deploy/mirror-base-images.sh new file mode 100755 index 0000000..30c60ee --- /dev/null +++ b/deploy/mirror-base-images.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Pulls all external base images the food-market builds depend on, then retags +# them into the local registry at 127.0.0.1:5001 under the "mirror/" prefix. +# +# Why: outbound to docker.io / mcr.microsoft.com flaps on KZ network. Once +# mirrored, Dockerfiles and docker-compose reference the local copy and builds +# no longer need the internet at all. +# +# Idempotent — safe to run as often as you want. Scheduled daily via +# food-market-mirror-base-images.timer. +set -euo pipefail + +REGISTRY=127.0.0.1:5001 +LOG_PREFIX=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +# image_ref → local name under mirror/ +IMAGES=( + "node:20-alpine|mirror/node:20-alpine" + "nginx:1.27-alpine|mirror/nginx:1.27-alpine" + "postgres:16-alpine|mirror/postgres:16-alpine" + "mcr.microsoft.com/dotnet/sdk:8.0|mirror/dotnet-sdk:8.0" + "mcr.microsoft.com/dotnet/aspnet:8.0|mirror/dotnet-aspnet:8.0" +) + +failures=0 +for pair in "${IMAGES[@]}"; do + src="${pair%|*}" + dst="${pair#*|}" + echo "$LOG_PREFIX pulling $src" + if ! docker pull "$src"; then + echo "$LOG_PREFIX FAILED: pull $src" + failures=$((failures + 1)) + continue + fi + docker tag "$src" "$REGISTRY/$dst" + if ! docker push "$REGISTRY/$dst"; then + echo "$LOG_PREFIX FAILED: push $REGISTRY/$dst" + failures=$((failures + 1)) + continue + fi + echo "$LOG_PREFIX ok $src -> $REGISTRY/$dst" +done + +if [[ $failures -gt 0 ]]; then + echo "$LOG_PREFIX done, $failures failed — registry still has old mirrored copies" + exit 1 +fi +echo "$LOG_PREFIX done, all mirrors fresh"