feat(docker-stack): add archmirror stack

This commit is contained in:
2025-08-31 22:14:19 +03:00
parent f07dc26c36
commit a2cc16ceae
7 changed files with 149 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
services:
rsync-mirror:
build:
context: ./rsync
dockerfile: Dockerfile
environment:
- MIRROR_URL=${MIRROR_URL}
- SYNC_SCHEDULE=${SYNC_SCHEDULE}
- TZ=${TZ}
- RSYNC_EXTRA_OPTIONS=${RSYNC_EXTRA_OPTIONS}
volumes:
- ${ARCHLINUX_VOLUME_PATH:-./archlinux}:/archlinux
restart: unless-stopped
healthcheck:
test: ["CMD", "ps", "aux", "|", "grep", "[s]upercronic"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
nginx-server:
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- "${HTTP_PORT:-8080}:80"
volumes:
- ${ARCHLINUX_VOLUME_PATH:-./archlinux}:/usr/share/nginx/html/archlinux:ro
environment:
- NGINX_WORKERS=${NGINX_WORKERS}
depends_on:
rsync-mirror:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
networks:
default:
name: archlinux-mirror-net

View File

@@ -0,0 +1,3 @@
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf

View File

@@ -0,0 +1,30 @@
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
gzip on;
server {
listen 80;
root /usr/share/nginx/html;
location /archlinux/ {
alias /usr/share/nginx/html/archlinux/;
autoindex on;
}
location = / {
return 301 /archlinux/;
}
location /health {
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
}

View File

@@ -0,0 +1,24 @@
FROM alpine:latest AS builder
RUN apk add --no-cache curl \
&& curl -fsSLO https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-amd64 \
&& echo "cd48d45c4b10f3f0bfdd3a57d054cd05ac96812b supercronic-linux-amd64" | sha1sum -c - \
&& chmod +x supercronic-linux-amd64
FROM alpine:latest
RUN apk add --no-cache rsync flock \
&& rm -rf /var/cache/apk/*
COPY --from=builder /supercronic-linux-amd64 /usr/local/bin/supercronic
RUN mkdir -p /archlinux /var/log /var/lock
COPY sync.sh /usr/local/bin/sync.sh
COPY crontab /etc/crontab
RUN chmod +x /usr/local/bin/sync.sh
WORKDIR /archlinux
CMD ["supercronic", "/etc/crontab"]

View File

@@ -0,0 +1,2 @@
0 */6 * * * /usr/bin/flock -n /var/lock/archlinux-sync.lock /usr/local/bin/sync.sh
* * * * * [ ! -f /var/lock/initial-sync-done ] && /usr/bin/flock -n /var/lock/archlinux-sync.lock /usr/local/bin/sync.sh && touch /var/lock/initial-sync-done

View File

@@ -0,0 +1,32 @@
#!/bin/sh
set -e
TARGET_DIR="/archlinux"
MAX_RETRIES=3
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >&2
}
if [ -z "$MIRROR_URL" ]; then
log "ERROR: MIRROR_URL not set"
exit 1
fi
mkdir -p "$TARGET_DIR"
for i in $(seq 1 $MAX_RETRIES); do
log "Sync attempt $i/$MAX_RETRIES from $MIRROR_URL"
if rsync --timeout=7200 \
-rlptH --safe-links --delete-delay --delay-updates \
${RSYNC_EXTRA_OPTIONS:-} \
"$MIRROR_URL/" "$TARGET_DIR/"; then
log "Sync completed successfully"
exit 0
fi
[ $i -lt $MAX_RETRIES ] && sleep $((i * 300))
done
log "All sync attempts failed"
exit 1

View File

@@ -0,0 +1,14 @@
# Mirror Configuration
MIRROR_URL=
SYNC_SCHEDULE=0 */6 * * *
RSYNC_EXTRA_OPTIONS=--info=progress2
# HTTP Configuration
HTTP_PORT=8080
NGINX_WORKERS=auto
# Path Configuration
ARCHLINUX_VOLUME_PATH=
# Basic Configuration
TZ=UTC