DockerProxy_Install.sh 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933
  1. #!/usr/bin/env bash
  2. #===============================================================================
  3. #
  4. # FILE: DockerProxy_Install.sh
  5. #
  6. # USAGE: ./DockerProxy_Install.sh
  7. #
  8. # DESCRIPTION: 自建Docker镜像加速服务,基于官方 registry 一键部署Docker、K8s、Quay、Ghcr镜像加速\管理服务.支持部署到Render.
  9. #
  10. # ORGANIZATION: DingQz dqzboy.com 浅时光博客
  11. #===============================================================================
  12. echo
  13. cat << EOF
  14. ██████╗ ██████╗ ██████╗██╗ ██╗███████╗██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗██╗ ██╗
  15. ██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗ ██╔══██╗██╔══██╗██╔═══██╗╚██╗██╔╝╚██╗ ██╔╝
  16. ██║ ██║██║ ██║██║ █████╔╝ █████╗ ██████╔╝ ██████╔╝██████╔╝██║ ██║ ╚███╔╝ ╚████╔╝
  17. ██║ ██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗ ██╔═══╝ ██╔══██╗██║ ██║ ██╔██╗ ╚██╔╝
  18. ██████╔╝╚██████╔╝╚██████╗██║ ██╗███████╗██║ ██║ ██║ ██║ ██║╚██████╔╝██╔╝ ██╗ ██║
  19. ╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
  20. 博客: dqzboy.com 浅时光博客
  21. 项目地址: https://github.com/dqzboy/Docker-Proxy
  22. EOF
  23. echo "----------------------------------------------------------------------------------------------------------"
  24. echo -e "\033[32m机场推荐\033[0m(\033[34m按量不限时,解锁ChatGPT\033[0m):\033[34;4mhttps://mojie.mx/#/register?code=CG6h8Irm\033[0m"
  25. echo "----------------------------------------------------------------------------------------------------------"
  26. echo
  27. echo
  28. GREEN="\033[0;32m"
  29. RED="\033[31m"
  30. YELLOW="\033[33m"
  31. RESET="\033[0m"
  32. BLUE="\033[0;34m"
  33. MAGENTA="\033[0;35m"
  34. CYAN="\033[0;36m"
  35. WHITE="\033[1;37m"
  36. BLACK="\033[0;30m"
  37. PINK="\033[0;95m"
  38. LIGHT_GREEN="\033[1;32m"
  39. LIGHT_RED="\033[1;31m"
  40. LIGHT_YELLOW="\033[1;33m"
  41. LIGHT_BLUE="\033[1;34m"
  42. LIGHT_MAGENTA="\033[1;35m"
  43. LIGHT_CYAN="\033[1;36m"
  44. LIGHT_PINK="\033[1;95m"
  45. BRIGHT_CYAN="\033[96m"
  46. BOLD="\033[1m"
  47. UNDERLINE="\033[4m"
  48. BLINK="\033[5m"
  49. REVERSE="\033[7m"
  50. INFO="[${GREEN}INFO${RESET}]"
  51. ERROR="[${RED}ERROR${RESET}]"
  52. WARN="[${YELLOW}WARN${RESET}]"
  53. function INFO() {
  54. echo -e "${INFO} ${1}"
  55. }
  56. function ERROR() {
  57. echo -e "${ERROR} ${1}"
  58. }
  59. function WARN() {
  60. echo -e "${WARN} ${1}"
  61. }
  62. function PROMPT_Y_N() {
  63. echo -e "[${LIGHT_GREEN}y${RESET}/${LIGHT_BLUE}n${RESET}]: "
  64. }
  65. PROMPT_YES_NO=$(PROMPT_Y_N)
  66. function SEPARATOR() {
  67. echo -e "${INFO}${BOLD}${LIGHT_BLUE}======================== ${1} ========================${RESET}"
  68. }
  69. PROXY_DIR="/data/registry-proxy"
  70. mkdir -p ${PROXY_DIR}
  71. cd "${PROXY_DIR}"
  72. GITRAW="https://raw.githubusercontent.com/dqzboy/Docker-Proxy/main"
  73. CNGITRAW="https://gitee.com/boydqz/Docker-Proxy/raw/main"
  74. # docker registry
  75. IMAGE_NAME="dqzboy/registry"
  76. UI_IMAGE_NAME="dqzboy/docker-registry-ui"
  77. DOCKER_COMPOSE_FILE="docker-compose.yaml"
  78. # HubCMD-UI
  79. CMDUI_IMAGE_NAME="dqzboy/hubcmd-ui"
  80. CMDUI_COMPOSE_FILE="${GITRAW}/hubcmdui/${DOCKER_COMPOSE_FILE}"
  81. attempts=0
  82. maxAttempts=3
  83. function CHECK_OS() {
  84. SEPARATOR "检查环境"
  85. OSVER=$(cat /etc/os-release | grep -o '[0-9]' | head -n 1)
  86. if [ -f /etc/os-release ]; then
  87. . /etc/os-release
  88. else
  89. echo "无法确定发行版"
  90. exit 1
  91. fi
  92. case "$ID" in
  93. "centos")
  94. repo_type="centos"
  95. ;;
  96. "debian")
  97. repo_type="debian"
  98. ;;
  99. "rhel")
  100. repo_type="rhel"
  101. ;;
  102. "ubuntu")
  103. repo_type="ubuntu"
  104. ;;
  105. "opencloudos")
  106. repo_type="centos"
  107. ;;
  108. "rocky")
  109. repo_type="centos"
  110. ;;
  111. *)
  112. WARN "此脚本目前不支持您的系统: $ID"
  113. exit 1
  114. ;;
  115. esac
  116. INFO "System release:: $NAME"
  117. INFO "System version: $VERSION"
  118. INFO "System ID: $ID"
  119. INFO "System ID Like: $ID_LIKE"
  120. }
  121. function CHECK_PACKAGE_MANAGER() {
  122. if command -v dnf &> /dev/null; then
  123. package_manager="dnf"
  124. elif command -v yum &> /dev/null; then
  125. package_manager="yum"
  126. elif command -v apt-get &> /dev/null; then
  127. package_manager="apt-get"
  128. elif command -v apt &> /dev/null; then
  129. package_manager="apt"
  130. else
  131. ERROR "不受支持的软件包管理器."
  132. exit 1
  133. fi
  134. }
  135. function CHECK_PKG_MANAGER() {
  136. if command -v rpm &> /dev/null; then
  137. pkg_manager="rpm"
  138. elif command -v dpkg &> /dev/null; then
  139. pkg_manager="dpkg"
  140. elif command -v apt &> /dev/null; then
  141. pkg_manager="apt"
  142. else
  143. ERROR "无法确定包管理系统."
  144. exit 1
  145. fi
  146. }
  147. function CHECKMEM() {
  148. memory_usage=$(free | awk '/^Mem:/ {printf "%.2f", $3/$2 * 100}')
  149. memory_usage=${memory_usage%.*}
  150. if [[ $memory_usage -gt 90 ]]; then
  151. read -e -p "$(WARN "内存占用率${LIGHT_RED}高于 70%($memory_usage%)${RESET} 是否继续安装? ${PROMPT_YES_NO}")" continu
  152. if [ "$continu" == "n" ] || [ "$continu" == "N" ]; then
  153. exit 1
  154. fi
  155. else
  156. INFO "内存资源充足.请继续 ${LIGHT_GREEN}($memory_usage%)${RESET}"
  157. fi
  158. }
  159. function CHECKFIRE() {
  160. systemctl stop firewalld &> /dev/null
  161. systemctl disable firewalld &> /dev/null
  162. systemctl stop iptables &> /dev/null
  163. systemctl disable iptables &> /dev/null
  164. ufw disable &> /dev/null
  165. INFO "防火墙已被禁用."
  166. if [[ "$repo_type" == "centos" || "$repo_type" == "rhel" ]]; then
  167. if sestatus | grep "SELinux status" | grep -q "enabled"; then
  168. WARN "SELinux 已启用。禁用 SELinux..."
  169. setenforce 0
  170. sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
  171. INFO "SELinux 已被禁用."
  172. else
  173. INFO "SELinux 已被禁用."
  174. fi
  175. fi
  176. }
  177. function CHECKBBR() {
  178. kernel_version=$(uname -r | awk -F "-" '{print $1}')
  179. read -e -p "$(WARN "是否开启${BRIGHT_CYAN}BBR${RESET},优化网络带宽提高网络性能? ${PROMPT_YES_NO}")" choice_bbr
  180. case $choice_bbr in
  181. y | Y)
  182. version_compare=$(echo "${kernel_version} 4.9" | awk '{if ($1 >= $2) print "yes"; else print "no"}')
  183. if [ "$version_compare" != "yes" ]; then
  184. WARN "你的内核版本小于4.9,无法启动BBR,需要你手动升级内核"
  185. exit 0
  186. fi
  187. sysctl net.ipv4.tcp_available_congestion_control | grep -q "bbr"
  188. if [ $? -eq 0 ]; then
  189. INFO "你的服务器已经启动 ${BRIGHT_CYAN}BBR${RESET}"
  190. else
  191. INFO "开启BBR中..."
  192. modprobe tcp_bbr
  193. if [ $? -eq 0 ]; then
  194. INFO "${BRIGHT_CYAN}BBR${RESET} 模块${LIGHT_GREEN}添加成功${RESET}"
  195. else
  196. ERROR "${BRIGHT_CYAN}BBR${RESET} 模块${LIGHT_RED}添加失败${RESET},请执行 ${LIGHT_CYAN}sysctl -p${RESET} 检查."
  197. exit 1
  198. fi
  199. if [ ! -d /etc/modules-load.d/ ]; then
  200. mkdir -p /etc/modules-load.d/
  201. fi
  202. if [ ! -f /etc/modules-load.d/tcp_bbr.conf ]; then
  203. touch /etc/modules-load.d/tcp_bbr.conf
  204. fi
  205. if ! grep -q "tcp_bbr" /etc/modules-load.d/tcp_bbr.conf ; then
  206. echo 'tcp_bbr' >> /etc/modules-load.d/tcp_bbr.conf
  207. fi
  208. for setting in "net.core.default_qdisc=fq" "net.ipv4.tcp_congestion_control=bbr"; do
  209. if ! grep -q "$setting" /etc/sysctl.conf; then
  210. echo "$setting" >> /etc/sysctl.conf
  211. fi
  212. done
  213. sysctl -p &> /dev/null
  214. if [ $? -ne 0 ]; then
  215. ERROR "应用sysctl设置过程中发生了一个错误,请执行 ${LIGHT_CYAN}sysctl -p${RESET} 检查."
  216. exit 2
  217. fi
  218. lsmod | grep tcp_bbr &> /dev/null
  219. if [ $? -eq 0 ]; then
  220. INFO "${BRIGHT_CYAN}BBR${RESET} 已经${LIGHT_GREEN}成功开启${RESET}"
  221. else
  222. ERROR "${BRIGHT_CYAN}BBR${RESET} 开启${LIGHT_RED}失败${RESET},请执行 ${LIGHT_CYAN}sysctl -p${RESET} 检查."
  223. exit 3
  224. fi
  225. WARN "如果 ${BRIGHT_CYAN}BBR${RESET} 开启后${LIGHT_YELLOW}未生效${RESET},请执行 ${LIGHT_BLUE}reboot${RESET} 重启服务器使其BBR模块生效"
  226. fi
  227. ;;
  228. n | N)
  229. INFO "不开启BBR"
  230. ;;
  231. *)
  232. WARN "输入了无效的选择。请重新输入${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}"
  233. CHECKBBR
  234. ;;
  235. esac
  236. }
  237. function INSTALL_PACKAGE(){
  238. SEPARATOR "安装依赖"
  239. INFO "检查依赖安装情况,请稍等 ..."
  240. TIMEOUT=300
  241. PACKAGES_APT=(
  242. lsof jq wget apache2-utils tar
  243. )
  244. PACKAGES_YUM=(
  245. epel-release lsof jq wget yum-utils httpd-tools tar
  246. )
  247. if [ "$package_manager" = "dnf" ] || [ "$package_manager" = "yum" ]; then
  248. for package in "${PACKAGES_YUM[@]}"; do
  249. if $pkg_manager -q "$package" &>/dev/null; then
  250. INFO "${LIGHT_GREEN}已经安装${RESET} $package ..."
  251. else
  252. INFO "${LIGHT_CYAN}正在安装${RESET} $package ..."
  253. start_time=$(date +%s)
  254. $package_manager -y install "$package" --skip-broken > /dev/null 2>&1 &
  255. install_pid=$!
  256. while [[ $(($(date +%s) - $start_time)) -lt $TIMEOUT ]] && kill -0 $install_pid &>/dev/null; do
  257. sleep 1
  258. done
  259. if kill -0 $install_pid &>/dev/null; then
  260. read -e -p "$(WARN "$package 的安装时间超过 ${LIGHT_YELLOW}$TIMEOUT 秒${RESET}。是否继续? ${PROMPT_YES_NO}")" continue_install
  261. if [ "$continue_install" != "y" ]; then
  262. ERROR "$package 的安装超时。退出脚本。"
  263. exit 1
  264. else
  265. continue
  266. fi
  267. fi
  268. wait $install_pid
  269. if [ $? -ne 0 ]; then
  270. ERROR "$package 安装失败。请检查系统安装源,然后再次运行此脚本!请尝试手动执行安装: ${LIGHT_BLUE}$package_manager -y install $package${RESET}"
  271. exit 1
  272. fi
  273. fi
  274. done
  275. elif [ "$package_manager" = "apt-get" ] || [ "$package_manager" = "apt" ];then
  276. dpkg --configure -a &>/dev/null
  277. $package_manager update &>/dev/null
  278. for package in "${PACKAGES_APT[@]}"; do
  279. if $pkg_manager -s "$package" &>/dev/null; then
  280. INFO "已经安装 $package ..."
  281. else
  282. INFO "正在安装 $package ..."
  283. $package_manager install -y $package > /dev/null 2>&1
  284. if [ $? -ne 0 ]; then
  285. ERROR "安装 $package 失败,请检查系统安装源之后再次运行此脚本!请尝试手动执行安装: ${LIGHT_BLUE}$package_manager -y install $package${RESET}"
  286. exit 1
  287. fi
  288. fi
  289. done
  290. else
  291. ERROR "无法确定包管理系统,脚本无法继续执行,请检查!"
  292. exit 1
  293. fi
  294. }
  295. function INSTALL_CADDY() {
  296. SEPARATOR "安装Caddy"
  297. start_caddy() {
  298. systemctl enable caddy.service &>/dev/null
  299. systemctl restart caddy.service
  300. status=$(systemctl is-active caddy)
  301. if [ "$status" = "active" ]; then
  302. INFO "Caddy 服务运行正常,请继续..."
  303. else
  304. ERROR "Caddy 服务未运行,请查看日志报错,定位问题后再次执行脚本!"
  305. ERROR "-----------服务启动失败,请查看错误日志 ↓↓↓-----------"
  306. journalctl -u caddy.service --no-pager
  307. ERROR "-----------服务启动失败,请查看错误日志 ↑↑↑-----------"
  308. exit 1
  309. fi
  310. }
  311. check_caddy() {
  312. if pgrep "caddy" > /dev/null; then
  313. INFO "Caddy 已在运行."
  314. else
  315. WARN "Caddy 未运行。尝试启动 Caddy..."
  316. start_attempts=3
  317. for ((i=1; i<=$start_attempts; i++)); do
  318. start_caddy
  319. if pgrep "caddy" > /dev/null; then
  320. INFO "Caddy 已成功启动."
  321. break
  322. else
  323. if [ $i -eq $start_attempts ]; then
  324. ERROR "Caddy 在尝试 $start_attempts 后无法启动。请检查配置"
  325. exit 1
  326. else
  327. WARN "在 $i 时间内启动 Caddy 失败。重试..."
  328. fi
  329. fi
  330. done
  331. fi
  332. }
  333. if [ "$package_manager" = "dnf" ]; then
  334. if which caddy &>/dev/null; then
  335. INFO "Caddy 已经安装."
  336. else
  337. INFO "正在安装Caddy程序,请稍候..."
  338. $package_manager -y install 'dnf-command(copr)' &>/dev/null
  339. $package_manager -y copr enable @caddy/caddy &>/dev/null
  340. while [ $attempts -lt $maxAttempts ]; do
  341. $package_manager -y install caddy &>/dev/null
  342. if [ $? -ne 0 ]; then
  343. ((attempts++))
  344. WARN "正在尝试安装Caddy >>> (Attempt: $attempts)"
  345. if [ $attempts -eq $maxAttempts ]; then
  346. ERROR "Caddy installation failed. Please try installing manually."
  347. echo "命令: $package_manager -y install 'dnf-command(copr)' && $package_manager -y copr enable @caddy/caddy && $package_manager -y install caddy"
  348. exit 1
  349. fi
  350. else
  351. INFO "已安装 Caddy."
  352. break
  353. fi
  354. done
  355. fi
  356. check_caddy
  357. elif [ "$package_manager" = "yum" ]; then
  358. if which caddy &>/dev/null; then
  359. INFO "Caddy 已经安装."
  360. else
  361. INFO "正在安装Caddy程序,请稍候..."
  362. $package_manager -y install yum-plugin-copr &>/dev/null
  363. $package_manager -y copr enable @caddy/caddy &>/dev/null
  364. while [ $attempts -lt $maxAttempts ]; do
  365. $package_manager -y install caddy &>/dev/null
  366. if [ $? -ne 0 ]; then
  367. ((attempts++))
  368. WARN "正在尝试安装Caddy >>> (Attempt: $attempts)"
  369. if [ $attempts -eq $maxAttempts ]; then
  370. ERROR "Caddy installation failed. Please try installing manually."
  371. echo "命令: $package_manager -y install 'dnf-command(copr)' && $package_manager -y copr enable @caddy/caddy && $package_manager -y install caddy"
  372. exit 1
  373. fi
  374. else
  375. INFO "已安装 Caddy."
  376. break
  377. fi
  378. done
  379. fi
  380. check_caddy
  381. elif [ "$package_manager" = "apt" ] || [ "$package_manager" = "apt-get" ];then
  382. dpkg --configure -a &>/dev/null
  383. $package_manager update &>/dev/null
  384. if $pkg_manager -s "caddy" &>/dev/null; then
  385. INFO "Caddy 已安装,跳过..."
  386. else
  387. INFO "安装 Caddy 请稍等 ..."
  388. $package_manager install -y debian-keyring debian-archive-keyring apt-transport-https &>/dev/null
  389. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg &>/dev/null
  390. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list &>/dev/null
  391. $package_manager update &>/dev/null
  392. $package_manager install -y caddy &>/dev/null
  393. if [ $? -ne 0 ]; then
  394. ERROR "安装 Caddy 失败,请检查系统安装源之后再次运行此脚本!请尝试手动执行安装:$package_manager -y install caddy"
  395. exit 1
  396. fi
  397. fi
  398. check_caddy
  399. else
  400. WARN "无法确定包管理系统."
  401. exit 1
  402. fi
  403. }
  404. function CONFIG_CADDY() {
  405. SEPARATOR "配置Caddy"
  406. while true; do
  407. INFO "${LIGHT_GREEN}>>> 域名解析主机记录(即域名前缀):${RESET} ${LIGHT_CYAN}ui、hub、gcr、ghcr、k8sgcr、k8s、quay、mcr、elastic${RESET}"
  408. WARN "${LIGHT_GREEN}>>> 只需选择你部署的服务进行解析即可${RESET},${LIGHT_YELLOW}无需将上面提示中所有的主机记录进行解析${RESET}"
  409. read -e -p "$(WARN "是否配置Caddy,实现自动HTTPS? 执行前需在DNS服务商对部署服务解析主机记录 ${PROMPT_YES_NO}")" caddy_conf
  410. case "$caddy_conf" in
  411. y|Y )
  412. read -e -p "$(INFO "请输入你的域名${LIGHT_BLUE}[例: baidu.com]${RESET} ${LIGHT_RED}不可为空${RESET}: ")" caddy_domain
  413. read -e -p "$(INFO "请输入要配置的${LIGHT_MAGENTA}主机记录${RESET},用逗号分隔${LIGHT_BLUE}[例: ui,hub]${RESET}: ")" selected_records
  414. # 验证输入的主机记录
  415. local valid_records=("ui" "hub" "gcr" "ghcr" "k8sgcr" "k8s" "quay" "mcr" "elastic")
  416. IFS=',' read -r -a records_array <<< "$selected_records"
  417. local invalid_records=()
  418. for record in "${records_array[@]}"; do
  419. if ! [[ " ${valid_records[@]} " =~ " ${record} " ]]; then
  420. invalid_records+=("$record")
  421. fi
  422. done
  423. if [[ ${#invalid_records[@]} -gt 0 ]]; then
  424. ERROR "无效的主机记录: ${LIGHT_RED}${invalid_records[@]}${RESET}"
  425. INFO "请输入有效的主机记录: ${LIGHT_GREEN}ui、hub、gcr、ghcr、k8sgcr、k8s、quay、mcr、elastic${RESET}"
  426. continue
  427. fi
  428. declare -A record_templates
  429. record_templates[ui]="ui.$caddy_domain {
  430. reverse_proxy localhost:50000 {
  431. header_up Host {host}
  432. header_up Origin {scheme}://{host}
  433. header_up X-Forwarded-For {remote_addr}
  434. header_up X-Forwarded-Proto {scheme}
  435. header_up X-Forwarded-Ssl on
  436. header_up X-Forwarded-Port {server_port}
  437. header_up X-Forwarded-Host {host}
  438. }
  439. }"
  440. record_templates[hub]="hub.$caddy_domain {
  441. reverse_proxy localhost:51000 {
  442. header_up Host {host}
  443. header_up X-Real-IP {remote_addr}
  444. header_up X-Forwarded-For {remote_addr}
  445. header_up X-Nginx-Proxy true
  446. }
  447. }"
  448. record_templates[ghcr]="ghcr.$caddy_domain {
  449. reverse_proxy localhost:52000 {
  450. header_up Host {host}
  451. header_up X-Real-IP {remote_addr}
  452. header_up X-Forwarded-For {remote_addr}
  453. header_up X-Nginx-Proxy true
  454. }
  455. }"
  456. record_templates[gcr]="gcr.$caddy_domain {
  457. reverse_proxy localhost:53000 {
  458. header_up Host {host}
  459. header_up X-Real-IP {remote_addr}
  460. header_up X-Forwarded-For {remote_addr}
  461. header_up X-Nginx-Proxy true
  462. }
  463. }"
  464. record_templates[k8sgcr]="k8sgcr.$caddy_domain {
  465. reverse_proxy localhost:54000 {
  466. header_up Host {host}
  467. header_up X-Real-IP {remote_addr}
  468. header_up X-Forwarded-For {remote_addr}
  469. header_up X-Nginx-Proxy true
  470. }
  471. }"
  472. record_templates[k8s]="k8s.$caddy_domain {
  473. reverse_proxy localhost:55000 {
  474. header_up Host {host}
  475. header_up X-Real-IP {remote_addr}
  476. header_up X-Forwarded-For {remote_addr}
  477. header_up X-Nginx-Proxy true
  478. }
  479. }"
  480. record_templates[quay]="quay.$caddy_domain {
  481. reverse_proxy localhost:56000 {
  482. header_up Host {host}
  483. header_up X-Real-IP {remote_addr}
  484. header_up X-Forwarded-For {remote_addr}
  485. header_up X-Nginx-Proxy true
  486. }
  487. }"
  488. record_templates[mcr]="mcr.$caddy_domain {
  489. reverse_proxy localhost:57000 {
  490. header_up Host {host}
  491. header_up X-Real-IP {remote_addr}
  492. header_up X-Forwarded-For {remote_addr}
  493. header_up X-Nginx-Proxy true
  494. }
  495. }"
  496. record_templates[elastic]="elastic.$caddy_domain {
  497. reverse_proxy localhost:58000 {
  498. header_up Host {host}
  499. header_up X-Real-IP {remote_addr}
  500. header_up X-Forwarded-For {remote_addr}
  501. header_up X-Nginx-Proxy true
  502. }
  503. }"
  504. > /etc/caddy/Caddyfile
  505. for record in "${records_array[@]}"; do
  506. if [[ -n "${record_templates[$record]}" ]]; then
  507. echo "${record_templates[$record]}" >> /etc/caddy/Caddyfile
  508. fi
  509. done
  510. start_attempts=3
  511. for ((i=1; i<=$start_attempts; i++)); do
  512. start_caddy
  513. if pgrep "caddy" > /dev/null; then
  514. INFO "重新载入配置成功. Caddy服务启动完成"
  515. break
  516. else
  517. if [ $i -eq $start_attempts ]; then
  518. ERROR "Caddy 在尝试 $start_attempts 后无法启动。请检查配置"
  519. exit 1
  520. else
  521. WARN "第 $i 次启动 Caddy 失败。重试..."
  522. fi
  523. fi
  524. done
  525. break;;
  526. n|N )
  527. WARN "退出配置 Caddy 操作。"
  528. break;;
  529. * )
  530. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  531. esac
  532. done
  533. }
  534. function INSTALL_NGINX() {
  535. SEPARATOR "安装Nginx"
  536. start_nginx() {
  537. systemctl enable nginx &>/dev/null
  538. systemctl restart nginx
  539. status=$(systemctl is-active nginx)
  540. if [ "$status" = "active" ]; then
  541. INFO "Nginx 服务运行正常,请继续..."
  542. else
  543. ERROR "Nginx 服务未运行,请查看日志报错,定位问题后再次执行脚本!"
  544. ERROR "-----------服务启动失败,请查看错误日志 ↓↓↓-----------"
  545. journalctl -u nginx.service --no-pager
  546. ERROR "-----------服务启动失败,请查看错误日志 ↑↑↑-----------"
  547. exit 1
  548. fi
  549. }
  550. check_nginx() {
  551. if pgrep "nginx" > /dev/null; then
  552. INFO "Nginx 已在运行."
  553. else
  554. WARN "Nginx 未运行。尝试启动 Nginx..."
  555. start_attempts=3
  556. for ((i=1; i<=$start_attempts; i++)); do
  557. start_nginx
  558. if pgrep "nginx" > /dev/null; then
  559. INFO "Nginx 已成功启动."
  560. break
  561. else
  562. if [ $i -eq $start_attempts ]; then
  563. ERROR "Nginx 在尝试 $start_attempts 次后无法启动。请检查配置"
  564. exit 1
  565. else
  566. WARN "第 $i 次启动 Nginx 失败。重试..."
  567. fi
  568. fi
  569. done
  570. fi
  571. }
  572. if [ "$package_manager" = "dnf" ] || [ "$package_manager" = "yum" ]; then
  573. if which nginx &>/dev/null; then
  574. INFO "Nginx 已经安装."
  575. else
  576. INFO "正在安装Nginx程序,请稍候..."
  577. NGINX="nginx-1.24.0-1.el${OSVER}.ngx.x86_64.rpm"
  578. rm -f ${NGINX}
  579. wget http://nginx.org/packages/centos/${OSVER}/x86_64/RPMS/${NGINX} &>/dev/null
  580. while [ $attempts -lt $maxAttempts ]; do
  581. $package_manager -y install ${NGINX} &>/dev/null
  582. if [ $? -ne 0 ]; then
  583. ((attempts++))
  584. WARN "正在尝试安装Nginx >>> (Attempt: $attempts)"
  585. if [ $attempts -eq $maxAttempts ]; then
  586. ERROR "Nginx installation failed. Please try installing manually."
  587. rm -f ${NGINX}
  588. echo "命令: wget http://nginx.org/packages/centos/${OSVER}/x86_64/RPMS/${NGINX} && $package_manager -y install ${NGINX}"
  589. exit 1
  590. fi
  591. else
  592. INFO "已安装 Nginx."
  593. rm -f ${NGINX}
  594. break
  595. fi
  596. done
  597. fi
  598. check_nginx
  599. elif [ "$package_manager" = "apt-get" ] || [ "$package_manager" = "apt" ];then
  600. dpkg --configure -a &>/dev/null
  601. $package_manager update &>/dev/null
  602. if $pkg_manager -s "nginx" &>/dev/null; then
  603. INFO "nginx 已安装,跳过..."
  604. else
  605. INFO "安装 nginx 请稍等 ..."
  606. $package_manager install -y nginx > /dev/null 2>&1
  607. if [ $? -ne 0 ]; then
  608. ERROR "安装 nginx 失败,请检查系统安装源之后再次运行此脚本!请尝试手动执行安装:$package_manager -y install nginx"
  609. exit 1
  610. fi
  611. fi
  612. check_nginx
  613. else
  614. WARN "无法确定包管理系统."
  615. exit 1
  616. fi
  617. }
  618. function CONFIG_NGINX() {
  619. SEPARATOR "配置Nginx"
  620. while true; do
  621. WARN "自行安装的 Nginx ${LIGHT_RED}请勿执行此操作${RESET},${LIGHT_BLUE}以防覆盖原有配置${RESET}"
  622. INFO "${LIGHT_GREEN}>>> 域名解析主机记录(即域名前缀):${RESET} ${LIGHT_CYAN}ui、hub、gcr、ghcr、k8sgcr、k8s、quay、mcr、elastic${RESET}"
  623. WARN "${LIGHT_GREEN}>>> 只需选择你部署的服务进行解析即可${RESET},${LIGHT_YELLOW}无需将上面提示中所有的主机记录进行解析${RESET}"
  624. read -e -p "$(WARN "是否配置 Nginx?配置完成后需在DNS服务商解析主机记录 ${PROMPT_YES_NO}")" nginx_conf
  625. case "$nginx_conf" in
  626. y|Y )
  627. read -e -p "$(INFO "请输入你的域名${LIGHT_BLUE}[例: baidu.com]${RESET} ${LIGHT_RED}不可为空${RESET}: ")" nginx_domain
  628. read -e -p "$(INFO "请输入要配置的${LIGHT_MAGENTA}主机记录${RESET},用逗号分隔${LIGHT_BLUE}[例: ui,hub]${RESET}: ")" selected_records
  629. # 验证输入的主机记录
  630. local valid_records=("ui" "hub" "gcr" "ghcr" "k8sgcr" "k8s" "quay" "mcr" "elastic")
  631. IFS=',' read -r -a records_array <<< "$selected_records"
  632. local invalid_records=()
  633. for record in "${records_array[@]}"; do
  634. if ! [[ " ${valid_records[@]} " =~ " ${record} " ]]; then
  635. invalid_records+=("$record")
  636. fi
  637. done
  638. if [[ ${#invalid_records[@]} -gt 0 ]]; then
  639. ERROR "无效的主机记录: ${LIGHT_RED}${invalid_records[@]}${RESET}"
  640. INFO "请输入有效的主机记录: ${LIGHT_GREEN}ui、hub、gcr、ghcr、k8sgcr、k8s、quay、mcr、elastic${RESET}"
  641. continue
  642. fi
  643. declare -A record_templates
  644. record_templates[ui]="server {
  645. listen 80;
  646. #listen 443 ssl;
  647. server_name ui.$nginx_domain;
  648. #ssl_certificate /path/to/your_domain_name.crt;
  649. #ssl_certificate_key /path/to/your_domain_name.key;
  650. #ssl_session_timeout 1d;
  651. #ssl_session_cache shared:SSL:50m;
  652. #ssl_session_tickets off;
  653. #ssl_protocols TLSv1.2 TLSv1.3;
  654. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  655. #ssl_prefer_server_ciphers on;
  656. #ssl_buffer_size 8k;
  657. proxy_connect_timeout 600;
  658. proxy_send_timeout 600;
  659. proxy_read_timeout 600;
  660. send_timeout 600;
  661. location / {
  662. proxy_pass http://localhost:50000;
  663. proxy_set_header Host \$host;
  664. proxy_set_header Origin \$scheme://\$host;
  665. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  666. proxy_set_header X-Forwarded-Proto \$scheme;
  667. proxy_set_header X-Forwarded-Ssl on;
  668. proxy_set_header X-Forwarded-Port \$server_port;
  669. proxy_set_header X-Forwarded-Host \$host;
  670. }
  671. }"
  672. record_templates[hub]="server {
  673. listen 80;
  674. #listen 443 ssl;
  675. server_name hub.$nginx_domain;
  676. #ssl_certificate /path/to/your_domain_name.crt;
  677. #ssl_certificate_key /path/to/your_domain_name.key;
  678. #ssl_session_timeout 1d;
  679. #ssl_session_cache shared:SSL:50m;
  680. #ssl_session_tickets off;
  681. #ssl_protocols TLSv1.2 TLSv1.3;
  682. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  683. #ssl_prefer_server_ciphers on;
  684. #ssl_buffer_size 8k;
  685. proxy_connect_timeout 600;
  686. proxy_send_timeout 600;
  687. proxy_read_timeout 600;
  688. send_timeout 600;
  689. location / {
  690. proxy_pass http://localhost:51000;
  691. proxy_set_header Host \$host;
  692. proxy_set_header X-Real-IP \$remote_addr;
  693. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  694. proxy_set_header X-Nginx-Proxy true;
  695. proxy_buffering off;
  696. proxy_redirect off;
  697. }
  698. }"
  699. record_templates[ghcr]="server {
  700. listen 80;
  701. #listen 443 ssl;
  702. server_name ghcr.$nginx_domain;
  703. #ssl_certificate /path/to/your_domain_name.crt;
  704. #ssl_certificate_key /path/to/your_domain_name.key;
  705. #ssl_session_timeout 1d;
  706. #ssl_session_cache shared:SSL:50m;
  707. #ssl_session_tickets off;
  708. #ssl_protocols TLSv1.2 TLSv1.3;
  709. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  710. #ssl_prefer_server_ciphers on;
  711. #ssl_buffer_size 8k;
  712. proxy_connect_timeout 600;
  713. proxy_send_timeout 600;
  714. proxy_read_timeout 600;
  715. send_timeout 600;
  716. location / {
  717. proxy_pass http://localhost:52000;
  718. proxy_set_header Host \$host;
  719. proxy_set_header X-Real-IP \$remote_addr;
  720. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  721. proxy_set_header X-Nginx-Proxy true;
  722. proxy_buffering off;
  723. proxy_redirect off;
  724. }
  725. }"
  726. record_templates[gcr]="server {
  727. listen 80;
  728. #listen 443 ssl;
  729. server_name gcr.$nginx_domain;
  730. #ssl_certificate /path/to/your_domain_name.crt;
  731. #ssl_certificate_key /path/to/your_domain_name.key;
  732. #ssl_session_timeout 1d;
  733. #ssl_session_cache shared:SSL:50m;
  734. #ssl_session_tickets off;
  735. #ssl_protocols TLSv1.2 TLSv1.3;
  736. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  737. #ssl_prefer_server_ciphers on;
  738. #ssl_buffer_size 8k;
  739. proxy_connect_timeout 600;
  740. proxy_send_timeout 600;
  741. proxy_read_timeout 600;
  742. send_timeout 600;
  743. location / {
  744. proxy_pass http://localhost:53000;
  745. proxy_set_header Host \$host;
  746. proxy_set_header X-Real-IP \$remote_addr;
  747. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  748. proxy_set_header X-Nginx-Proxy true;
  749. proxy_buffering off;
  750. proxy_redirect off;
  751. }
  752. }"
  753. record_templates[k8sgcr]="server {
  754. listen 80;
  755. #listen 443 ssl;
  756. server_name k8sgcr.$nginx_domain;
  757. #ssl_certificate /path/to/your_domain_name.crt;
  758. #ssl_certificate_key /path/to/your_domain_name.key;
  759. #ssl_session_timeout 1d;
  760. #ssl_session_cache shared:SSL:50m;
  761. #ssl_session_tickets off;
  762. #ssl_protocols TLSv1.2 TLSv1.3;
  763. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  764. #ssl_prefer_server_ciphers on;
  765. #ssl_buffer_size 8k;
  766. proxy_connect_timeout 600;
  767. proxy_send_timeout 600;
  768. proxy_read_timeout 600;
  769. send_timeout 600;
  770. location / {
  771. proxy_pass http://localhost:54000;
  772. proxy_set_header Host \$host;
  773. proxy_set_header X-Real-IP \$remote_addr;
  774. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  775. proxy_set_header X-Nginx-Proxy true;
  776. proxy_buffering off;
  777. proxy_redirect off;
  778. }
  779. }"
  780. record_templates[k8s]="server {
  781. listen 80;
  782. #listen 443 ssl;
  783. server_name k8s.$nginx_domain;
  784. #ssl_certificate /path/to/your_domain_name.crt;
  785. #ssl_certificate_key /path/to/your_domain_name.key;
  786. #ssl_session_timeout 1d;
  787. #ssl_session_cache shared:SSL:50m;
  788. #ssl_session_tickets off;
  789. #ssl_protocols TLSv1.2 TLSv1.3;
  790. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  791. #ssl_prefer_server_ciphers on;
  792. #ssl_buffer_size 8k;
  793. proxy_connect_timeout 600;
  794. proxy_send_timeout 600;
  795. proxy_read_timeout 600;
  796. send_timeout 600;
  797. location / {
  798. proxy_pass http://localhost:55000;
  799. proxy_set_header Host \$host;
  800. proxy_set_header X-Real-IP \$remote_addr;
  801. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  802. proxy_set_header X-Nginx-Proxy true;
  803. proxy_buffering off;
  804. proxy_redirect off;
  805. }
  806. }"
  807. record_templates[quay]="server {
  808. listen 80;
  809. #listen 443 ssl;
  810. server_name quay.$nginx_domain;
  811. #ssl_certificate /path/to/your_domain_name.crt;
  812. #ssl_certificate_key /path/to/your_domain_name.key;
  813. #ssl_session_timeout 1d;
  814. #ssl_session_cache shared:SSL:50m;
  815. #ssl_session_tickets off;
  816. #ssl_protocols TLSv1.2 TLSv1.3;
  817. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  818. #ssl_prefer_server_ciphers on;
  819. #ssl_buffer_size 8k;
  820. proxy_connect_timeout 600;
  821. proxy_send_timeout 600;
  822. proxy_read_timeout 600;
  823. send_timeout 600;
  824. location / {
  825. proxy_pass http://localhost:56000;
  826. proxy_set_header Host \$host;
  827. proxy_set_header X-Real-IP \$remote_addr;
  828. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  829. proxy_set_header X-Nginx-Proxy true;
  830. proxy_buffering off;
  831. proxy_redirect off;
  832. }
  833. }"
  834. record_templates[mcr]="server {
  835. listen 80;
  836. #listen 443 ssl;
  837. server_name mcr.$nginx_domain;
  838. #ssl_certificate /path/to/your_domain_name.crt;
  839. #ssl_certificate_key /path/to/your_domain_name.key;
  840. #ssl_session_timeout 1d;
  841. #ssl_session_cache shared:SSL:50m;
  842. #ssl_session_tickets off;
  843. #ssl_protocols TLSv1.2 TLSv1.3;
  844. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  845. #ssl_prefer_server_ciphers on;
  846. #ssl_buffer_size 8k;
  847. proxy_connect_timeout 600;
  848. proxy_send_timeout 600;
  849. proxy_read_timeout 600;
  850. send_timeout 600;
  851. location / {
  852. proxy_pass http://localhost:57000;
  853. proxy_set_header Host \$host;
  854. proxy_set_header X-Real-IP \$remote_addr;
  855. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  856. proxy_set_header X-Nginx-Proxy true;
  857. proxy_buffering off;
  858. proxy_redirect off;
  859. }
  860. }"
  861. record_templates[elastic]="server {
  862. listen 80;
  863. #listen 443 ssl;
  864. server_name elastic.$nginx_domain;
  865. #ssl_certificate /path/to/your_domain_name.crt;
  866. #ssl_certificate_key /path/to/your_domain_name.key;
  867. #ssl_session_timeout 1d;
  868. #ssl_session_cache shared:SSL:50m;
  869. #ssl_session_tickets off;
  870. #ssl_protocols TLSv1.2 TLSv1.3;
  871. #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  872. #ssl_prefer_server_ciphers on;
  873. #ssl_buffer_size 8k;
  874. proxy_connect_timeout 600;
  875. proxy_send_timeout 600;
  876. proxy_read_timeout 600;
  877. send_timeout 600;
  878. location / {
  879. proxy_pass http://localhost:58000;
  880. proxy_set_header Host \$host;
  881. proxy_set_header X-Real-IP \$remote_addr;
  882. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  883. proxy_set_header X-Nginx-Proxy true;
  884. proxy_buffering off;
  885. proxy_redirect off;
  886. }
  887. }"
  888. > /etc/nginx/conf.d/docker-proxy.conf
  889. for record in "${records_array[@]}"; do
  890. if [[ -n "${record_templates[$record]}" ]]; then
  891. echo "${record_templates[$record]}" >> /etc/nginx/conf.d/docker-proxy.conf
  892. fi
  893. done
  894. start_attempts=3
  895. for ((i=1; i<=$start_attempts; i++)); do
  896. start_nginx
  897. if pgrep "nginx" > /dev/null; then
  898. INFO "重新载入配置成功. Nginx服务启动完成"
  899. break
  900. else
  901. if [ $i -eq $start_attempts ]; then
  902. ERROR "Nginx 在尝试 $start_attempts 后无法启动。请检查配置"
  903. exit 1
  904. else
  905. WARN "第 $i 次启动 Nginx 失败。重试..."
  906. fi
  907. fi
  908. done
  909. break;;
  910. n|N )
  911. WARN "退出配置 Nginx 操作。"
  912. break;;
  913. * )
  914. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  915. esac
  916. done
  917. }
  918. function CHECK_DOCKER() {
  919. status=$(systemctl is-active docker)
  920. if [ "$status" = "active" ]; then
  921. INFO "Docker 服务运行正常,请继续..."
  922. else
  923. ERROR "Docker 服务未运行,请查看日志报错,定位问题后再次执行脚本!"
  924. ERROR "-----------服务启动失败,请查看错误日志 ↓↓↓-----------"
  925. journalctl -u docker.service --no-pager
  926. ERROR "-----------服务启动失败,请查看错误日志 ↑↑↑-----------"
  927. exit 1
  928. fi
  929. }
  930. function INSTALL_DOCKER() {
  931. repo_file="docker-ce.repo"
  932. url="https://download.docker.com/linux/$repo_type"
  933. MAX_ATTEMPTS=3
  934. attempt=0
  935. success=false
  936. if [ "$repo_type" = "centos" ] || [ "$repo_type" = "rhel" ]; then
  937. if ! command -v docker &> /dev/null;then
  938. while [[ $attempt -lt $MAX_ATTEMPTS ]]; do
  939. attempt=$((attempt + 1))
  940. WARN "Docker 未安装,正在进行安装..."
  941. yum-config-manager --add-repo $url/$repo_file &>/dev/null
  942. $package_manager -y install docker-ce &>/dev/null
  943. if [ $? -eq 0 ]; then
  944. success=true
  945. break
  946. fi
  947. ERROR "Docker 安装失败,正在尝试重新下载 (尝试次数: $attempt)"
  948. done
  949. if $success; then
  950. INFO "Docker 安装成功,版本为:$(docker --version)"
  951. systemctl restart docker &>/dev/null
  952. CHECK_DOCKER
  953. systemctl enable docker &>/dev/null
  954. else
  955. ERROR "Docker 安装失败,请尝试手动安装"
  956. exit 1
  957. fi
  958. else
  959. INFO "Docker 已安装,安装版本为:$(docker --version)"
  960. systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
  961. fi
  962. elif [ "$repo_type" == "ubuntu" ]; then
  963. if ! command -v docker &> /dev/null;then
  964. while [[ $attempt -lt $MAX_ATTEMPTS ]]; do
  965. attempt=$((attempt + 1))
  966. WARN "Docker 未安装,正在进行安装..."
  967. curl -fsSL $url/gpg | sudo apt-key add - &>/dev/null
  968. add-apt-repository "deb [arch=amd64] $url $(lsb_release -cs) stable" <<< $'\n' &>/dev/null
  969. $package_manager -y install docker-ce docker-ce-cli containerd.io &>/dev/null
  970. if [ $? -eq 0 ]; then
  971. success=true
  972. break
  973. fi
  974. ERROR "Docker 安装失败,正在尝试重新下载 (尝试次数: $attempt)"
  975. done
  976. if $success; then
  977. INFO "Docker 安装成功,版本为:$(docker --version)"
  978. systemctl restart docker &>/dev/null
  979. CHECK_DOCKER
  980. systemctl enable docker &>/dev/null
  981. else
  982. ERROR "Docker 安装失败,请尝试手动安装"
  983. exit 1
  984. fi
  985. else
  986. INFO "Docker 已安装,安装版本为:$(docker --version)"
  987. systemctl restart docker | grep -E "ERROR|ELIFECYCLE|WARN"
  988. fi
  989. elif [ "$repo_type" == "debian" ]; then
  990. if ! command -v docker &> /dev/null;then
  991. while [[ $attempt -lt $MAX_ATTEMPTS ]]; do
  992. attempt=$((attempt + 1))
  993. WARN "Docker 未安装,正在进行安装..."
  994. curl -fsSL $url/gpg | sudo apt-key add - &>/dev/null
  995. add-apt-repository "deb [arch=amd64] $url $(lsb_release -cs) stable" <<< $'\n' &>/dev/null
  996. $package_manager -y install docker-ce docker-ce-cli containerd.io &>/dev/null
  997. if [ $? -eq 0 ]; then
  998. success=true
  999. break
  1000. fi
  1001. ERROR "Docker 安装失败,正在尝试重新下载 (尝试次数: $attempt)"
  1002. done
  1003. if $success; then
  1004. INFO "Docker 安装成功,版本为:$(docker --version)"
  1005. systemctl restart docker &>/dev/null
  1006. CHECK_DOCKER
  1007. systemctl enable docker &>/dev/null
  1008. else
  1009. ERROR "Docker 安装失败,请尝试手动安装"
  1010. exit 1
  1011. fi
  1012. else
  1013. INFO "Docker 已安装,安装版本为:$(docker --version)"
  1014. systemctl restart docker &>/dev/null
  1015. CHECK_DOCKER
  1016. fi
  1017. else
  1018. ERROR "不支持的操作系统."
  1019. exit 1
  1020. fi
  1021. }
  1022. function INSTALL_COMPOSE() {
  1023. SEPARATOR "安装Docker Compose"
  1024. TAG=`curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r '.tag_name'`
  1025. url="https://github.com/docker/compose/releases/download/$TAG/docker-compose-$(uname -s)-$(uname -m)"
  1026. MAX_ATTEMPTS=3
  1027. attempt=0
  1028. success=false
  1029. save_path="/usr/local/bin"
  1030. chmod +x $save_path/docker-compose &>/dev/null
  1031. if ! command -v docker-compose &> /dev/null || [ -z "$(docker-compose --version)" ]; then
  1032. WARN "Docker Compose 未安装或安装不完整,正在进行安装..."
  1033. while [ $attempt -lt $MAX_ATTEMPTS ]; do
  1034. attempt=$((attempt + 1))
  1035. wget --continue -q $url -O $save_path/docker-compose
  1036. if [ $? -eq 0 ]; then
  1037. chmod +x $save_path/docker-compose
  1038. version_check=$(docker-compose --version)
  1039. if [ -n "$version_check" ]; then
  1040. success=true
  1041. chmod +x $save_path/docker-compose
  1042. break
  1043. else
  1044. WARN "Docker Compose 下载的文件不完整,正在尝试重新下载 (尝试次数: $attempt)"
  1045. rm -f $save_path/docker-compose
  1046. fi
  1047. fi
  1048. ERROR "Docker Compose 下载失败,正在尝试重新下载 (尝试次数: $attempt)"
  1049. done
  1050. if $success; then
  1051. INFO "Docker Compose 安装成功,版本为:$(docker-compose --version)"
  1052. else
  1053. ERROR "Docker Compose 下载失败,请尝试手动安装docker-compose"
  1054. exit 1
  1055. fi
  1056. else
  1057. chmod +x $save_path/docker-compose
  1058. INFO "Docker Compose 已经安装,版本为:$(docker-compose --version)"
  1059. fi
  1060. }
  1061. function INSTALL_DOCKER_CN() {
  1062. MAX_ATTEMPTS=3
  1063. attempt=0
  1064. success=false
  1065. cpu_arch=$(uname -m)
  1066. save_path="/opt/docker_tgz"
  1067. mkdir -p $save_path
  1068. docker_ver="docker-26.1.4.tgz"
  1069. case $cpu_arch in
  1070. "arm64")
  1071. url="https://raw.gitcode.com/dqzboy/docker/blobs/686ed74bf10e53fbec21f4c8d0eb4ae68b458198/$docker_ver"
  1072. ;;
  1073. "aarch64")
  1074. url="https://raw.gitcode.com/dqzboy/docker/blobs/686ed74bf10e53fbec21f4c8d0eb4ae68b458198/$docker_ver"
  1075. ;;
  1076. "x86_64")
  1077. url="https://raw.gitcode.com/dqzboy/docker/blobs/f4cf4ec4167a4e6e4debc61d7b0be0d9b729a93a/$docker_ver"
  1078. ;;
  1079. *)
  1080. ERROR "不支持的CPU架构: $cpu_arch"
  1081. exit 1
  1082. ;;
  1083. esac
  1084. if ! command -v docker &> /dev/null; then
  1085. while [ $attempt -lt $MAX_ATTEMPTS ]; do
  1086. attempt=$((attempt + 1))
  1087. WARN "Docker 未安装,正在进行安装..."
  1088. wget -P "$save_path" "$url" &>/dev/null
  1089. if [ $? -eq 0 ]; then
  1090. success=true
  1091. break
  1092. fi
  1093. ERROR "Docker 安装失败,正在尝试重新下载 (尝试次数: $attempt)"
  1094. done
  1095. if $success; then
  1096. tar -xzf $save_path/$docker_ver -C $save_path
  1097. \cp $save_path/docker/* /usr/bin/ &>/dev/null
  1098. rm -rf $save_path
  1099. INFO "Docker 安装成功,版本为:$(docker --version)"
  1100. cat > /usr/lib/systemd/system/docker.service <<EOF
  1101. [Unit]
  1102. Description=Docker Application Container Engine
  1103. Documentation=https://docs.docker.com
  1104. After=network-online.target firewalld.service
  1105. Wants=network-online.target
  1106. [Service]
  1107. Type=notify
  1108. ExecStart=/usr/bin/dockerd
  1109. ExecReload=/bin/kill -s HUP
  1110. LimitNOFILE=infinity
  1111. LimitNPROC=infinity
  1112. LimitCORE=infinity
  1113. TimeoutStartSec=0
  1114. Delegate=yes
  1115. KillMode=process
  1116. Restart=on-failure
  1117. StartLimitBurst=3
  1118. StartLimitInterval=60s
  1119. [Install]
  1120. WantedBy=multi-user.target
  1121. EOF
  1122. systemctl daemon-reload
  1123. systemctl restart docker &>/dev/null
  1124. CHECK_DOCKER
  1125. systemctl enable docker &>/dev/null
  1126. else
  1127. ERROR "Docker 安装失败,请尝试手动安装"
  1128. exit 1
  1129. fi
  1130. else
  1131. INFO "Docker 已安装,安装版本为:$(docker --version)"
  1132. systemctl restart docker &>/dev/null
  1133. CHECK_DOCKER
  1134. fi
  1135. }
  1136. function INSTALL_COMPOSE_CN() {
  1137. SEPARATOR "安装Docker Compose"
  1138. MAX_ATTEMPTS=3
  1139. attempt=0
  1140. cpu_arch=$(uname -m)
  1141. success=false
  1142. save_path="/usr/local/bin"
  1143. case $cpu_arch in
  1144. "arm64")
  1145. url="https://raw.gitcode.com/dqzboy/docker/blobs/b373da5a65a002691d78cf8d279704e85253d18a/docker-compose-linux-aarch64"
  1146. ;;
  1147. "aarch64")
  1148. url="https://raw.gitcode.com/dqzboy/docker/blobs/b373da5a65a002691d78cf8d279704e85253d18a/docker-compose-linux-aarch64"
  1149. ;;
  1150. "x86_64")
  1151. url="https://raw.gitcode.com/dqzboy/docker/blobs/3cd18cebe93acf81597b9c18f6770bf1bc5fa6dc/docker-compose-linux-x86_64"
  1152. ;;
  1153. *)
  1154. ERROR "不支持的CPU架构: $cpu_arch"
  1155. exit 1
  1156. ;;
  1157. esac
  1158. chmod +x $save_path/docker-compose &>/dev/null
  1159. if ! command -v docker-compose &> /dev/null || [ -z "$(docker-compose --version)" ]; then
  1160. WARN "Docker Compose 未安装或安装不完整,正在进行安装..."
  1161. while [ $attempt -lt $MAX_ATTEMPTS ]; do
  1162. attempt=$((attempt + 1))
  1163. wget --continue -q $url -O $save_path/docker-compose
  1164. if [ $? -eq 0 ]; then
  1165. chmod +x $save_path/docker-compose
  1166. version_check=$(docker-compose --version)
  1167. if [ -n "$version_check" ]; then
  1168. success=true
  1169. chmod +x $save_path/docker-compose
  1170. break
  1171. else
  1172. WARN "Docker Compose 下载的文件不完整,正在尝试重新下载 (尝试次数: $attempt)"
  1173. rm -f $save_path/docker-compose
  1174. fi
  1175. fi
  1176. ERROR "Docker Compose 下载失败,正在尝试重新下载 (尝试次数: $attempt)"
  1177. done
  1178. if $success; then
  1179. INFO "Docker Compose 安装成功,版本为:$(docker-compose --version)"
  1180. else
  1181. ERROR "Docker Compose 下载失败,请尝试手动安装docker-compose"
  1182. exit 1
  1183. fi
  1184. else
  1185. chmod +x $save_path/docker-compose
  1186. INFO "Docker Compose 安装成功,版本为:$(docker-compose --version)"
  1187. fi
  1188. }
  1189. function update_docker_registry_url() {
  1190. local container_name=$1
  1191. if [[ -f "${PROXY_DIR}/${DOCKER_COMPOSE_FILE}" ]]; then
  1192. sed -i "s@- DOCKER_REGISTRY_URL=.*@- DOCKER_REGISTRY_URL=http://${container_name}:5000@g" ${PROXY_DIR}/${DOCKER_COMPOSE_FILE}
  1193. else
  1194. ERROR "文件 ${LIGHT_CYAN}${PROXY_DIR}/${DOCKER_COMPOSE_FILE} ${RESET} ${LIGHT_RED}不存在${RESET},导致容器无法应用新配置"
  1195. exit 1
  1196. fi
  1197. }
  1198. function CONFIG_FILES() {
  1199. while true; do
  1200. read -e -p "$(INFO "安装环境确认 [${LIGHT_GREEN}国外输1${RESET} ${LIGHT_YELLOW}国内输2${RESET}] > ")" install_docker_reg
  1201. case "$install_docker_reg" in
  1202. 1 )
  1203. files=(
  1204. "dockerhub reg-docker-hub ${GITRAW}/config/registry-hub.yml"
  1205. "gcr reg-gcr ${GITRAW}/config/registry-gcr.yml"
  1206. "ghcr reg-ghcr ${GITRAW}/config/registry-ghcr.yml"
  1207. "quay reg-quay ${GITRAW}/config/registry-quay.yml"
  1208. "k8sgcr reg-k8s-gcr ${GITRAW}/config/registry-k8sgcr.yml"
  1209. "k8s reg-k8s ${GITRAW}/config/registry-k8s.yml"
  1210. "mcr reg-mcr ${GITRAW}/config/registry-mcr.yml"
  1211. "elastic reg-elastic ${GITRAW}/config/registry-elastic.yml"
  1212. )
  1213. break;;
  1214. 2 )
  1215. files=(
  1216. "dockerhub reg-docker-hub ${CNGITRAW}/config/registry-hub.yml"
  1217. "gcr reg-gcr ${CNGITRAW}/config/registry-gcr.yml"
  1218. "ghcr reg-ghcr ${CNGITRAW}/config/registry-ghcr.yml"
  1219. "quay reg-quay ${CNGITRAW}/config/registry-quay.yml"
  1220. "k8sgcr reg-k8s-gcr ${CNGITRAW}/config/registry-k8sgcr.yml"
  1221. "k8s reg-k8s ${CNGITRAW}/config/registry-k8s.yml"
  1222. "mcr reg-mcr ${CNGITRAW}/config/registry-mcr.yml"
  1223. "elastic reg-elastic ${CNGITRAW}/config/registry-elastic.yml"
  1224. )
  1225. break;;
  1226. * )
  1227. INFO "请输入 ${LIGHT_GREEN}1${RESET} 表示国外 或者 ${LIGHT_YELLOW}2${RESET} 表示大陆";;
  1228. esac
  1229. done
  1230. }
  1231. function DOWN_CONFIG() {
  1232. selected_names=()
  1233. selected_files=()
  1234. selected_containers=()
  1235. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1236. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  1237. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  1238. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  1239. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  1240. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  1241. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  1242. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  1243. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  1244. echo -e "${GREEN}9)${RESET} ${BOLD}all${RESET}"
  1245. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  1246. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1247. read -e -p "$(INFO "输入序号下载对应配置文件,${LIGHT_YELLOW}空格分隔${RESET}多个选项. ${LIGHT_CYAN}all下载所有${RESET} > ")" choices_reg
  1248. while [[ ! "$choices_reg" =~ ^([0-9]+[[:space:]]*)+$ ]]; do
  1249. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-9 ${RESET}序号"
  1250. read -e -p "$(INFO "输入序号下载对应配置文件,${LIGHT_YELLOW}空格分隔${RESET}多个选项. ${LIGHT_CYAN}all下载所有${RESET} > ")" choices_reg
  1251. done
  1252. if [[ "$choices_reg" == "9" ]]; then
  1253. for file in "${files[@]}"; do
  1254. file_name=$(echo "$file" | cut -d' ' -f1)
  1255. container_name=$(echo "$file" | cut -d' ' -f2)
  1256. file_url=$(echo "$file" | cut -d' ' -f3-)
  1257. selected_names+=("$file_name")
  1258. selected_containers+=("$container_name")
  1259. selected_files+=("$file_url")
  1260. wget -NP ${PROXY_DIR}/ $file_url &>/dev/null
  1261. done
  1262. selected_all=true
  1263. elif [[ "$choices_reg" == "0" ]]; then
  1264. WARN "退出下载配置! ${LIGHT_YELLOW}首次安装如果没有配置无法启动服务,只能启动UI服务${RESET}"
  1265. return
  1266. else
  1267. for choice in ${choices_reg}; do
  1268. if [[ $choice =~ ^[0-9]+$ ]] && ((choice > 0 && choice <= ${#files[@]})); then
  1269. file_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f1)
  1270. container_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f2)
  1271. file_url=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f3-)
  1272. selected_names+=("$file_name")
  1273. selected_containers+=("$container_name")
  1274. selected_files+=("$file_url")
  1275. wget -NP ${PROXY_DIR}/ $file_url &>/dev/null
  1276. else
  1277. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-9 ${RESET}序号"
  1278. fi
  1279. done
  1280. selected_all=false
  1281. # 非更新配置操作则执行下面步骤
  1282. if [[ "$main_choice" != "4" ]]; then
  1283. first_selected_container=${selected_containers[0]}
  1284. update_docker_registry_url "$first_selected_container"
  1285. fi
  1286. fi
  1287. WARN "${LIGHT_GREEN}>>> 提示:${RESET} ${LIGHT_BLUE}Proxy代理缓存过期时间${RESET} ${MAGENTA}单位:ns、us、ms、s、m、h.默认ns,0禁用缓存过期${RESET}"
  1288. read -e -p "$(INFO "是否要修改缓存时间? ${PROMPT_YES_NO}")" modify_cache
  1289. while [[ "$modify_cache" != "y" && "$modify_cache" != "n" ]]; do
  1290. WARN "无效输入,请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}"
  1291. read -e -p "$(INFO "是否要修改缓存时间? ${PROMPT_YES_NO}")" modify_cache
  1292. done
  1293. if [[ "$modify_cache" == "y" ]]; then
  1294. while true; do
  1295. read -e -p "$(INFO "请输入新的缓存时间值: ")" new_ttl
  1296. for file_url in "${selected_files[@]}"; do
  1297. yml_name=$(basename "$file_url")
  1298. sed -ri "s/ttl: 168h/ttl: ${new_ttl}/g" ${PROXY_DIR}/${yml_name} &>/dev/null
  1299. done
  1300. break
  1301. done
  1302. fi
  1303. }
  1304. # 一键部署调此函数
  1305. function PROXY_HTTP() {
  1306. read -e -p "$(INFO "是否添加代理? ${PROMPT_YES_NO}")" modify_config
  1307. case $modify_config in
  1308. [Yy]* )
  1309. read -e -p "$(INFO "输入代理地址 ${LIGHT_MAGENTA}(eg: host:port)${RESET}: ")" url
  1310. while [[ -z "$url" ]]; do
  1311. WARN "代理${LIGHT_YELLOW}地址不能为空${RESET},请重新输入!"
  1312. read -e -p "$(INFO "输入代理地址 ${LIGHT_MAGENTA}(eg: host:port)${RESET}: ")" url
  1313. done
  1314. sed -i "s@#- http=http://host:port@- http_proxy=http://${url}@g" ${PROXY_DIR}/${DOCKER_COMPOSE_FILE}
  1315. sed -i "s@#- https=http://host:port@- https_proxy=http://${url}@g" ${PROXY_DIR}/${DOCKER_COMPOSE_FILE}
  1316. INFO "你配置代理地址为: ${CYAN}http://${url}${RESET}"
  1317. ;;
  1318. [Nn]* )
  1319. WARN "跳过添加代理配置"
  1320. ;;
  1321. * )
  1322. ERROR "无效的输入。请重新输入${LIGHT_GREEN}Y or N ${RESET}的选项"
  1323. PROXY_HTTP
  1324. ;;
  1325. esac
  1326. }
  1327. # 7) 本机Docker代理,调此函数
  1328. function DOCKER_PROXY_HTTP() {
  1329. WARN "${BOLD}${LIGHT_GREEN}提示:${RESET} ${LIGHT_CYAN}配置本机Docker服务走代理,加速本机Docker镜像下载${RESET}"
  1330. read -e -p "$(INFO "是否添加本机Docker服务代理? ${PROMPT_YES_NO}")" modify_proxy
  1331. case $modify_proxy in
  1332. [Yy]* )
  1333. read -e -p "$(INFO "输入代理地址 ${LIGHT_MAGENTA}(eg: host:port)${RESET}: ")" url
  1334. while [[ -z "$url" ]]; do
  1335. WARN "代理${LIGHT_YELLOW}地址不能为空${RESET},请重新输入。"
  1336. read -e -p "$(INFO "输入代理地址 ${LIGHT_MAGENTA}(eg: host:port)${RESET}: ")" url
  1337. done
  1338. INFO "你配置代理地址为: ${CYAN}http://${url}${RESET}"
  1339. ;;
  1340. [Nn]* )
  1341. WARN "退出本机Docker服务代理配置"
  1342. exit 1
  1343. ;;
  1344. * )
  1345. ERROR "无效的输入。请重新输入${LIGHT_GREEN}Y or N ${RESET}的选项"
  1346. DOCKER_PROXY_HTTP
  1347. ;;
  1348. esac
  1349. }
  1350. function CHECK_DOCKER_PROXY() {
  1351. local url=$1
  1352. local http_proxy=$(docker info 2>/dev/null | grep -i "HTTP Proxy" | awk -F ': ' '{print $2}')
  1353. local https_proxy=$(docker info 2>/dev/null | grep -i "HTTPS Proxy" | awk -F ': ' '{print $2}')
  1354. if [[ "$http_proxy" == "http://$url" && "$https_proxy" == "http://$url" ]]; then
  1355. INFO "Docker 代理${LIGHT_GREEN}配置成功${RESET},当前 HTTP Proxy: ${LIGHT_CYAN}$http_proxy${RESET}, HTTPS Proxy: ${LIGHT_CYAN}$https_proxy${RESET}"
  1356. else
  1357. ERROR "Docker 代理${LIGHT_RED}配置失败${RESET},请检查配置并重新执行配置"
  1358. DOCKER_PROXY_HTTP
  1359. fi
  1360. }
  1361. function ADD_DOCKERD_PROXY() {
  1362. mkdir -p /etc/systemd/system/docker.service.d
  1363. if [ ! -f /etc/systemd/system/docker.service.d/http-proxy.conf ]; then
  1364. cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
  1365. [Service]
  1366. Environment="HTTP_PROXY=http://$url"
  1367. Environment="HTTPS_PROXY=http://$url"
  1368. EOF
  1369. systemctl daemon-reload
  1370. systemctl restart docker &>/dev/null
  1371. CHECK_DOCKER
  1372. CHECK_DOCKER_PROXY "$url"
  1373. else
  1374. if ! grep -q "HTTP_PROXY=http://$url" /etc/systemd/system/docker.service.d/http-proxy.conf || ! grep -q "HTTPS_PROXY=http://$url" /etc/systemd/system/docker.service.d/http-proxy.conf; then
  1375. cat >> /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
  1376. [Service]
  1377. Environment="HTTP_PROXY=http://$url"
  1378. Environment="HTTPS_PROXY=http://$url"
  1379. EOF
  1380. systemctl daemon-reload
  1381. systemctl restart docker &>/dev/null
  1382. CHECK_DOCKER
  1383. CHECK_DOCKER_PROXY "$url"
  1384. else
  1385. if [[ "$main_choice" = "7" ]]; then
  1386. WARN "已经存在相同的代理配置,${LIGHT_RED}请勿重复配置${RESET}"
  1387. fi
  1388. fi
  1389. fi
  1390. }
  1391. # 一键部署时调用START_CONTAINER
  1392. function START_CONTAINER() {
  1393. if [ "$modify_config" = "y" ] || [ "$modify_config" = "Y" ]; then
  1394. ADD_DOCKERD_PROXY
  1395. else
  1396. INFO "拉取服务镜像并启动服务中,请稍等..."
  1397. fi
  1398. # DOWN_CONFIG函数执行后判断selected_all变量
  1399. if [ "$selected_all" = true ]; then
  1400. docker-compose up -d --force-recreate
  1401. # 检查命令执行是否成功
  1402. if [ $? -ne 0 ]; then
  1403. ERROR "Docker 容器启动失败,请通过查看日志确认启动失败原因"
  1404. exit 1
  1405. fi
  1406. else
  1407. docker-compose up -d "${selected_names[@]}" registry-ui
  1408. # 检查命令执行是否成功
  1409. if [ $? -ne 0 ]; then
  1410. ERROR "Docker 容器启动失败,请通过查看日志确认启动失败原因"
  1411. exit 1
  1412. fi
  1413. fi
  1414. }
  1415. # 使用函数UPDATE_CONFIG时调用RESTART_CONTAINER
  1416. function RESTART_CONTAINER() {
  1417. # DOWN_CONFIG函数执行后判断selected_all变量
  1418. if [ "$selected_all" = true ]; then
  1419. docker-compose restart
  1420. # 检查命令执行是否成功
  1421. if [ $? -ne 0 ]; then
  1422. ERROR "Docker 容器启动失败,请通过查看日志确认启动失败原因"
  1423. exit 1
  1424. fi
  1425. else
  1426. docker-compose restart "${selected_names[@]}"
  1427. # 检查命令执行是否成功
  1428. if [ $? -ne 0 ]; then
  1429. ERROR "Docker 容器启动失败,请通过查看日志确认启动失败原因"
  1430. exit 1
  1431. fi
  1432. fi
  1433. }
  1434. function INSTALL_DOCKER_PROXY() {
  1435. SEPARATOR "部署Docker Proxy"
  1436. CONFIG_FILES
  1437. if [[ "$install_docker_reg" == "1" ]]; then
  1438. wget -NP ${PROXY_DIR}/ ${GITRAW}/${DOCKER_COMPOSE_FILE} &>/dev/null
  1439. elif [[ "$install_docker_reg" == "2" ]]; then
  1440. wget -NP ${PROXY_DIR}/ ${CNGITRAW}/${DOCKER_COMPOSE_FILE} &>/dev/null
  1441. fi
  1442. DOWN_CONFIG
  1443. PROXY_HTTP
  1444. START_CONTAINER
  1445. }
  1446. function STOP_REMOVE_CONTAINER() {
  1447. if [[ -f "${PROXY_DIR}/${DOCKER_COMPOSE_FILE}" ]]; then
  1448. INFO "停止和移除所有容器"
  1449. docker-compose -f "${PROXY_DIR}/${DOCKER_COMPOSE_FILE}" down --remove-orphans
  1450. else
  1451. WARN "${LIGHT_YELLOW}容器目前未处于运行状态,无需进行删除操作!${RESET}"
  1452. exit 1
  1453. fi
  1454. }
  1455. function UPDATE_CONFIG() {
  1456. while true; do
  1457. read -e -p "$(WARN "是否更新配置,更新前请确保您已备份现有配置,此操作不可逆? ${PROMPT_YES_NO}")" update_conf
  1458. case "$update_conf" in
  1459. y|Y )
  1460. CONFIG_FILES
  1461. DOWN_CONFIG
  1462. RESTART_CONTAINER
  1463. break;;
  1464. n|N )
  1465. WARN "退出配置更新操作。"
  1466. break;;
  1467. * )
  1468. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  1469. esac
  1470. done
  1471. }
  1472. function REMOVE_NONE_TAG() {
  1473. docker images | grep "^${IMAGE_NAME}.*<none>" | awk '{print $3}' | xargs -r docker rmi
  1474. images=$(docker images ${IMAGE_NAME} --format '{{.Repository}}:{{.Tag}}')
  1475. latest=$(echo "$images" | sort -V | tail -n1)
  1476. for image in $images
  1477. do
  1478. if [ "$image" != "$latest" ];then
  1479. docker rmi $image
  1480. fi
  1481. done
  1482. }
  1483. function PACKAGE() {
  1484. while true; do
  1485. read -e -p "$(INFO "是否执行软件包安装? (${LIGHT_YELLOW}首次部署需安装依赖${RESET}) ${PROMPT_YES_NO}")" choice_package
  1486. case "$choice_package" in
  1487. y|Y )
  1488. INSTALL_PACKAGE
  1489. break;;
  1490. n|N )
  1491. WARN "跳过软件包安装步骤"
  1492. break;;
  1493. * )
  1494. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  1495. esac
  1496. done
  1497. }
  1498. function INSTALL_WEB() {
  1499. while true; do
  1500. SEPARATOR "安装WEB服务"
  1501. read -e -p "$(INFO "是否安装WEB服务? (用来通过域名方式访问加速服务) ${PROMPT_YES_NO}")" choice_service
  1502. if [[ "$choice_service" =~ ^[YyNn]$ ]]; then
  1503. if [[ "$choice_service" == "Y" || "$choice_service" == "y" ]]; then
  1504. while true; do
  1505. read -e -p "$(INFO "选择安装的WEB服务。安装${LIGHT_CYAN}Caddy可自动开启HTTPS${RESET} [Nginx/Caddy]: ")" web_service
  1506. if [[ "$web_service" =~ ^(nginx|Nginx|caddy|Caddy)$ ]]; then
  1507. if [[ "$web_service" == "nginx" || "$web_service" == "Nginx" ]]; then
  1508. INSTALL_NGINX
  1509. CONFIG_NGINX
  1510. break
  1511. elif [[ "$web_service" == "caddy" || "$web_service" == "Caddy" ]]; then
  1512. INSTALL_CADDY
  1513. CONFIG_CADDY
  1514. break
  1515. fi
  1516. else
  1517. WARN "请输入 ${LIGHT_CYAN}nginx${RESET} 或 ${LIGHT_BLUE}caddy${RESET}"
  1518. fi
  1519. done
  1520. break
  1521. else
  1522. WARN "跳过WEB服务安装步骤"
  1523. break
  1524. fi
  1525. else
  1526. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}"
  1527. fi
  1528. done
  1529. }
  1530. function PROMPT(){
  1531. PUBLIC_IP=$(curl -s https://ifconfig.me)
  1532. ALL_IPS=$(hostname -I)
  1533. INTERNAL_IP=$(echo "$ALL_IPS" | awk '$1!="127.0.0.1" && $1!="::1" && $1!="docker0" {print $1}')
  1534. echo
  1535. INFO "=================感谢您的耐心等待,安装已经完成=================="
  1536. INFO
  1537. INFO "请用浏览器访问 UI 面板: "
  1538. INFO "公网访问地址: ${UNDERLINE}http://$PUBLIC_IP:50000${RESET}"
  1539. INFO "内网访问地址: ${UNDERLINE}http://$INTERNAL_IP:50000${RESET}"
  1540. INFO
  1541. INFO "服务安装路径: ${LIGHT_BLUE}${PROXY_DIR}${RESET}"
  1542. INFO
  1543. INFO "作者博客: https://dqzboy.com"
  1544. INFO "技术交流: https://t.me/dqzboyblog"
  1545. INFO "代码仓库: https://github.com/dqzboy/Docker-Proxy"
  1546. INFO
  1547. INFO "若用云服务器并设域名及证书,需在安全组开放80、443端口;否则开放对应服务监听端口"
  1548. INFO
  1549. INFO "================================================================"
  1550. }
  1551. function INSTALL_PROXY() {
  1552. ALL_IN_ONE() {
  1553. CHECK_OS
  1554. CHECK_PACKAGE_MANAGER
  1555. CHECK_PKG_MANAGER
  1556. CHECKMEM
  1557. CHECKFIRE
  1558. CHECKBBR
  1559. PACKAGE
  1560. INSTALL_WEB
  1561. while true; do
  1562. SEPARATOR "安装Docker"
  1563. read -e -p "$(INFO "安装环境确认 [${LIGHT_GREEN}国外输1${RESET} ${LIGHT_YELLOW}国内输2${RESET}] > ")" deploy_docker
  1564. case "$deploy_docker" in
  1565. 1 )
  1566. INSTALL_DOCKER
  1567. INSTALL_COMPOSE
  1568. break;;
  1569. 2 )
  1570. INSTALL_DOCKER_CN
  1571. INSTALL_COMPOSE_CN
  1572. break;;
  1573. * )
  1574. INFO "请输入 ${LIGHT_GREEN}1${RESET} 表示国外 或者 ${LIGHT_YELLOW}2${RESET} 表示大陆";;
  1575. esac
  1576. done
  1577. INSTALL_DOCKER_PROXY
  1578. PROMPT
  1579. }
  1580. ADD_DOCKER_SERVICE() {
  1581. WARN "提示: 此操作是在你的服务器${LIGHT_CYAN}已经部署对应组件${RESET}后才可执行,否则执行过程将会出现${LIGHT_RED}各种报错!${RESET}"
  1582. INSTALL_DOCKER_PROXY
  1583. }
  1584. SEPARATOR "安装服务"
  1585. echo -e "1) 一键${BOLD}${LIGHT_GREEN}部署所有${RESET}服务"
  1586. echo -e "2) ${BOLD}${LIGHT_CYAN}安装指定${RESET}容器服务"
  1587. echo -e "3) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  1588. echo -e "0) ${BOLD}退出脚本${RESET}"
  1589. echo "---------------------------------------------------------------"
  1590. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" proxy_install
  1591. case $proxy_install in
  1592. 1)
  1593. ALL_IN_ONE
  1594. ;;
  1595. 2)
  1596. ADD_DOCKER_SERVICE
  1597. ;;
  1598. 3)
  1599. main_menu
  1600. ;;
  1601. 0)
  1602. exit 1
  1603. ;;
  1604. *)
  1605. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-3${RESET}的选项."
  1606. INSTALL_PROXY
  1607. ;;
  1608. esac
  1609. }
  1610. function REMOVE_CMDUI() {
  1611. if [ -d "${CMDUI_DIR}" ]; then
  1612. if [ -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" ]; then
  1613. INFO "停止和移除HubCMD-UI容器"
  1614. docker-compose -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" down --remove-orphans
  1615. rm -rf "${CMDUI_DIR}"
  1616. else
  1617. WARN "${LIGHT_YELLOW}文件${CMDUI_DIR}/${DOCKER_COMPOSE_FILE} 不存在,无需进行删除操作!${RESET}"
  1618. fi
  1619. else
  1620. WARN "${LIGHT_YELLOW}目录 ${CMDUI_DIR} 不存在,无需进行删除操作!${RESET}"
  1621. fi
  1622. docker images | grep "^${CMDUI_IMAGE_NAME}.*<none>" | awk '{print $3}' | xargs -r docker rmi
  1623. images=$(docker images ${CMDUI_IMAGE_NAME} --format '{{.Repository}}:{{.Tag}}')
  1624. latest=$(echo "$images" | sort -V | tail -n1)
  1625. for image in $images; do
  1626. if [ "$image" != "$latest" ]; then
  1627. docker rmi $image
  1628. fi
  1629. done
  1630. # 强制移除所有相关镜像
  1631. docker rmi --force $(docker images -q ${CMDUI_IMAGE_NAME}) &>/dev/null
  1632. }
  1633. function HUBCMDUI() {
  1634. CMDUI_NAME="hubcmd-ui"
  1635. CMDUI_DIR="${PROXY_DIR}/hubcmdui"
  1636. CMDUI_PROMPT() {
  1637. PUBLIC_IP=$(curl -s https://ifconfig.me)
  1638. ALL_IPS=$(hostname -I)
  1639. INTERNAL_IP=$(echo "$ALL_IPS" | awk '$1!="127.0.0.1" && $1!="::1" && $1!="docker0" {print $1}')
  1640. echo
  1641. INFO "=================感谢您的耐心等待,安装已经完成=================="
  1642. INFO
  1643. INFO "请用浏览器访问 HubCMD-UI 面板: "
  1644. INFO "公网访问地址: ${UNDERLINE}http://$PUBLIC_IP:30080${RESET}"
  1645. INFO "内网访问地址: ${UNDERLINE}http://$INTERNAL_IP:30080${RESET}"
  1646. INFO
  1647. INFO "后端访问地址: 地址后面跟admin,例: ${UNDERLINE}http://$INTERNAL_IP/admin:30080${RESET}"
  1648. INFO "默认账号密码: ${LIGHT_GREEN}root${RESET}/${LIGHT_CYAN}admin${RESET}"
  1649. INFO
  1650. INFO "服务安装路径: ${LIGHT_BLUE}${CMDUI_DIR}${RESET}"
  1651. INFO
  1652. INFO "作者博客: https://dqzboy.com"
  1653. INFO "技术交流: https://t.me/dqzboyblog"
  1654. INFO "代码仓库: https://github.com/dqzboy/Docker-Proxy"
  1655. INFO
  1656. INFO "================================================================"
  1657. }
  1658. INSTALL_HUBCMDUI() {
  1659. mkdir -p ${CMDUI_DIR}
  1660. INFO "正在安装HubCMD-UI服务,请稍等!安装路径 ${LIGHT_CYAN}${CMDUI_DIR}${RESET}"
  1661. if [[ -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" ]]; then
  1662. if docker-compose ps --services 2>/dev/null | grep -q "^${CMDUI_NAME}$"; then
  1663. INFO "${CMDUI_NAME} 已经安装并启动,无需重复执行安装!"
  1664. else
  1665. docker-compose -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" up -d
  1666. fi
  1667. else
  1668. wget -NP ${CMDUI_DIR}/ ${CMDUI_COMPOSE_FILE} &>/dev/null
  1669. if [ $? -ne 0 ]; then
  1670. WARN "下载${LIGHT_YELLOW}docker-compose.yaml 文件失败${RESET},请稍后重试!"
  1671. HUBCMDUI
  1672. fi
  1673. docker-compose -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" up -d
  1674. if [ $? -eq 0 ]; then
  1675. CMDUI_PROMPT
  1676. exit 1
  1677. else
  1678. WARN "服务安装失败,请稍后重试!"
  1679. HUBCMDUI
  1680. fi
  1681. fi
  1682. }
  1683. UPDATE_HUBCMDUI() {
  1684. if [ -d "${CMDUI_DIR}" ]; then
  1685. if [ -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" ]; then
  1686. INFO "正在更新HubCMD-UI容器"
  1687. docker-compose -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" pull
  1688. if [ $? -ne 0 ]; then
  1689. WARN "HubCMD-UI ${LIGHT_YELLOW}镜像拉取失败${RESET},请稍后重试!"
  1690. HUBCMDUI
  1691. fi
  1692. docker-compose -f "${CMDUI_DIR}/${DOCKER_COMPOSE_FILE}" up -d --force-recreate
  1693. if [ $? -ne 0 ]; then
  1694. WARN "HubCMD-UI ${LIGHT_YELLOW}服务启动失败${RESET},请稍后重试!"
  1695. HUBCMDUI
  1696. else
  1697. INFO "HubCMD-UI ${LIGHT_GREEN}服务更新并启动完成${RESET}"
  1698. fi
  1699. else
  1700. WARN "${LIGHT_YELLOW}文件${CMDUI_DIR}/${DOCKER_COMPOSE_FILE} 不存在,无法进行更新操作!${RESET}"
  1701. fi
  1702. else
  1703. WARN "${LIGHT_YELLOW}目录 ${CMDUI_DIR} 不存在,无法进行更新操作!${RESET}"
  1704. fi
  1705. }
  1706. UNINSTALL_HUBCMDUI() {
  1707. WARN "${LIGHT_RED}注意:${RESET} ${LIGHT_YELLOW}请执行删除之前确定是否需要备份配置文件${RESET}"
  1708. while true; do
  1709. read -e -p "$(INFO "本人${LIGHT_RED}已知晓后果,确认删除${RESET}服务? ${PROMPT_YES_NO}")" delcmdui
  1710. case "$delcmdui" in
  1711. y|Y )
  1712. REMOVE_CMDUI
  1713. break;;
  1714. n|N )
  1715. WARN "退出执行卸载服务"
  1716. break;;
  1717. * )
  1718. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  1719. esac
  1720. done
  1721. }
  1722. SEPARATOR "HubCMD-UI管理"
  1723. echo -e "1) ${BOLD}${LIGHT_GREEN}安装${RESET}HubCMD-UI"
  1724. echo -e "2) ${BOLD}${LIGHT_YELLOW}卸载${RESET}HubCMD-UI"
  1725. echo -e "3) ${BOLD}${LIGHT_CYAN}更新${RESET}HubCMD-UI"
  1726. echo -e "4) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  1727. echo -e "0) ${BOLD}退出脚本${RESET}"
  1728. echo "---------------------------------------------------------------"
  1729. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" cmdui_choice
  1730. case $cmdui_choice in
  1731. 1)
  1732. INSTALL_HUBCMDUI
  1733. HUBCMDUI
  1734. ;;
  1735. 2)
  1736. UNINSTALL_HUBCMDUI
  1737. HUBCMDUI
  1738. ;;
  1739. 3)
  1740. UPDATE_HUBCMDUI
  1741. HUBCMDUI
  1742. ;;
  1743. 4)
  1744. main_menu
  1745. ;;
  1746. 0)
  1747. exit 1
  1748. ;;
  1749. *)
  1750. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-4${RESET}的选项."
  1751. HUBCMDUI
  1752. ;;
  1753. esac
  1754. }
  1755. function COMP_INST() {
  1756. SEPARATOR "安装组件"
  1757. echo -e "1) ${BOLD}安装${LIGHT_GREEN}环境依赖${RESET}"
  1758. echo -e "2) ${BOLD}安装${LIGHT_CYAN}Docker${RESET}"
  1759. echo -e "3) ${BOLD}安装${LIGHT_MAGENTA}Compose${RESET}"
  1760. echo -e "4) ${BOLD}安装${GREEN}Nginx${RESET}"
  1761. echo -e "5) ${BOLD}安装${LIGHT_BLUE}Caddy${RESET}"
  1762. echo -e "6) ${BOLD}配置${LIGHT_YELLOW}Nginx${RESET}"
  1763. echo -e "7) ${BOLD}配置${CYAN}Caddy${RESET}"
  1764. echo -e "8) ${BOLD}安装${BLUE}HubCMD-UI${RESET}"
  1765. echo -e "9) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  1766. echo -e "0) ${BOLD}退出脚本${RESET}"
  1767. echo "---------------------------------------------------------------"
  1768. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" comp_choice
  1769. case $comp_choice in
  1770. 1)
  1771. CHECK_OS
  1772. CHECK_PACKAGE_MANAGER
  1773. CHECK_PKG_MANAGER
  1774. CHECKMEM
  1775. PACKAGE
  1776. COMP_INST
  1777. ;;
  1778. 2)
  1779. CHECK_OS
  1780. CHECK_PACKAGE_MANAGER
  1781. CHECK_PKG_MANAGER
  1782. while true; do
  1783. SEPARATOR "安装Docker"
  1784. read -e -p "$(INFO "安装环境确认 [${LIGHT_GREEN}国外输1${RESET} ${LIGHT_YELLOW}国内输2${RESET}] > ")" deploy_docker
  1785. case "$deploy_docker" in
  1786. 1 )
  1787. INSTALL_DOCKER
  1788. break;;
  1789. 2 )
  1790. INSTALL_DOCKER_CN
  1791. break;;
  1792. * )
  1793. INFO "请输入 ${LIGHT_GREEN}1${RESET} 表示国外 或者 ${LIGHT_YELLOW}2${RESET} 表示大陆";;
  1794. esac
  1795. done
  1796. COMP_INST
  1797. ;;
  1798. 3)
  1799. CHECK_OS
  1800. CHECK_PACKAGE_MANAGER
  1801. CHECK_PKG_MANAGER
  1802. while true; do
  1803. read -e -p "$(INFO "安装环境确认 [${LIGHT_GREEN}国外输1${RESET} ${LIGHT_YELLOW}国内输2${RESET}] > ")" deploy_compose
  1804. case "$deploy_compose" in
  1805. 1 )
  1806. INSTALL_COMPOSE
  1807. break;;
  1808. 2 )
  1809. INSTALL_COMPOSE_CN
  1810. break;;
  1811. * )
  1812. INFO "请输入 ${LIGHT_GREEN}1${RESET} 表示国外 或者 ${LIGHT_YELLOW}2${RESET} 表示大陆";;
  1813. esac
  1814. done
  1815. COMP_INST
  1816. ;;
  1817. 4)
  1818. CHECK_OS
  1819. CHECK_PACKAGE_MANAGER
  1820. CHECK_PKG_MANAGER
  1821. INSTALL_NGINX
  1822. COMP_INST
  1823. ;;
  1824. 5)
  1825. CHECK_OS
  1826. CHECK_PACKAGE_MANAGER
  1827. CHECK_PKG_MANAGER
  1828. INSTALL_CADDY
  1829. COMP_INST
  1830. ;;
  1831. 6)
  1832. CONFIG_NGINX
  1833. COMP_INST
  1834. ;;
  1835. 7)
  1836. CONFIG_CADDY
  1837. COMP_INST
  1838. ;;
  1839. 8)
  1840. HUBCMDUI
  1841. COMP_INST
  1842. ;;
  1843. 9)
  1844. main_menu
  1845. ;;
  1846. 0)
  1847. exit 1
  1848. ;;
  1849. *)
  1850. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-8${RESET}的选项."
  1851. COMP_INST
  1852. ;;
  1853. esac
  1854. }
  1855. function SVC_MGMT() {
  1856. # 定义Docker容器服务名称
  1857. CONTAINER_SERVICES() {
  1858. services=(
  1859. "dockerhub"
  1860. "gcr"
  1861. "ghcr"
  1862. "quay"
  1863. "k8sgcr"
  1864. "k8s"
  1865. "mcr"
  1866. "elastic"
  1867. )
  1868. }
  1869. RESTART_SERVICE() {
  1870. CONTAINER_SERVICES
  1871. selected_services=()
  1872. WARN "重启服务请在${LIGHT_GREEN}${DOCKER_COMPOSE_FILE}${RESET}文件存储目录下执行脚本.默认安装路径: ${LIGHT_BLUE}${PROXY_DIR}${RESET}"
  1873. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1874. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  1875. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  1876. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  1877. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  1878. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  1879. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  1880. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  1881. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  1882. echo -e "${GREEN}9)${RESET} ${BOLD}all${RESET}"
  1883. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  1884. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1885. read -e -p "$(INFO "输入序号选择对应服务,${LIGHT_YELLOW}空格分隔${RESET}多个选项. ${LIGHT_CYAN}all选择所有${RESET} > ")" restart_service
  1886. if [[ "$restart_service" == "9" ]]; then
  1887. for service_name in "${services[@]}"; do
  1888. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  1889. selected_services+=("$service_name")
  1890. else
  1891. WARN "服务 ${service_name}未运行,跳过重启。"
  1892. fi
  1893. done
  1894. INFO "重启的服务: ${selected_services[*]}"
  1895. elif [[ "$restart_service" == "0" ]]; then
  1896. WARN "退出重启服务!"
  1897. exit 1
  1898. else
  1899. for choice in ${restart_service}; do
  1900. if [[ $choice =~ ^[0-9]+$ ]] && ((choice >0 && choice <= ${#services[@]})); then
  1901. service_name="${services[$((choice -1))]}"
  1902. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  1903. selected_services+=("$service_name")
  1904. else
  1905. WARN "服务 ${service_name} 未运行,跳过重启。"
  1906. fi
  1907. else
  1908. ERROR "无效的选择: $choice. 请重新${LIGHT_GREEN}选择0-9${RESET}的选项"
  1909. RESTART_SERVICE # 选择无效重新调用当前函数进行选择
  1910. fi
  1911. done
  1912. INFO "重启的服务: ${selected_services[*]}"
  1913. fi
  1914. }
  1915. UPDATE_SERVICE() {
  1916. CONTAINER_SERVICES
  1917. selected_services=()
  1918. WARN "更新服务请在${LIGHT_GREEN}${DOCKER_COMPOSE_FILE}${RESET}文件存储目录下执行脚本.默认安装路径: ${LIGHT_BLUE}${PROXY_DIR}${RESET}"
  1919. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1920. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  1921. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  1922. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  1923. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  1924. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  1925. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  1926. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  1927. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  1928. echo -e "${GREEN}9)${RESET} ${BOLD}all${RESET}"
  1929. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  1930. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1931. read -e -p "$(INFO "输入序号选择对应服务,${LIGHT_YELLOW}空格分隔${RESET}多个选项. ${LIGHT_CYAN}all选择所有${RESET} > ")" choices_service
  1932. if [[ "$choices_service" == "9" ]]; then
  1933. for service_name in "${services[@]}"; do
  1934. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  1935. selected_services+=("$service_name")
  1936. else
  1937. WARN "服务 ${service_name}未运行,跳过更新。"
  1938. fi
  1939. done
  1940. INFO "更新的服务: ${selected_services[*]}"
  1941. elif [[ "$choices_service" == "0" ]]; then
  1942. WARN "退出更新服务!"
  1943. exit 1
  1944. else
  1945. for choice in ${choices_service}; do
  1946. if [[ $choice =~ ^[0-9]+$ ]] && ((choice >0 && choice <= ${#services[@]})); then
  1947. service_name="${services[$((choice -1))]}"
  1948. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  1949. selected_services+=("$service_name")
  1950. else
  1951. WARN "服务 ${service_name} 未运行,跳过更新。"
  1952. fi
  1953. else
  1954. ERROR "无效的选择: $choice. 请重新${LIGHT_GREEN}选择0-9${RESET}的选项"
  1955. UPDATE_SERVICE # 选择无效重新调用当前函数进行选择
  1956. fi
  1957. done
  1958. INFO "更新的服务: ${selected_services[*]}"
  1959. fi
  1960. }
  1961. CONTAIENR_LOGS() {
  1962. CONTAINER_SERVICES
  1963. selected_services=()
  1964. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1965. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  1966. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  1967. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  1968. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  1969. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  1970. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  1971. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  1972. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  1973. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  1974. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  1975. read -e -p "$(INFO "输入序号选择对应服务,${LIGHT_YELLOW}空格分隔${RESET}多个选项. ${LIGHT_CYAN}all选择所有${RESET} > ")" restart_service
  1976. if [[ "$restart_service" == "0" ]]; then
  1977. WARN "退出查看容器服务日志操作!"
  1978. exit 1
  1979. else
  1980. for choice in ${restart_service}; do
  1981. if [[ $choice =~ ^[0-9]+$ ]] && ((choice >0 && choice <= ${#services[@]})); then
  1982. service_name="${services[$((choice -1))]}"
  1983. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  1984. selected_services+=("$service_name")
  1985. else
  1986. WARN "服务 ${service_name} 未运行,无法查看容器日志。"
  1987. fi
  1988. else
  1989. ERROR "无效的选择: $choice. 请重新${LIGHT_GREEN}选择0-8${RESET}的选项"
  1990. CONTAIENR_LOGS # 选择无效重新调用当前函数进行选择
  1991. fi
  1992. done
  1993. INFO "查看日志的服务: ${selected_services[*]}"
  1994. fi
  1995. }
  1996. MODIFY_SERVICE_CONFIG() {
  1997. selected_services=()
  1998. selected_files=()
  1999. existing_files=()
  2000. non_existing_files=()
  2001. files=(
  2002. "dockerhub registry-hub.yml"
  2003. "gcr registry-gcr.yml"
  2004. "ghcr registry-ghcr.yml"
  2005. "quay registry-quay.yml"
  2006. "k8sgcr registry-k8sgcr.yml"
  2007. "k8s registry-k8s.yml"
  2008. "mcr registry-mcr.yml"
  2009. "elastic registry-elastic.yml"
  2010. )
  2011. while true; do
  2012. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2013. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  2014. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  2015. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  2016. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  2017. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  2018. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  2019. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  2020. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  2021. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  2022. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2023. read -e -p "$(INFO "输入序号修改服务对应配置文件,${LIGHT_YELLOW}空格分隔${RESET}多个选项 > ")" ttl_service
  2024. if [[ "$ttl_service" == "0" ]]; then
  2025. WARN "退出修改容器服务配置操作!"
  2026. return
  2027. elif [[ "$ttl_service" =~ ^([1-8]+[[:space:]]*)+$ ]]; then
  2028. break
  2029. else
  2030. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2031. fi
  2032. done
  2033. for choice in ${ttl_service}; do
  2034. file_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f2)
  2035. service_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f1)
  2036. selected_files+=("$file_name")
  2037. if [ -f "${PROXY_DIR}/${file_name}" ]; then
  2038. existing_files+=("$file_name")
  2039. selected_services+=("$service_name")
  2040. else
  2041. non_existing_files+=("$file_name")
  2042. fi
  2043. if ! docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  2044. WARN "服务 ${service_name} 未运行。"
  2045. fi
  2046. done
  2047. if [ ${#existing_files[@]} -gt 0 ]; then
  2048. INFO "${GREEN}存在的配置文件:${RESET} ${existing_files[*]}${RESET}"
  2049. fi
  2050. if [ ${#non_existing_files[@]} -gt 0 ]; then
  2051. WARN "${RED}不存在的配置文件:${RESET} ${non_existing_files[*]}"
  2052. fi
  2053. if [ ${#existing_files[@]} -gt 0 ]; then
  2054. WARN "${LIGHT_GREEN}>>> 提示:${RESET} ${LIGHT_BLUE}Proxy代理缓存过期时间${RESET} ${MAGENTA}单位:ns、us、ms、s、m、h.默认ns,0禁用缓存过期${RESET}"
  2055. read -e -p "$(INFO "是否要修改缓存时间? ${PROMPT_YES_NO}")" modify_cache
  2056. while [[ "$modify_cache" != "y" && "$modify_cache" != "n" ]]; do
  2057. WARN "无效输入,请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}"
  2058. read -e -p "$(INFO "是否要修改缓存时间? ${PROMPT_YES_NO}")" modify_cache
  2059. done
  2060. if [[ "$modify_cache" == "y" ]]; then
  2061. while true; do
  2062. read -e -p "$(INFO "请输入新的缓存时间值: ")" new_ttl
  2063. for file_url in "${existing_files[@]}"; do
  2064. yml_name=$(basename "$file_url")
  2065. WARN "${YELLOW}正在修改配置文件: ${PROXY_DIR}/${yml_name}${RESET}"
  2066. sed -i "s/ttl: .*/ttl: ${new_ttl}/g" "${PROXY_DIR}/${yml_name}" &>/dev/null
  2067. INFO "${GREEN}配置文件 ${yml_name} 修改完成,代理缓存过期时间已设置为: ${new_ttl}${RESET}"
  2068. done
  2069. break
  2070. done
  2071. fi
  2072. else
  2073. WARN "未选择有效的配置文件进行修改。"
  2074. fi
  2075. }
  2076. SEPARATOR "服务管理"
  2077. echo -e "1) ${BOLD}${LIGHT_GREEN}重启${RESET}服务"
  2078. echo -e "2) ${BOLD}${LIGHT_CYAN}更新${RESET}服务"
  2079. echo -e "3) ${BOLD}${LIGHT_MAGENTA}查看${RESET}日志"
  2080. echo -e "4) ${BOLD}${LIGHT_BLUE}缓存${RESET}时效"
  2081. echo -e "5) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  2082. echo -e "0) ${BOLD}退出脚本${RESET}"
  2083. echo "---------------------------------------------------------------"
  2084. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" ser_choice
  2085. case $ser_choice in
  2086. 1)
  2087. RESTART_SERVICE
  2088. if [ ${#selected_services[@]} -eq 0 ]; then
  2089. ERROR "没有需要重启的服务,请重新选择"
  2090. RESTART_SERVICE
  2091. else
  2092. docker-compose stop ${selected_services[*]}
  2093. docker-compose up -d --force-recreate ${selected_services[*]}
  2094. fi
  2095. SVC_MGMT
  2096. ;;
  2097. 2)
  2098. UPDATE_SERVICE
  2099. if [ ${#selected_services[@]} -eq 0 ]; then
  2100. ERROR "没有需要更新的服务,请重新选择"
  2101. UPDATE_SERVICE
  2102. else
  2103. docker-compose pull ${selected_services[*]}
  2104. docker-compose up -d --force-recreate ${selected_services[*]}
  2105. fi
  2106. SVC_MGMT
  2107. ;;
  2108. 3)
  2109. CONTAIENR_LOGS
  2110. if [ ${#selected_services[@]} -eq 0 ]; then
  2111. ERROR "没有需要查看的服务,请重新选择"
  2112. CONTAIENR_LOGS
  2113. else
  2114. # 查看最近30条日志
  2115. docker-compose logs --tail=30 ${selected_services[*]}
  2116. fi
  2117. SVC_MGMT
  2118. ;;
  2119. 4)
  2120. MODIFY_SERVICE_CONFIG
  2121. if [ ${#selected_services[@]} -eq 0 ]; then
  2122. ERROR "修改的服务未运行,请重新选择"
  2123. MODIFY_SERVICE_CONFIG
  2124. else
  2125. docker-compose restart ${selected_services[*]}
  2126. fi
  2127. SVC_MGMT
  2128. ;;
  2129. 5)
  2130. main_menu
  2131. ;;
  2132. 0)
  2133. exit 1
  2134. ;;
  2135. *)
  2136. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-5${RESET}的选项."
  2137. SVC_MGMT
  2138. ;;
  2139. esac
  2140. }
  2141. function ADD_SYS_CMD() {
  2142. MAX_ATTEMPTS=3
  2143. attempt=0
  2144. success=false
  2145. TARGET_PATH="/usr/bin/hub"
  2146. INSTALL_ENV() {
  2147. while true; do
  2148. read -e -p "$(INFO "安装环境确认 [${LIGHT_GREEN}国外输1${RESET} ${LIGHT_YELLOW}国内输2${RESET}] > ")" sys_cmd
  2149. case "$sys_cmd" in
  2150. 1 )
  2151. DOWNLOAD_URL="https://raw.githubusercontent.com/dqzboy/Docker-Proxy/main/install/DockerProxy_Install.sh"
  2152. break;;
  2153. 2 )
  2154. DOWNLOAD_URL="https://cdn.jsdelivr.net/gh/dqzboy/Docker-Proxy/install/DockerProxy_Install.sh"
  2155. break;;
  2156. * )
  2157. INFO "请输入 ${LIGHT_GREEN}1${RESET} 表示国外 或者 ${LIGHT_YELLOW}2${RESET} 表示大陆";;
  2158. esac
  2159. done
  2160. }
  2161. INSTALL_OR_UPDATE_CMD() {
  2162. local action=$1
  2163. while [[ $attempt -lt $MAX_ATTEMPTS ]]; do
  2164. attempt=$((attempt + 1))
  2165. if [[ "$action" == "安装" ]]; then
  2166. if command -v hub &> /dev/null; then
  2167. INFO "系统命令已存在,无需安装。"
  2168. success=true
  2169. break
  2170. fi
  2171. WARN "正在安装脚本中,请稍等..."
  2172. else
  2173. WARN "正在进行脚本更新,请稍等..."
  2174. fi
  2175. wget -q -O "$TARGET_PATH" "$DOWNLOAD_URL" &>/dev/null
  2176. if [ $? -eq 0 ]; then
  2177. success=true
  2178. chmod +x "$TARGET_PATH"
  2179. break
  2180. fi
  2181. ERROR "${action}脚本${RED}失败${RESET},正在尝试重新${action} (尝试次数: $attempt)"
  2182. done
  2183. if $success; then
  2184. INFO "${action}脚本${GREEN}成功${RESET},命令行输入 ${LIGHT_GREEN}hub${RESET} 运行"
  2185. else
  2186. ERROR "设置系统命令失败"
  2187. exit 1
  2188. fi
  2189. }
  2190. SEPARATOR "设置脚本为系统命令"
  2191. echo -e "1) ${BOLD}安装${LIGHT_GREEN}系统命令${RESET}"
  2192. echo -e "2) ${BOLD}更新${LIGHT_CYAN}系统命令${RESET}"
  2193. echo -e "3) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  2194. echo -e "0) ${BOLD}退出脚本${RESET}"
  2195. echo "---------------------------------------------------------------"
  2196. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" cmd_choice
  2197. case $cmd_choice in
  2198. 1)
  2199. INSTALL_ENV
  2200. INSTALL_OR_UPDATE_CMD "安装"
  2201. ;;
  2202. 2)
  2203. INSTALL_ENV
  2204. INSTALL_OR_UPDATE_CMD "更新"
  2205. ;;
  2206. 3)
  2207. main_menu
  2208. ;;
  2209. 0)
  2210. exit 1
  2211. ;;
  2212. *)
  2213. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-3${RESET}的选项."
  2214. ADD_SYS_CMD
  2215. ;;
  2216. esac
  2217. }
  2218. function UNI_DOCKER_SERVICE() {
  2219. RM_SERVICE() {
  2220. selected_containers=()
  2221. files=(
  2222. "dockerhub registry-hub.yml"
  2223. "gcr registry-gcr.yml"
  2224. "ghcr registry-ghcr.yml"
  2225. "quay registry-quay.yml"
  2226. "k8sgcr registry-k8sgcr.yml"
  2227. "k8s registry-k8s.yml"
  2228. "mcr registry-mcr.yml"
  2229. "elastic registry-elastic.yml"
  2230. )
  2231. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2232. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  2233. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  2234. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  2235. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  2236. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  2237. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  2238. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  2239. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  2240. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  2241. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2242. read -e -p "$(INFO "输入序号删除服务和对应配置文件,${LIGHT_YELLOW}空格分隔${RESET}多个选项 > ")" rm_service
  2243. while [[ ! "$rm_service" =~ ^([0-8]+[[:space:]]*)+$ ]]; do
  2244. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2245. read -e -p "$(INFO "输入序号删除服务和对应配置文件,${LIGHT_YELLOW}空格分隔${RESET}多个选项 > ")" rm_service
  2246. done
  2247. if [[ "$rm_service" == "0" ]]; then
  2248. WARN "退出删除容器服务操作!"
  2249. return
  2250. else
  2251. selected_services=()
  2252. for choice in ${rm_service}; do
  2253. if [[ $choice =~ ^[0-8]+$ ]] && ((choice > 0 && choice <= ${#files[@]})); then
  2254. file_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f2)
  2255. service_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f1)
  2256. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  2257. selected_services+=("$service_name")
  2258. else
  2259. WARN "服务 ${LIGHT_MAGENTA}${service_name} 未运行${RESET},但将尝试删除相关文件。"
  2260. fi
  2261. if [ -f "${PROXY_DIR}/${file_name}" ]; then
  2262. rm -f "${PROXY_DIR}/${file_name}"
  2263. INFO "配置文件 ${LIGHT_CYAN}${file_name}${RESET} ${LIGHT_GREEN}已被删除${RESET}"
  2264. else
  2265. WARN "配置文件 ${LIGHT_CYAN}${file_name}${RESET} 不存在,${LIGHT_YELLOW}无需删除${RESET}"
  2266. fi
  2267. else
  2268. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2269. UNI_DOCKER_SERVICE
  2270. return
  2271. fi
  2272. done
  2273. # 一次性删除所有选中的服务
  2274. if [ ${#selected_services[@]} -gt 0 ]; then
  2275. INFO "删除的服务: ${LIGHT_RED}${selected_services[*]}${RESET}"
  2276. docker-compose down ${selected_services[*]}
  2277. fi
  2278. fi
  2279. }
  2280. RM_ALLSERVICE() {
  2281. STOP_REMOVE_CONTAINER
  2282. REMOVE_NONE_TAG
  2283. REMOVE_CMDUI
  2284. docker rmi --force $(docker images -q ${IMAGE_NAME}) &>/dev/null
  2285. docker rmi --force $(docker images -q ${UI_IMAGE_NAME}) &>/dev/null
  2286. if [ -d "${PROXY_DIR}" ]; then
  2287. rm -rf "${PROXY_DIR}" &>/dev/null
  2288. fi
  2289. if [ -f "/usr/bin/hub" ]; then
  2290. rm -f /usr/bin/hub &>/dev/null
  2291. fi
  2292. INFO "${LIGHT_YELLOW}感谢您的使用,Docker-Proxy服务已卸载。欢迎您再次使用!${RESET}"
  2293. SEPARATOR "DONE"
  2294. }
  2295. CONFIREM_ACTION() {
  2296. local action_name=$1
  2297. local action_function=$2
  2298. WARN "${LIGHT_RED}注意:${RESET} ${LIGHT_YELLOW}卸载服务会一同将本地的配置和对应服务删除,请执行删除之前确定是否需要备份本地的配置文件${RESET}"
  2299. while true; do
  2300. read -e -p "$(INFO "本人${LIGHT_RED}已知晓后果,确认${action_name}${RESET}服务? ${PROMPT_YES_NO}")" uniservice
  2301. case "$uniservice" in
  2302. y|Y )
  2303. $action_function
  2304. break;;
  2305. n|N )
  2306. WARN "退出${action_name}服务."
  2307. break;;
  2308. * )
  2309. INFO "请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}";;
  2310. esac
  2311. done
  2312. }
  2313. SEPARATOR "卸载服务"
  2314. echo -e "1) ${BOLD}卸载${LIGHT_YELLOW}所有服务${RESET}"
  2315. echo -e "2) ${BOLD}删除${LIGHT_CYAN}指定服务${RESET}"
  2316. echo -e "3) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  2317. echo -e "0) ${BOLD}退出脚本${RESET}"
  2318. echo "---------------------------------------------------------------"
  2319. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" rm_choice
  2320. case $rm_choice in
  2321. 1)
  2322. CONFIREM_ACTION "卸载所有" RM_ALLSERVICE
  2323. ;;
  2324. 2)
  2325. CONFIREM_ACTION "删除指定" RM_SERVICE
  2326. UNI_DOCKER_SERVICE
  2327. ;;
  2328. 3)
  2329. main_menu
  2330. ;;
  2331. 0)
  2332. exit 1
  2333. ;;
  2334. *)
  2335. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-3${RESET}的选项."
  2336. UNI_DOCKER_SERVICE
  2337. ;;
  2338. esac
  2339. }
  2340. function AUTH_SERVICE_CONFIG() {
  2341. CHECK_REG_AUTH() {
  2342. if ! command -v docker &> /dev/null; then
  2343. ERROR "docker 命令未找到,请确保 Docker 已正确安装"
  2344. AUTH_SERVICE_CONFIG
  2345. fi
  2346. declare -A services
  2347. services=(
  2348. ["reg-docker-hub"]="dockerhub"
  2349. ["reg-gcr"]="gcr"
  2350. ["reg-ghcr"]="ghcr"
  2351. ["reg-quay"]="quay"
  2352. ["reg-k8s-gcr"]="k8sgcr"
  2353. ["reg-k8s"]="k8s"
  2354. ["reg-mcr"]="mcr"
  2355. ["reg-elastic"]="elastic"
  2356. )
  2357. container_names=$(docker ps --filter "name=reg-" --filter "status=running" --format "{{.Names}}")
  2358. auth_containers=()
  2359. for container_name in $container_names; do
  2360. specified_name=${services[$container_name]}
  2361. if [ -z "$specified_name" ]; then
  2362. specified_name=$container_name
  2363. fi
  2364. if docker exec $container_name grep -q "auth" /etc/distribution/config.yml; then
  2365. auth_containers+=("$specified_name")
  2366. fi
  2367. done
  2368. if [ ${#auth_containers[@]} -gt 0 ]; then
  2369. INFO "当前运行的 Docker 容器中${LIGHT_GREEN}包含认证${RESET}的容器有: ${LIGHT_CYAN}${auth_containers[*]}${RESET}"
  2370. else
  2371. WARN "当前运行的 Docker 容器中${LIGHT_YELLOW}没有包含认证${RESET}的容器"
  2372. fi
  2373. }
  2374. AUTH_MENU() {
  2375. CHECK_REG_AUTH
  2376. selected_files=()
  2377. selected_services=()
  2378. files=(
  2379. "dockerhub registry-hub.yml"
  2380. "gcr registry-gcr.yml"
  2381. "ghcr registry-ghcr.yml"
  2382. "quay registry-quay.yml"
  2383. "k8sgcr registry-k8sgcr.yml"
  2384. "k8s registry-k8s.yml"
  2385. "mcr registry-mcr.yml"
  2386. "elastic registry-elastic.yml"
  2387. )
  2388. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2389. echo -e "${GREEN}1)${RESET} ${BOLD}docker hub${RESET}"
  2390. echo -e "${GREEN}2)${RESET} ${BOLD}gcr${RESET}"
  2391. echo -e "${GREEN}3)${RESET} ${BOLD}ghcr${RESET}"
  2392. echo -e "${GREEN}4)${RESET} ${BOLD}quay${RESET}"
  2393. echo -e "${GREEN}5)${RESET} ${BOLD}k8s-gcr${RESET}"
  2394. echo -e "${GREEN}6)${RESET} ${BOLD}k8s${RESET}"
  2395. echo -e "${GREEN}7)${RESET} ${BOLD}mcr${RESET}"
  2396. echo -e "${GREEN}8)${RESET} ${BOLD}elastic${RESET}"
  2397. echo -e "${GREEN}0)${RESET} ${BOLD}exit${RESET}"
  2398. echo -e "${YELLOW}-------------------------------------------------${RESET}"
  2399. read -e -p "$(INFO "输入序号选择添加认证的服务,${LIGHT_YELLOW}空格分隔${RESET}多个选项 > ")" auth_service
  2400. while [[ ! "$auth_service" =~ ^([0-8]+[[:space:]]*)+$ ]]; do
  2401. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2402. read -e -p "$(INFO "输入序号选择添加认证的服务,${LIGHT_YELLOW}空格分隔${RESET}多个选项 > ")" auth_service
  2403. done
  2404. }
  2405. ADD_AUTH_CONFIG() {
  2406. local FILE=$1
  2407. local auth_config="
  2408. auth:
  2409. htpasswd:
  2410. realm: basic-realm
  2411. path: /auth/htpasswd"
  2412. if [ ! -f "$FILE" ]; then
  2413. ERROR "配置文件 ${LIGHT_BLUE}$FILE${RESET} 不存在"
  2414. exit 1
  2415. else
  2416. if ! grep -q "auth:" "$FILE" || ! grep -q "htpasswd:" "$FILE" || ! grep -q "realm: basic-realm" "$FILE" || ! grep -q "path: /auth/htpasswd" "$FILE"; then
  2417. echo -e "$auth_config" | sudo tee -a "$FILE" > /dev/null
  2418. INFO "配置文件 ${LIGHT_BLUE}$FILE${RESET} 添加认证配置成功"
  2419. else
  2420. WARN "配置文件 ${LIGHT_BLUE}$FILE${RESET} 已添加认证配置"
  2421. fi
  2422. fi
  2423. }
  2424. ADD_AUTH_COMPOSE() {
  2425. local SERVICES=$1
  2426. local FILE=${DOCKER_COMPOSE_FILE}
  2427. local HTPASSWD_CONFIG=" - ./${SERVICES}_htpasswd:/auth/htpasswd"
  2428. if [ ! -f "$FILE" ]; then
  2429. ERROR "配置文件 ${LIGHT_BLUE}$FILE${RESET} 不存在"
  2430. exit 1
  2431. fi
  2432. for SERVICE in "${SERVICES[@]}"; do
  2433. if grep -q " $SERVICE:" "$FILE"; then
  2434. if ! grep -A10 " $SERVICE:" "$FILE" | grep -q " - ./${SERVICES}_htpasswd:/auth/htpasswd"; then
  2435. sed -i "/ $SERVICE:/,/volumes:/ {
  2436. /volumes:/a\\
  2437. $HTPASSWD_CONFIG
  2438. }" "$FILE"
  2439. INFO "Htpasswd配置添加到 ${LIGHT_GREEN}$SERVICE${RESET} 服务中"
  2440. else
  2441. WARN "Htpasswd配置已存在 ${LIGHT_YELLOW}$SERVICE${RESET} 服务中"
  2442. fi
  2443. else
  2444. ERROR "服务 $SERVICE 在 $FILE 中不存在"
  2445. fi
  2446. done
  2447. }
  2448. DEL_AUTH_CONFIG() {
  2449. local FILE=$1
  2450. if [ ! -f "$FILE" ]; then
  2451. ERROR "配置文件 $FILE 不存在"
  2452. else
  2453. if grep -q "auth:" "$FILE"; then
  2454. sed -i '/^auth:$/,/^[^[:space:]]/d' "$FILE" >/dev/null
  2455. INFO "配置文件 ${LIGHT_BLUE}$FILE${RESET} 成功移除认证信息"
  2456. else
  2457. WARN "配置文件 ${LIGHT_BLUE}$FILE${RESET} 不存在认证信息"
  2458. fi
  2459. fi
  2460. }
  2461. DEL_AUTH_COMPOSE() {
  2462. local SERVICES=$1
  2463. local FILE=${DOCKER_COMPOSE_FILE}
  2464. if [ ! -f "$FILE" ]; then
  2465. ERROR "$File 不存在"
  2466. exit 1
  2467. fi
  2468. for SERVICE in "${SERVICES[@]}"; do
  2469. if grep -q " $SERVICE:" "$FILE"; then
  2470. sed -i "/ $SERVICE:/,/^[^[:space:]]/ {/^[[:space:]]*- .\/${SERVICES}_htpasswd:\/auth\/htpasswd/d}" "$FILE"
  2471. else
  2472. ERROR "$FILE 中不存在服务 $SERVICE"
  2473. fi
  2474. done
  2475. }
  2476. ENABLE_AUTH() {
  2477. AUTH_MENU
  2478. if [[ "$auth_service" == "0" ]]; then
  2479. WARN "退出添加容器认证操作!"
  2480. return
  2481. else
  2482. for choice in ${auth_service}; do
  2483. if [[ $choice =~ ^[0-8]+$ ]] && ((choice > 0 && choice <= ${#files[@]})); then
  2484. file_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f2)
  2485. service_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f1)
  2486. selected_files+=("$file_name")
  2487. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  2488. selected_services+=("$service_name")
  2489. else
  2490. WARN "服务 ${LIGHT_MAGENTA}${service_name} 未运行${RESET},无法添加认证授权"
  2491. fi
  2492. else
  2493. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2494. AUTH_MENU
  2495. return
  2496. fi
  2497. done
  2498. WARN "${LIGHT_GREEN}>>> 提示:${RESET} ${LIGHT_CYAN}配置认证后,执行镜像拉取需先通过 docker login登入后使用.访问UI需输入账号密码${RESET}"
  2499. read -e -p "$(INFO "是否需要配置镜像仓库访问账号和密码? ${PROMPT_YES_NO}")" enable_auth
  2500. while [[ "$enable_auth" != "y" && "$enable_auth" != "n" ]]; do
  2501. WARN "无效输入,请输入 ${LIGHT_GREEN}y${RESET} 或 ${LIGHT_YELLOW}n${RESET}"
  2502. read -e -p "$(INFO "是否需要配置镜像仓库访问账号和密码? ${PROMPT_YES_NO}")" enable_auth
  2503. done
  2504. if [[ "$enable_auth" == "y" ]]; then
  2505. while true; do
  2506. read -e -p "$(INFO "请输入账号名称: ")" username
  2507. if [[ -z "$username" ]]; then
  2508. ERROR "用户名不能为空。请重新输入"
  2509. else
  2510. break
  2511. fi
  2512. done
  2513. while true; do
  2514. read -e -p "$(INFO "请输入账号密码: ")" password
  2515. if [[ -z "$password" ]]; then
  2516. ERROR "密码不能为空。请重新输入"
  2517. else
  2518. break
  2519. fi
  2520. done
  2521. for file_url in "${selected_files[@]}"; do
  2522. yml_name=$(basename "$file_url")
  2523. ADD_AUTH_CONFIG "${PROXY_DIR}/${yml_name}"
  2524. done
  2525. for server in "${selected_services[@]}"; do
  2526. htpasswd -Bbc ${PROXY_DIR}/${server}_htpasswd "$username" "$password" 2>/dev/null
  2527. ADD_AUTH_COMPOSE "${server}"
  2528. done
  2529. fi
  2530. fi
  2531. }
  2532. DELETE_AUTH() {
  2533. AUTH_MENU
  2534. if [[ "$auth_service" == "0" ]]; then
  2535. WARN "退出移除容器认证操作!"
  2536. return
  2537. else
  2538. for choice in ${auth_service}; do
  2539. if [[ $choice =~ ^[0-8]+$ ]] && ((choice > 0 && choice <= ${#files[@]})); then
  2540. file_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f2)
  2541. service_name=$(echo "${files[$((choice - 1))]}" | cut -d' ' -f1)
  2542. selected_files+=("$file_name")
  2543. if docker-compose ps --services 2>/dev/null | grep -q "^${service_name}$"; then
  2544. selected_services+=("$service_name")
  2545. else
  2546. WARN "服务 ${LIGHT_MAGENTA}${service_name} 未运行${RESET},无法添加认证授权"
  2547. fi
  2548. else
  2549. WARN "无效输入,请重新输入${LIGHT_YELLOW} 0-8 ${RESET}序号"
  2550. AUTH_MENU
  2551. return
  2552. fi
  2553. done
  2554. for file_url in "${selected_files[@]}"; do
  2555. yml_name=$(basename "$file_url")
  2556. DEL_AUTH_CONFIG "${PROXY_DIR}/${yml_name}"
  2557. done
  2558. for server in "${selected_services[@]}"; do
  2559. DEL_AUTH_COMPOSE "${server}"
  2560. rm -f ${PROXY_DIR}/${server}_htpasswd
  2561. done
  2562. fi
  2563. }
  2564. SEPARATOR "认证授权"
  2565. echo -e "1) ${BOLD}${LIGHT_YELLOW}添加${RESET}认证"
  2566. echo -e "2) ${BOLD}${LIGHT_CYAN}删除${RESET}认证"
  2567. echo -e "3) ${BOLD}返回${LIGHT_RED}主菜单${RESET}"
  2568. echo -e "0) ${BOLD}退出脚本${RESET}"
  2569. echo "---------------------------------------------------------------"
  2570. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" auth_choice
  2571. case $auth_choice in
  2572. 1)
  2573. ENABLE_AUTH
  2574. if [ ${#selected_services[@]} -eq 0 ]; then
  2575. WARN "没有运行任何选择的服务,请${LIGHT_CYAN}重新选择运行${RESET}的服务"
  2576. AUTH_SERVICE_CONFIG # 没有服务运行调用函数
  2577. else
  2578. docker-compose down ${selected_services[*]}
  2579. docker-compose up -d --force-recreate ${selected_services[*]}
  2580. fi
  2581. AUTH_SERVICE_CONFIG
  2582. ;;
  2583. 2)
  2584. DELETE_AUTH
  2585. if [ ${#selected_services[@]} -eq 0 ]; then
  2586. WARN "没有运行任何选择的服务,请${LIGHT_CYAN}重新选择运行${RESET}的服务"
  2587. AUTH_SERVICE_CONFIG # 没有服务运行调用函数
  2588. else
  2589. docker-compose down ${selected_services[*]}
  2590. docker-compose up -d --force-recreate ${selected_services[*]}
  2591. fi
  2592. AUTH_SERVICE_CONFIG
  2593. ;;
  2594. 3)
  2595. main_menu
  2596. ;;
  2597. 0)
  2598. exit 1
  2599. ;;
  2600. *)
  2601. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-3${RESET}的选项."
  2602. AUTH_SERVICE_CONFIG
  2603. ;;
  2604. esac
  2605. }
  2606. ## 主菜单
  2607. function main_menu() {
  2608. echo -e "╔════════════════════════════════════════════════════╗"
  2609. echo -e "║ ║"
  2610. echo -e "║ ${LIGHT_CYAN}欢迎使用Docker-Proxy${RESET} ║"
  2611. echo -e "║ ║"
  2612. echo -e "║ TG频道: ${UNDERLINE}https://t.me/dqzboyblog${RESET} ║"
  2613. echo -e "║ ║"
  2614. echo -e "║ ${LIGHT_BLUE}by dqzboy${RESET} ║"
  2615. echo -e "║ ║"
  2616. echo -e "╚════════════════════════════════════════════════════╝"
  2617. echo
  2618. SEPARATOR "请选择操作"
  2619. echo -e "1) ${BOLD}${LIGHT_GREEN}安装${RESET}服务"
  2620. echo -e "2) ${BOLD}${LIGHT_MAGENTA}组件${RESET}安装"
  2621. echo -e "3) ${BOLD}${LIGHT_YELLOW}管理${RESET}服务"
  2622. echo -e "4) ${BOLD}${LIGHT_CYAN}更新${RESET}配置"
  2623. echo -e "5) ${BOLD}${LIGHT_RED}卸载${RESET}服务"
  2624. echo -e "6) ${BOLD}${LIGHT_BLUE}认证${RESET}授权"
  2625. echo -e "7) 本机${BOLD}${CYAN}Docker代理${RESET}"
  2626. echo -e "8) 设置成${BOLD}${YELLOW}系统命令${RESET}"
  2627. echo -e "0) ${BOLD}退出脚本${RESET}"
  2628. echo "---------------------------------------------------------------"
  2629. read -e -p "$(INFO "输入${LIGHT_CYAN}对应数字${RESET}并按${LIGHT_GREEN}Enter${RESET}键 > ")" main_choice
  2630. case $main_choice in
  2631. 1)
  2632. INSTALL_PROXY
  2633. ;;
  2634. 2)
  2635. COMP_INST
  2636. ;;
  2637. 3)
  2638. SVC_MGMT
  2639. ;;
  2640. 4)
  2641. SEPARATOR "更新配置"
  2642. UPDATE_CONFIG
  2643. SEPARATOR "更新完成"
  2644. ;;
  2645. 5)
  2646. UNI_DOCKER_SERVICE
  2647. ;;
  2648. 6)
  2649. AUTH_SERVICE_CONFIG
  2650. ;;
  2651. 7)
  2652. SEPARATOR "配置本机Docker代理"
  2653. DOCKER_PROXY_HTTP
  2654. ADD_DOCKERD_PROXY
  2655. SEPARATOR "Docker代理配置完成"
  2656. ;;
  2657. 8)
  2658. ADD_SYS_CMD
  2659. ;;
  2660. 0)
  2661. exit 1
  2662. ;;
  2663. *)
  2664. WARN "输入了无效的选择。请重新${LIGHT_GREEN}选择0-7${RESET}的选项."
  2665. sleep 2; main_menu
  2666. ;;
  2667. esac
  2668. }
  2669. main_menu