DockerProxy_Install.sh 96 KB

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