345ae0a4b5
CI/CD / CI · Admin API (dotnet build) (push) Successful in 41s
CI/CD / CI · Admin Web (tsc) (push) Failing after 5s
CI/CD / CI · Website (tsc) (push) Failing after 4s
CI/CD / CI · Koja (tsc) (push) Failing after 5s
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m13s
CI/CD / CI · Dashboard (tsc) (push) Failing after 2m32s
CI/CD / Deploy · all services (push) Has been skipped
201 lines
8.6 KiB
Bash
201 lines
8.6 KiB
Bash
#!/usr/bin/env bash
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# Nexus first-time provisioning
|
||
# Run once on the server after: docker compose -f docker-compose.mirror.yml up -d
|
||
#
|
||
# Docker upstream:
|
||
# By default → registry-1.docker.io (Docker Hub directly — works from VPS)
|
||
# With Liara → docker-mirror.liara.ir (Iranian relay, faster + more reliable)
|
||
#
|
||
# To use Liara mirror, get credentials from https://app.liara.ir
|
||
# (Account → Docker Mirror section), then run:
|
||
# DOCKER_MIRROR_URL=https://docker-mirror.liara.ir \
|
||
# DOCKER_MIRROR_USER=your-liara-email \
|
||
# DOCKER_MIRROR_PASS=your-liara-token \
|
||
# ./mirrors/nexus/provision.sh
|
||
#
|
||
# Usage:
|
||
# ./mirrors/nexus/provision.sh # Docker Hub direct
|
||
# NEXUS_ADMIN_PASS=MySecret ./mirrors/nexus/provision.sh
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
set -euo pipefail
|
||
|
||
NEXUS_URL="http://localhost:8081"
|
||
NEW_PASS="${NEXUS_ADMIN_PASS:-Mirror@2024!}"
|
||
CONTAINER="meezi-mirror-nexus"
|
||
|
||
# Docker upstream — override with Liara mirror once you have credentials
|
||
DOCKER_UPSTREAM="${DOCKER_MIRROR_URL:-https://registry-1.docker.io}"
|
||
DOCKER_USER="${DOCKER_MIRROR_USER:-}"
|
||
DOCKER_PASS="${DOCKER_MIRROR_PASS:-}"
|
||
|
||
# ── 1. Wait for Nexus ────────────────────────────────────────────────────────
|
||
echo "⏳ Waiting for Nexus (can take 2-3 min on first boot)..."
|
||
until curl -sf "$NEXUS_URL/service/rest/v1/status" | grep -q '"edition"'; do
|
||
printf "."
|
||
sleep 6
|
||
done
|
||
echo ""
|
||
echo "✅ Nexus is up"
|
||
|
||
# ── 2. Resolve admin password ────────────────────────────────────────────────
|
||
INIT_PASS_FILE=$(docker exec "$CONTAINER" sh -c 'cat /nexus-data/admin.password 2>/dev/null || true')
|
||
|
||
if [ -n "$INIT_PASS_FILE" ]; then
|
||
echo "🔐 First-time password found — changing to configured password..."
|
||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||
-u "admin:$INIT_PASS_FILE" -X PUT \
|
||
"$NEXUS_URL/service/rest/v1/security/users/admin/change-password" \
|
||
-H "Content-Type: text/plain" \
|
||
-d "$NEW_PASS")
|
||
if [ "$HTTP_CODE" = "204" ]; then
|
||
echo "✅ Password updated"
|
||
else
|
||
echo "⚠️ Password change returned HTTP $HTTP_CODE — using original password"
|
||
NEW_PASS="$INIT_PASS_FILE"
|
||
fi
|
||
ADMIN_PASS="$NEW_PASS"
|
||
else
|
||
echo "ℹ️ admin.password not found — using NEXUS_ADMIN_PASS (already provisioned?)"
|
||
ADMIN_PASS="$NEW_PASS"
|
||
fi
|
||
|
||
AUTH="-u admin:$ADMIN_PASS"
|
||
|
||
# ── 3. Enable anonymous read access ─────────────────────────────────────────
|
||
echo "🔓 Enabling anonymous access..."
|
||
curl -sf $AUTH -X PUT "$NEXUS_URL/service/rest/v1/security/anonymous" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"enabled":true,"userId":"anonymous","realmName":"NexusAuthorizingRealm"}' \
|
||
&& echo "✅ Anonymous access enabled"
|
||
|
||
# Enable NuGet + npm token realms
|
||
curl -sf $AUTH -X PUT "$NEXUS_URL/service/rest/v1/security/realms/active" \
|
||
-H "Content-Type: application/json" \
|
||
-d '["NexusAuthenticatingRealm","NexusAuthorizingRealm","NuGetApiKey","NpmToken"]' \
|
||
&& echo "✅ Realms configured (NuGet, npm)"
|
||
|
||
# ── Helper: create or update repo ───────────────────────────────────────────
|
||
create_repo() {
|
||
local TYPE="$1"
|
||
local JSON="$2"
|
||
local NAME
|
||
NAME=$(echo "$JSON" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
|
||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" $AUTH \
|
||
-X POST "$NEXUS_URL/service/rest/v1/repositories/$TYPE" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$JSON")
|
||
case "$HTTP" in
|
||
201) echo "✅ $NAME created" ;;
|
||
400) echo "⚠️ $NAME already exists (skipped — update via UI if needed)" ;;
|
||
*) echo "❌ $NAME failed — HTTP $HTTP" ;;
|
||
esac
|
||
}
|
||
|
||
# ── 4. NuGet proxy ──────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "📦 Creating NuGet proxy → nuget.org ..."
|
||
create_repo "nuget/proxy" '{
|
||
"name": "nuget-proxy",
|
||
"online": true,
|
||
"storage": {
|
||
"blobStoreName": "default",
|
||
"strictContentTypeValidation": true
|
||
},
|
||
"proxy": {
|
||
"remoteUrl": "https://api.nuget.org/v3/index.json",
|
||
"contentMaxAge": 1440,
|
||
"metadataMaxAge": 1440
|
||
},
|
||
"negativeCache": { "enabled": true, "timeToLive": 1440 },
|
||
"httpClient": { "blocked": false, "autoBlock": true }
|
||
}'
|
||
|
||
# ── 5. npm proxy ─────────────────────────────────────────────────────────────
|
||
echo "📦 Creating npm proxy → registry.npmjs.org ..."
|
||
create_repo "npm/proxy" '{
|
||
"name": "npm-proxy",
|
||
"online": true,
|
||
"storage": {
|
||
"blobStoreName": "default",
|
||
"strictContentTypeValidation": false
|
||
},
|
||
"proxy": {
|
||
"remoteUrl": "https://registry.npmjs.org",
|
||
"contentMaxAge": 1440,
|
||
"metadataMaxAge": 1440
|
||
},
|
||
"negativeCache": { "enabled": true, "timeToLive": 1440 },
|
||
"httpClient": { "blocked": false, "autoBlock": true }
|
||
}'
|
||
|
||
# ── 6. Docker proxy ──────────────────────────────────────────────────────────
|
||
if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASS" ]; then
|
||
echo "🐳 Creating Docker proxy → $DOCKER_UPSTREAM (with auth) ..."
|
||
DOCKER_AUTH_JSON='"authentication":{"type":"username","username":"'"$DOCKER_USER"'","password":"'"$DOCKER_PASS"'"},'
|
||
DOCKER_INDEX_TYPE="REGISTRY" # Liara is a plain registry, not hub.docker.com
|
||
else
|
||
echo "🐳 Creating Docker proxy → $DOCKER_UPSTREAM (no auth) ..."
|
||
DOCKER_AUTH_JSON=""
|
||
DOCKER_INDEX_TYPE="HUB" # direct Docker Hub — use hub index
|
||
fi
|
||
|
||
create_repo "docker/proxy" '{
|
||
"name": "docker-hub-proxy",
|
||
"online": true,
|
||
"storage": {
|
||
"blobStoreName": "default",
|
||
"strictContentTypeValidation": true
|
||
},
|
||
"proxy": {
|
||
"remoteUrl": "'"$DOCKER_UPSTREAM"'",
|
||
"contentMaxAge": 1440,
|
||
"metadataMaxAge": 1440
|
||
},
|
||
"negativeCache": { "enabled": true, "timeToLive": 1440 },
|
||
"httpClient": {
|
||
"blocked": false,
|
||
"autoBlock": true,
|
||
'"$DOCKER_AUTH_JSON"'
|
||
"connection": { "useTrustStore": false }
|
||
},
|
||
"docker": {
|
||
"v1Enabled": false,
|
||
"forceBasicAuth": false,
|
||
"httpPort": 8083
|
||
},
|
||
"dockerProxy": {
|
||
"indexType": "'"$DOCKER_INDEX_TYPE"'",
|
||
"cacheForeignLayers": false
|
||
}
|
||
}'
|
||
|
||
# ── Done ─────────────────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "═══════════════════════════════════════════════════════════════"
|
||
echo "🎉 Nexus provisioned!"
|
||
echo "═══════════════════════════════════════════════════════════════"
|
||
echo ""
|
||
echo " UI → https://mirror.soroushasadi.com/"
|
||
echo " admin / $ADMIN_PASS"
|
||
echo ""
|
||
echo " NuGet → https://mirror.soroushasadi.com/repository/nuget-group/index.json"
|
||
echo " npm → https://mirror.soroushasadi.com/repository/npm-group/"
|
||
echo " Docker → https://mirror.soroushasadi.com ← upstream: $DOCKER_UPSTREAM"
|
||
echo ""
|
||
if [ -z "$DOCKER_USER" ]; then
|
||
echo " 💡 To switch Docker upstream to Liara mirror (faster in Iran):"
|
||
echo " Get credentials from https://app.liara.ir → Docker Mirror, then:"
|
||
echo ""
|
||
echo " DOCKER_MIRROR_URL=https://docker-mirror.liara.ir \\"
|
||
echo " DOCKER_MIRROR_USER=your-email \\"
|
||
echo " DOCKER_MIRROR_PASS=your-token \\"
|
||
echo " ./mirrors/nexus/update-docker-upstream.sh"
|
||
echo ""
|
||
fi
|
||
echo "To activate Docker Hub mirror on this server:"
|
||
echo " Merge docker/daemon-registry-mirror.example.json into /etc/docker/daemon.json"
|
||
echo ' { "registry-mirrors": ["https://mirror.soroushasadi.com"] }'
|
||
echo " systemctl restart docker"
|
||
echo ""
|