Zuletzt aktiv 1 month ago

πŸš€ Автоматизирано ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° Π·Π°Ρ‰ΠΈΡ‚Π΅Π½ хостинг с Cloudflare Tunnel & Docker ΠΈ Wordpress сайтовС

urocibg hat die Gist bearbeitet 1 month ago. Zu Γ„nderung gehen

1 file changed, 158 insertions, 98 deletions

setup_hosting.sh

@@ -16,12 +16,9 @@ success() { echo -e "${GREEN}[OK] $*${RESET}"; }
16 16 warn() { echo -e "${YELLOW}[WARN] $*${RESET}"; }
17 17 error() { echo -e "${RED}[ERROR] $*${RESET}" >&2; exit 1; }
18 18
19 - # -- Password generator -------------------------------------------------------
20 19 gen_pass() {
21 20 openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 24
22 21 }
23 -
24 - # -- Input validation ---------------------------------------------------------
25 22 validate_yn() {
26 23 [[ "$1" =~ ^[yYnN]$ ]] || error "Vuvedete 'y' ili 'n'."
27 24 }
@@ -29,84 +26,144 @@ validate_count() {
29 26 [[ "$1" =~ ^[0-2]$ ]] || error "Vuvedete 0, 1 ili 2."
30 27 }
31 28
29 + # -- Create DB user directly in running MariaDB -------------------------------
30 + create_db_user() {
31 + local db_name="$1"
32 + local db_user="$2"
33 + local db_pass="$3"
34 + local root_pass="$4"
35 + local db_container="$5"
36 +
37 + info "Creating database '$db_name' and user '$db_user' ..."
38 + docker exec "$db_container" mariadb -u root -p"${root_pass}" -e "
39 + CREATE DATABASE IF NOT EXISTS ${db_name} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
40 + CREATE USER IF NOT EXISTS '${db_user}'@'%' IDENTIFIED BY '${db_pass}';
41 + GRANT ALL PRIVILEGES ON ${db_name}.* TO '${db_user}'@'%';
42 + FLUSH PRIVILEGES;
43 + " && success "Database '$db_name' ready." || error "Failed to create database '$db_name'."
44 + }
45 +
46 + # -- Find running container by partial name -----------------------------------
47 + find_container() {
48 + docker ps --format '{{.Names}}' 2>/dev/null | grep "$1" | head -1
49 + }
50 +
51 + # =============================================================================
52 + # Detect already running containers
53 + # =============================================================================
54 + CF_CONTAINER=$(find_container "cloudflared")
55 + KUMA_CONTAINER=$(find_container "uptime-kuma")
56 + WP1_CONTAINER=$(find_container "wp1")
57 + WP2_CONTAINER=$(find_container "wp2")
58 + DB_CONTAINER=$(find_container "db")
59 +
60 + HAVE_CF=false; [[ -n "$CF_CONTAINER" ]] && HAVE_CF=true
61 + HAVE_KUMA=false; [[ -n "$KUMA_CONTAINER" ]] && HAVE_KUMA=true
62 + HAVE_WP1=false; [[ -n "$WP1_CONTAINER" ]] && HAVE_WP1=true
63 + HAVE_WP2=false; [[ -n "$WP2_CONTAINER" ]] && HAVE_WP2=true
64 + HAVE_DB=false; [[ -n "$DB_CONTAINER" ]] && HAVE_DB=true
65 +
66 + SERVER_IP=$(hostname -I | awk '{print $1}')
67 +
32 68 # =============================================================================
33 69 echo -e "\n${BOLD}================================================${RESET}"
34 70 echo -e "${BOLD} Modular Hosting Setup - Izberete moduli ${RESET}"
35 71 echo -e "${BOLD}================================================${RESET}\n"
36 72
73 + echo -e "${BOLD}Tekushto sastoyanie:${RESET}"
74 + $HAVE_CF && echo -e " ${GREEN}[running]${RESET} Cloudflare Tunnel" || echo -e " ${YELLOW}[not installed]${RESET} Cloudflare Tunnel"
75 + $HAVE_KUMA && echo -e " ${GREEN}[running]${RESET} Uptime Kuma" || echo -e " ${YELLOW}[not installed]${RESET} Uptime Kuma"
76 + $HAVE_WP1 && echo -e " ${GREEN}[running]${RESET} WordPress 1" || echo -e " ${YELLOW}[not installed]${RESET} WordPress 1"
77 + $HAVE_WP2 && echo -e " ${GREEN}[running]${RESET} WordPress 2" || echo -e " ${YELLOW}[not installed]${RESET} WordPress 2"
78 + echo ""
79 +
37 80 # =============================================================================
38 - # [1/4] Module selection
81 + # [1/4] What to ADD
39 82 # =============================================================================
40 - echo -e "${BOLD}[1/4] Izberete koi moduli da se instalΠΈΡ€Π°Ρ‚:${RESET}\n"
83 + echo -e "${BOLD}[1/4] Koe iskate da DOBAVITE:${RESET}\n"
41 84
42 - read -rp " Instaliraj Cloudflare Tunnel? (y/n): " install_cf
43 - validate_yn "$install_cf"; install_cf="${install_cf,,}"
85 + ADD_CF="n"; ADD_KUMA="n"; ADD_WP1=false; ADD_WP2=false
44 86
45 - read -rp " Instaliraj Uptime Kuma? (y/n): " install_kuma
46 - validate_yn "$install_kuma"; install_kuma="${install_kuma,,}"
87 + if $HAVE_CF; then
88 + info "Cloudflare Tunnel - veche e instaliran, preskachame."
89 + else
90 + read -rp " Instaliraj Cloudflare Tunnel? (y/n): " ADD_CF
91 + validate_yn "$ADD_CF"; ADD_CF="${ADD_CF,,}"
92 + fi
47 93
48 - read -rp " Broy WordPress sajtove? (0/1/2): " wp_count
49 - validate_count "$wp_count"
94 + if $HAVE_KUMA; then
95 + info "Uptime Kuma - veche e instaliran, preskachame."
96 + else
97 + read -rp " Instaliraj Uptime Kuma? (y/n): " ADD_KUMA
98 + validate_yn "$ADD_KUMA"; ADD_KUMA="${ADD_KUMA,,}"
99 + fi
50 100
51 - # At least one module must be selected
52 - if [[ "$install_cf" == "n" && "$install_kuma" == "n" && "$wp_count" == "0" ]]; then
53 - error "Tryabva da izberete poΠ½Π΅ edin modul."
101 + if $HAVE_WP1 && $HAVE_WP2; then
102 + info "I dvata WordPress sajta veche sa instalΠΈrani, preskachame."
103 + elif $HAVE_WP1 && ! $HAVE_WP2; then
104 + info "WordPress 1 veche e instaliran."
105 + read -rp " Dobavi WordPress 2? (y/n): " _add2
106 + validate_yn "$_add2"
107 + [[ "${_add2,,}" == "y" ]] && ADD_WP2=true
108 + elif ! $HAVE_WP1 && ! $HAVE_WP2; then
109 + read -rp " Broy WordPress sajtove? (0/1/2): " _wpc
110 + validate_count "$_wpc"
111 + [[ "$_wpc" -ge 1 ]] && ADD_WP1=true
112 + [[ "$_wpc" -ge 2 ]] && ADD_WP2=true
54 113 fi
55 114
56 - # DB is needed only when WordPress is requested
57 - need_db="n"
58 - [[ "$wp_count" -ge 1 ]] && need_db="y"
115 + # Nothing new?
116 + if [[ "$ADD_CF" == "n" && "$ADD_KUMA" == "n" ]] && ! $ADD_WP1 && ! $ADD_WP2; then
117 + warn "Nyama nishto novo za dobavyane. Izlizame."
118 + exit 0
119 + fi
59 120
60 121 # =============================================================================
61 - # [2/4] Cloudflare Tunnel config (only if selected)
122 + # [2/4] Cloudflare config
62 123 # =============================================================================
63 124 CLOUDFLARED_CMD=""
64 125 CF_ENV_LINE=""
65 126 CF_TOKEN_IN_ENV="# Cloudflare Tunnel not installed"
66 127 cf_method=""
67 128
68 - if [[ "$install_cf" == "y" ]]; then
69 - echo -e "\n${BOLD}[2/4] Cloudflare Tunnel - metod na svarzavane${RESET}"
70 - echo " 1) Token - vuvedash gotov token ot Cloudflare Dashboard"
71 - echo " 2) Login - cloudflared se logva sam (URL / brauzar)"
129 + if [[ "$ADD_CF" == "y" ]]; then
130 + echo -e "\n${BOLD}[2/4] Cloudflare Tunnel - metod${RESET}"
131 + echo " 1) Token - gotov token ot Cloudflare Dashboard"
132 + echo " 2) Login - cloudflared se logva sam (URL)"
72 133 echo ""
73 134 read -rp " Izberi metod [1/2]: " cf_method
74 -
75 135 case "$cf_method" in
76 136 1)
77 - read -rp " Vuvedete Tunnel Token: " cf_token
137 + read -rp " Tunnel Token: " cf_token
78 138 [[ -n "$cf_token" ]] || error "Tokenat ne mozhe da e prazen."
79 139 CLOUDFLARED_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
80 140 CF_ENV_LINE=" - TUNNEL_TOKEN=\${TUNNEL_TOKEN}"
81 141 CF_TOKEN_IN_ENV="TUNNEL_TOKEN=$cf_token"
82 142 ;;
83 143 2)
84 - info "cloudflared shte izvede URL za avtentikaciya pri start."
85 144 CLOUDFLARED_CMD='tunnel --no-autoupdate login'
86 - CF_ENV_LINE=""
87 - CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (login method - not needed)"
145 + CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (login method)"
88 146 cf_token=""
89 147 ;;
90 - *)
91 - error "NevaliΠ΄Π΅Π½ izbor. Vuvedete 1 ili 2."
92 - ;;
148 + *) error "Nevaliden izbor." ;;
93 149 esac
94 - else
95 - info "Cloudflare Tunnel - skipped."
96 150 fi
97 151
98 152 # =============================================================================
99 - # [3/4] Generate passwords
153 + # [3/4] Passwords β€” keep existing, generate only what is missing
100 154 # =============================================================================
101 - echo -e "\n${BOLD}[3/4] Generirane na paroli...${RESET}"
102 - DB_ROOT_PASS=$(gen_pass)
103 - WP1_DB_PASS=$(gen_pass)
104 - WP2_DB_PASS=$(gen_pass)
155 + echo -e "\n${BOLD}[3/4] Paroli...${RESET}"
156 +
157 + [[ -f .env ]] && set -a && source .env 2>/dev/null && set +a || true
158 +
159 + DB_ROOT_PASS="${DB_ROOT_PASSWORD:-$(gen_pass)}"
160 + WP1_DB_PASS="${WP1_DB_PASSWORD:-$(gen_pass)}"
161 + WP2_DB_PASS="${WP2_DB_PASSWORD:-$(gen_pass)}"
105 162
106 163 # =============================================================================
107 - # [4/4] Generate files
164 + # [4/4] Generate docker-compose.yml
108 165 # =============================================================================
109 - echo -e "\n${BOLD}[4/4] Generirane na konfiguracionnite fajlove...${RESET}"
166 + echo -e "\n${BOLD}[4/4] Generiranje na fajlove...${RESET}"
110 167
111 168 # -- .env ---------------------------------------------------------------------
112 169 cat > .env <<ENVEOF
@@ -119,24 +176,16 @@ WP1_DB_PASSWORD=$WP1_DB_PASS
119 176 WP2_DB_PASSWORD=$WP2_DB_PASS
120 177 ENVEOF
121 178 chmod 600 .env
122 - success ".env created (chmod 600)"
179 + success ".env updated"
123 180
124 - # -- DB init SQL (only when WP is needed) -------------------------------------
125 - if [[ "$need_db" == "y" ]]; then
181 + # -- db-init (only for fresh installs, no DB running yet) ---------------------
182 + if ! $HAVE_DB; then
126 183 mkdir -p db-init
127 - SQL_CONTENT=""
128 - if [[ "$wp_count" -ge 1 ]]; then
129 - SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
130 - SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp1_user'@'%' IDENTIFIED BY '${WP1_DB_PASS}';\n"
131 - SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp1_db.* TO 'wp1_user'@'%';\n"
132 - fi
133 - if [[ "$wp_count" -ge 2 ]]; then
134 - SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
135 - SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp2_user'@'%' IDENTIFIED BY '${WP2_DB_PASS}';\n"
136 - SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp2_db.* TO 'wp2_user'@'%';\n"
137 - fi
138 - SQL_CONTENT+="FLUSH PRIVILEGES;\n"
139 - printf "%b" "$SQL_CONTENT" > db-init/01-init.sql
184 + SQL=""
185 + $ADD_WP1 && SQL+="CREATE DATABASE IF NOT EXISTS wp1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER IF NOT EXISTS 'wp1_user'@'%' IDENTIFIED BY '${WP1_DB_PASS}';\nGRANT ALL PRIVILEGES ON wp1_db.* TO 'wp1_user'@'%';\n"
186 + $ADD_WP2 && SQL+="CREATE DATABASE IF NOT EXISTS wp2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER IF NOT EXISTS 'wp2_user'@'%' IDENTIFIED BY '${WP2_DB_PASS}';\nGRANT ALL PRIVILEGES ON wp2_db.* TO 'wp2_user'@'%';\n"
187 + SQL+="FLUSH PRIVILEGES;\n"
188 + printf "%b" "$SQL" > db-init/01-init.sql
140 189 success "db-init/01-init.sql created"
141 190 fi
142 191
@@ -145,28 +194,29 @@ cat > docker-compose.yml <<DCEOF
145 194 services:
146 195 DCEOF
147 196
148 - # -- Cloudflare Tunnel --------------------------------------------------------
149 - if [[ "$install_cf" == "y" ]]; then
197 + # Cloudflare
198 + if $HAVE_CF || [[ "$ADD_CF" == "y" ]]; then
199 + USE_CMD="$CLOUDFLARED_CMD"
200 + $HAVE_CF && USE_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
150 201 cat >> docker-compose.yml <<DCEOF
151 202
152 203 # -- Cloudflare Tunnel -------------------------------------------------------
153 204 cloudflared:
154 205 image: cloudflare/cloudflared:latest
155 206 restart: always
156 - command: $CLOUDFLARED_CMD
207 + command: $USE_CMD
208 + environment:
209 + - TUNNEL_TOKEN=\${TUNNEL_TOKEN}
157 210 networks:
158 211 - internal
159 212 DCEOF
160 - if [[ -n "$CF_ENV_LINE" ]]; then
161 - cat >> docker-compose.yml <<DCEOF
162 - environment:
163 - $CF_ENV_LINE
164 - DCEOF
165 - fi
166 213 fi
167 214
168 - # -- MariaDB (only when WP is needed) -----------------------------------------
169 - if [[ "$need_db" == "y" ]]; then
215 + # MariaDB
216 + NEED_DB=false
217 + ( $HAVE_DB || $HAVE_WP1 || $HAVE_WP2 || $ADD_WP1 || $ADD_WP2 ) && NEED_DB=true
218 +
219 + if $NEED_DB; then
170 220 cat >> docker-compose.yml <<DCEOF
171 221
172 222 # -- Database ----------------------------------------------------------------
@@ -188,8 +238,8 @@ cat >> docker-compose.yml <<DCEOF
188 238 DCEOF
189 239 fi
190 240
191 - # -- Uptime Kuma --------------------------------------------------------------
192 - if [[ "$install_kuma" == "y" ]]; then
241 + # Uptime Kuma
242 + if $HAVE_KUMA || [[ "$ADD_KUMA" == "y" ]]; then
193 243 cat >> docker-compose.yml <<DCEOF
194 244
195 245 # -- Uptime Kuma -------------------------------------------------------------
@@ -197,6 +247,8 @@ cat >> docker-compose.yml <<DCEOF
197 247 image: louislam/uptime-kuma:latest
198 248 container_name: uptime-kuma
199 249 restart: always
250 + ports:
251 + - "3001:3001"
200 252 volumes:
201 253 - kuma_data:/app/data
202 254 networks:
@@ -204,8 +256,8 @@ cat >> docker-compose.yml <<DCEOF
204 256 DCEOF
205 257 fi
206 258
207 - # -- WordPress 1 --------------------------------------------------------------
208 - if [[ "$wp_count" -ge 1 ]]; then
259 + # WordPress 1
260 + if $HAVE_WP1 || $ADD_WP1; then
209 261 cat >> docker-compose.yml <<DCEOF
210 262
211 263 # -- WordPress 1 -------------------------------------------------------------
@@ -215,6 +267,8 @@ cat >> docker-compose.yml <<DCEOF
215 267 depends_on:
216 268 db:
217 269 condition: service_healthy
270 + ports:
271 + - "8081:80"
218 272 environment:
219 273 WORDPRESS_DB_HOST: db
220 274 WORDPRESS_DB_USER: wp1_user
@@ -227,8 +281,8 @@ cat >> docker-compose.yml <<DCEOF
227 281 DCEOF
228 282 fi
229 283
230 - # -- WordPress 2 --------------------------------------------------------------
231 - if [[ "$wp_count" -ge 2 ]]; then
284 + # WordPress 2
285 + if $HAVE_WP2 || $ADD_WP2; then
232 286 cat >> docker-compose.yml <<DCEOF
233 287
234 288 # -- WordPress 2 -------------------------------------------------------------
@@ -238,6 +292,8 @@ cat >> docker-compose.yml <<DCEOF
238 292 depends_on:
239 293 db:
240 294 condition: service_healthy
295 + ports:
296 + - "8082:80"
241 297 environment:
242 298 WORDPRESS_DB_HOST: db
243 299 WORDPRESS_DB_USER: wp2_user
@@ -250,7 +306,7 @@ cat >> docker-compose.yml <<DCEOF
250 306 DCEOF
251 307 fi
252 308
253 - # -- Networks & Volumes -------------------------------------------------------
309 + # Networks & Volumes
254 310 cat >> docker-compose.yml <<DCEOF
255 311
256 312 networks:
@@ -260,40 +316,44 @@ networks:
260 316 volumes:
261 317 DCEOF
262 318
263 - # Only add volumes that are actually used
264 - [[ "$need_db" == "y" ]] && echo " db_data:" >> docker-compose.yml
265 - [[ "$install_kuma" == "y" ]] && echo " kuma_data:" >> docker-compose.yml
266 - [[ "$wp_count" -ge 1 ]] && echo " wp1_data:" >> docker-compose.yml
267 - [[ "$wp_count" -ge 2 ]] && echo " wp2_data:" >> docker-compose.yml
319 + $NEED_DB && echo " db_data:" >> docker-compose.yml
320 + ( $HAVE_KUMA || [[ "$ADD_KUMA" == "y" ]] ) && echo " kuma_data:" >> docker-compose.yml
321 + ( $HAVE_WP1 || $ADD_WP1 ) && echo " wp1_data:" >> docker-compose.yml
322 + ( $HAVE_WP2 || $ADD_WP2 ) && echo " wp2_data:" >> docker-compose.yml
268 323
269 - success "docker-compose.yml created"
324 + success "docker-compose.yml updated"
270 325
271 326 # =============================================================================
272 - # Summary
327 + # Create DB users for newly added WordPress (DB is already running)
328 + # =============================================================================
329 + if $HAVE_DB; then
330 + if $ADD_WP1; then
331 + create_db_user "wp1_db" "wp1_user" "$WP1_DB_PASS" "$DB_ROOT_PASS" "$DB_CONTAINER"
332 + fi
333 + if $ADD_WP2; then
334 + create_db_user "wp2_db" "wp2_user" "$WP2_DB_PASS" "$DB_ROOT_PASS" "$DB_CONTAINER"
335 + fi
336 + fi
337 +
338 + # -- Apply changes ------------------------------------------------------------
339 + echo ""
340 + info "Prilagame promΠ΅Π½ΠΈΡ‚Π΅ s 'docker compose up -d' ..."
341 + docker compose up -d
342 + success "Vsichko e startΠΈrano!"
343 +
344 + # =============================================================================
345 + # Summary with real URLs
273 346 # =============================================================================
274 347 echo ""
275 348 echo -e "${BOLD}================================================${RESET}"
276 - echo -e "${BOLD} Summary / Rezultat ${RESET}"
349 + echo -e "${BOLD} Dostap do uslugite / Access URLs ${RESET}"
277 350 echo -e "${BOLD}================================================${RESET}"
278 351
279 - if [[ "$install_cf" == "y" ]]; then
280 - CF_LABEL="Yes ($([ "$cf_method" == "1" ] && echo "Token" || echo "Login"))"
281 - else
282 - CF_LABEL="No"
283 - fi
352 + ( $HAVE_WP1 || $ADD_WP1 ) && echo -e " WordPress 1 : ${GREEN}http://${SERVER_IP}:8081${RESET}"
353 + ( $HAVE_WP2 || $ADD_WP2 ) && echo -e " WordPress 2 : ${GREEN}http://${SERVER_IP}:8082${RESET}"
354 + ( $HAVE_KUMA || [[ "$ADD_KUMA" == "y" ]] ) && echo -e " Uptime Kuma : ${GREEN}http://${SERVER_IP}:3001${RESET}"
355 + ( $HAVE_CF || [[ "$ADD_CF" == "y" ]] ) && echo -e " Cloudflare : ${CYAN}(configured via Cloudflare Dashboard)${RESET}"
284 356
285 - echo -e " Cloudflare Tunnel : ${CYAN}$CF_LABEL${RESET}"
286 - echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Yes" || echo "No")${RESET}"
287 - echo -e " WordPress sites : ${CYAN}$wp_count${RESET}"
288 - echo -e " MariaDB : ${CYAN}$([ "$need_db" == "y" ] && echo "Yes" || echo "No")${RESET}"
289 - echo ""
290 - echo -e "${BOLD} Files created:${RESET}"
291 - echo " .env (chmod 600)"
292 - echo " docker-compose.yml"
293 - [[ "$need_db" == "y" ]] && echo " db-init/01-init.sql"
294 - echo ""
295 - echo -e "${BOLD} Next step:${RESET}"
296 - echo -e " ${GREEN}docker compose up -d${RESET}"
297 357 echo ""
298 358 warn "Keep .env in a safe place - it contains your passwords!"
299 359 echo -e "${BOLD}================================================${RESET}\n"

urocibg hat die Gist bearbeitet 1 month ago. Zu Γ„nderung gehen

1 file changed, 111 insertions, 74 deletions

setup_hosting.sh

@@ -1,6 +1,6 @@
1 1 #!/bin/bash
2 2 # =============================================================================
3 - # Hosting setup with Cloudflare Tunnel
3 + # Modular Hosting Setup with optional Cloudflare Tunnel
4 4 # Author Fedya Serafiev
5 5 # Site itpraktika.com
6 6 # =============================================================================
@@ -25,63 +25,90 @@ gen_pass() {
25 25 validate_yn() {
26 26 [[ "$1" =~ ^[yYnN]$ ]] || error "Vuvedete 'y' ili 'n'."
27 27 }
28 -
29 28 validate_count() {
30 29 [[ "$1" =~ ^[0-2]$ ]] || error "Vuvedete 0, 1 ili 2."
31 30 }
32 31
33 32 # =============================================================================
34 33 echo -e "\n${BOLD}================================================${RESET}"
35 - echo -e "${BOLD} Nastrojka na Hosting s Cloudflare Tunnel ${RESET}"
34 + echo -e "${BOLD} Modular Hosting Setup - Izberete moduli ${RESET}"
36 35 echo -e "${BOLD}================================================${RESET}\n"
37 36
38 - # -- [1/4] Cloudflare Tunnel method -------------------------------------------
39 - echo -e "${BOLD}[1/4] Cloudflare Tunnel - metod na svarzavane${RESET}"
40 - echo " 1) Token - vuvedash gotov token ot Cloudflare Dashboard"
41 - echo " 2) Login - cloudflared se logva sam (URL / brauzar)"
42 - echo ""
43 - read -rp "Izberi metod [1/2]: " cf_method
44 -
45 - case "$cf_method" in
46 - 1)
47 - read -rp " Vuvedete Tunnel Token: " cf_token
48 - [[ -n "$cf_token" ]] || error "Tokenat ne mozhe da e prazen."
49 - CLOUDFLARED_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
50 - CF_ENV_LINE=" - TUNNEL_TOKEN=\${TUNNEL_TOKEN}"
51 - CF_TOKEN_IN_ENV="TUNNEL_TOKEN=$cf_token"
52 - ;;
53 - 2)
54 - info "Pri startΠΈrane cloudflared shte izvede URL za avtentikaciya."
55 - CLOUDFLARED_CMD='tunnel --no-autoupdate login'
56 - CF_ENV_LINE=""
57 - CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (login method)"
58 - cf_token=""
59 - ;;
60 - *)
61 - error "NevaliΠ΄Π΅Π½ izbor. Vuvedete 1 ili 2."
62 - ;;
63 - esac
64 -
65 - # -- [2/4] Uptime Kuma --------------------------------------------------------
66 - echo -e "\n${BOLD}[2/4] Uptime Kuma${RESET}"
67 - read -rp "Instaliraj Uptime Kuma? (y/n): " install_kuma
68 - validate_yn "$install_kuma"
69 - install_kuma="${install_kuma,,}"
70 -
71 - # -- [3/4] WordPress sites ----------------------------------------------------
72 - echo -e "\n${BOLD}[3/4] WordPress sajtove${RESET}"
73 - read -rp "Broy WordPress sajtove? (0/1/2): " wp_count
37 + # =============================================================================
38 + # [1/4] Module selection
39 + # =============================================================================
40 + echo -e "${BOLD}[1/4] Izberete koi moduli da se instalΠΈΡ€Π°Ρ‚:${RESET}\n"
41 +
42 + read -rp " Instaliraj Cloudflare Tunnel? (y/n): " install_cf
43 + validate_yn "$install_cf"; install_cf="${install_cf,,}"
44 +
45 + read -rp " Instaliraj Uptime Kuma? (y/n): " install_kuma
46 + validate_yn "$install_kuma"; install_kuma="${install_kuma,,}"
47 +
48 + read -rp " Broy WordPress sajtove? (0/1/2): " wp_count
74 49 validate_count "$wp_count"
75 50
76 - # -- [4/4] Generate passwords -------------------------------------------------
77 - echo -e "\n${BOLD}[4/4] Generirane na paroli...${RESET}"
51 + # At least one module must be selected
52 + if [[ "$install_cf" == "n" && "$install_kuma" == "n" && "$wp_count" == "0" ]]; then
53 + error "Tryabva da izberete poΠ½Π΅ edin modul."
54 + fi
55 +
56 + # DB is needed only when WordPress is requested
57 + need_db="n"
58 + [[ "$wp_count" -ge 1 ]] && need_db="y"
59 +
60 + # =============================================================================
61 + # [2/4] Cloudflare Tunnel config (only if selected)
62 + # =============================================================================
63 + CLOUDFLARED_CMD=""
64 + CF_ENV_LINE=""
65 + CF_TOKEN_IN_ENV="# Cloudflare Tunnel not installed"
66 + cf_method=""
67 +
68 + if [[ "$install_cf" == "y" ]]; then
69 + echo -e "\n${BOLD}[2/4] Cloudflare Tunnel - metod na svarzavane${RESET}"
70 + echo " 1) Token - vuvedash gotov token ot Cloudflare Dashboard"
71 + echo " 2) Login - cloudflared se logva sam (URL / brauzar)"
72 + echo ""
73 + read -rp " Izberi metod [1/2]: " cf_method
74 +
75 + case "$cf_method" in
76 + 1)
77 + read -rp " Vuvedete Tunnel Token: " cf_token
78 + [[ -n "$cf_token" ]] || error "Tokenat ne mozhe da e prazen."
79 + CLOUDFLARED_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
80 + CF_ENV_LINE=" - TUNNEL_TOKEN=\${TUNNEL_TOKEN}"
81 + CF_TOKEN_IN_ENV="TUNNEL_TOKEN=$cf_token"
82 + ;;
83 + 2)
84 + info "cloudflared shte izvede URL za avtentikaciya pri start."
85 + CLOUDFLARED_CMD='tunnel --no-autoupdate login'
86 + CF_ENV_LINE=""
87 + CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (login method - not needed)"
88 + cf_token=""
89 + ;;
90 + *)
91 + error "NevaliΠ΄Π΅Π½ izbor. Vuvedete 1 ili 2."
92 + ;;
93 + esac
94 + else
95 + info "Cloudflare Tunnel - skipped."
96 + fi
97 +
98 + # =============================================================================
99 + # [3/4] Generate passwords
100 + # =============================================================================
101 + echo -e "\n${BOLD}[3/4] Generirane na paroli...${RESET}"
78 102 DB_ROOT_PASS=$(gen_pass)
79 103 WP1_DB_PASS=$(gen_pass)
80 104 WP2_DB_PASS=$(gen_pass)
81 105
82 106 # =============================================================================
83 - # .env file
107 + # [4/4] Generate files
84 108 # =============================================================================
109 + echo -e "\n${BOLD}[4/4] Generirane na konfiguracionnite fajlove...${RESET}"
110 +
111 + # -- .env ---------------------------------------------------------------------
85 112 cat > .env <<ENVEOF
86 113 # -- Cloudflare ---------------------------------------------------------------
87 114 $CF_TOKEN_IN_ENV
@@ -91,36 +118,36 @@ DB_ROOT_PASSWORD=$DB_ROOT_PASS
91 118 WP1_DB_PASSWORD=$WP1_DB_PASS
92 119 WP2_DB_PASSWORD=$WP2_DB_PASS
93 120 ENVEOF
94 -
95 121 chmod 600 .env
96 122 success ".env created (chmod 600)"
97 123
98 - # =============================================================================
99 - # DB init SQL
100 - # =============================================================================
101 - mkdir -p db-init
102 -
103 - SQL_CONTENT=""
104 - if [[ "$wp_count" -ge 1 ]]; then
105 - SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
106 - SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp1_user'@'%' IDENTIFIED BY '${WP1_DB_PASS}';\n"
107 - SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp1_db.* TO 'wp1_user'@'%';\n"
124 + # -- DB init SQL (only when WP is needed) -------------------------------------
125 + if [[ "$need_db" == "y" ]]; then
126 + mkdir -p db-init
127 + SQL_CONTENT=""
128 + if [[ "$wp_count" -ge 1 ]]; then
129 + SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
130 + SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp1_user'@'%' IDENTIFIED BY '${WP1_DB_PASS}';\n"
131 + SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp1_db.* TO 'wp1_user'@'%';\n"
132 + fi
133 + if [[ "$wp_count" -ge 2 ]]; then
134 + SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
135 + SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp2_user'@'%' IDENTIFIED BY '${WP2_DB_PASS}';\n"
136 + SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp2_db.* TO 'wp2_user'@'%';\n"
137 + fi
138 + SQL_CONTENT+="FLUSH PRIVILEGES;\n"
139 + printf "%b" "$SQL_CONTENT" > db-init/01-init.sql
140 + success "db-init/01-init.sql created"
108 141 fi
109 - if [[ "$wp_count" -ge 2 ]]; then
110 - SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
111 - SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp2_user'@'%' IDENTIFIED BY '${WP2_DB_PASS}';\n"
112 - SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp2_db.* TO 'wp2_user'@'%';\n"
113 - fi
114 - SQL_CONTENT+="FLUSH PRIVILEGES;\n"
115 -
116 - printf "%b" "$SQL_CONTENT" > db-init/01-init.sql
117 - success "db-init/01-init.sql created"
118 142
119 - # =============================================================================
120 - # docker-compose.yml
121 - # =============================================================================
143 + # -- docker-compose.yml -------------------------------------------------------
122 144 cat > docker-compose.yml <<DCEOF
123 145 services:
146 + DCEOF
147 +
148 + # -- Cloudflare Tunnel --------------------------------------------------------
149 + if [[ "$install_cf" == "y" ]]; then
150 + cat >> docker-compose.yml <<DCEOF
124 151
125 152 # -- Cloudflare Tunnel -------------------------------------------------------
126 153 cloudflared:
@@ -130,16 +157,16 @@ services:
130 157 networks:
131 158 - internal
132 159 DCEOF
133 -
134 - # Add environment block only for token method
135 - if [[ -n "$CF_ENV_LINE" ]]; then
160 + if [[ -n "$CF_ENV_LINE" ]]; then
136 161 cat >> docker-compose.yml <<DCEOF
137 162 environment:
138 163 $CF_ENV_LINE
139 164 DCEOF
165 + fi
140 166 fi
141 167
142 - # -- MariaDB ------------------------------------------------------------------
168 + # -- MariaDB (only when WP is needed) -----------------------------------------
169 + if [[ "$need_db" == "y" ]]; then
143 170 cat >> docker-compose.yml <<DCEOF
144 171
145 172 # -- Database ----------------------------------------------------------------
@@ -159,6 +186,7 @@ cat >> docker-compose.yml <<DCEOF
159 186 timeout: 5s
160 187 retries: 5
161 188 DCEOF
189 + fi
162 190
163 191 # -- Uptime Kuma --------------------------------------------------------------
164 192 if [[ "$install_kuma" == "y" ]]; then
@@ -230,9 +258,10 @@ networks:
230 258 driver: bridge
231 259
232 260 volumes:
233 - db_data:
234 261 DCEOF
235 262
263 + # Only add volumes that are actually used
264 + [[ "$need_db" == "y" ]] && echo " db_data:" >> docker-compose.yml
236 265 [[ "$install_kuma" == "y" ]] && echo " kuma_data:" >> docker-compose.yml
237 266 [[ "$wp_count" -ge 1 ]] && echo " wp1_data:" >> docker-compose.yml
238 267 [[ "$wp_count" -ge 2 ]] && echo " wp2_data:" >> docker-compose.yml
@@ -246,14 +275,22 @@ echo ""
246 275 echo -e "${BOLD}================================================${RESET}"
247 276 echo -e "${BOLD} Summary / Rezultat ${RESET}"
248 277 echo -e "${BOLD}================================================${RESET}"
249 - echo -e " CF method : ${CYAN}$([ "$cf_method" == "1" ] && echo "Token" || echo "Login")${RESET}"
250 - echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Yes" || echo "No")${RESET}"
251 - echo -e " WordPress : ${CYAN}$wp_count site(s)${RESET}"
278 +
279 + if [[ "$install_cf" == "y" ]]; then
280 + CF_LABEL="Yes ($([ "$cf_method" == "1" ] && echo "Token" || echo "Login"))"
281 + else
282 + CF_LABEL="No"
283 + fi
284 +
285 + echo -e " Cloudflare Tunnel : ${CYAN}$CF_LABEL${RESET}"
286 + echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Yes" || echo "No")${RESET}"
287 + echo -e " WordPress sites : ${CYAN}$wp_count${RESET}"
288 + echo -e " MariaDB : ${CYAN}$([ "$need_db" == "y" ] && echo "Yes" || echo "No")${RESET}"
252 289 echo ""
253 290 echo -e "${BOLD} Files created:${RESET}"
254 291 echo " .env (chmod 600)"
255 292 echo " docker-compose.yml"
256 - echo " db-init/01-init.sql"
293 + [[ "$need_db" == "y" ]] && echo " db-init/01-init.sql"
257 294 echo ""
258 295 echo -e "${BOLD} Next step:${RESET}"
259 296 echo -e " ${GREEN}docker compose up -d${RESET}"

urocibg hat die Gist bearbeitet 1 month ago. Zu Γ„nderung gehen

1 file changed, 83 insertions, 83 deletions

setup_hosting.sh

@@ -1,102 +1,102 @@
1 1 #!/bin/bash
2 2 # =============================================================================
3 - # Настройка Π½Π° Π₯остинг ΡΡŠΡ€Π²ΡŠΡ€ с Cloudflare Tunnel
4 - # Автор: ЀСдя Π‘Π΅Ρ€Π°Ρ„ΠΈΠ΅Π² | itpraktika.com
3 + # Hosting setup with Cloudflare Tunnel
4 + # Author Fedya Serafiev
5 + # Site itpraktika.com
5 6 # =============================================================================
6 7
7 8 set -euo pipefail
8 9
9 - # ── Π¦Π²Π΅Ρ‚ΠΎΠ²Π΅ ──────────────────────────────────────────────────────────────────
10 + # -- Colors -------------------------------------------------------------------
10 11 RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
11 12 CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
12 13
13 - info() { echo -e "${CYAN}ℹ️ $*${RESET}"; }
14 - success() { echo -e "${GREEN}βœ… $*${RESET}"; }
15 - warn() { echo -e "${YELLOW}⚠️ $*${RESET}"; }
16 - error() { echo -e "${RED}❌ $*${RESET}" >&2; exit 1; }
14 + info() { echo -e "${CYAN}[INFO] $*${RESET}"; }
15 + success() { echo -e "${GREEN}[OK] $*${RESET}"; }
16 + warn() { echo -e "${YELLOW}[WARN] $*${RESET}"; }
17 + error() { echo -e "${RED}[ERROR] $*${RESET}" >&2; exit 1; }
17 18
18 - # ── Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»Π° ─────────────────────────────────────────────────────
19 + # -- Password generator -------------------------------------------------------
19 20 gen_pass() {
20 21 openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 24
21 22 }
22 23
23 - # ── Валидация ─────────────────────────────────────────────────────────────────
24 + # -- Input validation ---------------------------------------------------------
24 25 validate_yn() {
25 - local val="$1"
26 - [[ "$val" =~ ^[yYnN]$ ]] || error "Π’ΡŠΠ²Π΅Π΄ΠΈ 'y' ΠΈΠ»ΠΈ 'n'."
26 + [[ "$1" =~ ^[yYnN]$ ]] || error "Vuvedete 'y' ili 'n'."
27 27 }
28 28
29 29 validate_count() {
30 - local val="$1"
31 - [[ "$val" =~ ^[0-2]$ ]] || error "Π’ΡŠΠ²Π΅Π΄ΠΈ 0, 1 ΠΈΠ»ΠΈ 2."
30 + [[ "$1" =~ ^[0-2]$ ]] || error "Vuvedete 0, 1 ili 2."
32 31 }
33 32
34 33 # =============================================================================
35 - echo -e "\n${BOLD}════════════════════════════════════════════════════${RESET}"
36 - echo -e "${BOLD} πŸš€ Настройка Π½Π° Π₯остинг с Cloudflare Tunnel ${RESET}"
37 - echo -e "${BOLD}════════════════════════════════════════════════════${RESET}\n"
38 -
39 - # ── 1. Π˜Π·Π±ΠΎΡ€ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° Cloudflare Tunnel ────────────────────────────────────
40 - echo -e "${BOLD}[1/4] Cloudflare Tunnel β€” ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅${RESET}"
41 - echo " 1) Token β€” въвСТдаш Π³ΠΎΡ‚ΠΎΠ² Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΡ‚ Cloudflare Dashboard"
42 - echo " 2) Login β€” cloudflared сС Π»ΠΎΠ³Π²Π° сам (Ρ‰Π΅ ΠΎΡ‚Π²ΠΎΡ€ΠΈ Π±Ρ€Π°ΡƒΠ·ΡŠΡ€ / URL)"
34 + echo -e "\n${BOLD}================================================${RESET}"
35 + echo -e "${BOLD} Nastrojka na Hosting s Cloudflare Tunnel ${RESET}"
36 + echo -e "${BOLD}================================================${RESET}\n"
37 +
38 + # -- [1/4] Cloudflare Tunnel method -------------------------------------------
39 + echo -e "${BOLD}[1/4] Cloudflare Tunnel - metod na svarzavane${RESET}"
40 + echo " 1) Token - vuvedash gotov token ot Cloudflare Dashboard"
41 + echo " 2) Login - cloudflared se logva sam (URL / brauzar)"
43 42 echo ""
44 - read -rp "Π˜Π·Π±Π΅Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ [1/2]: " cf_method
43 + read -rp "Izberi metod [1/2]: " cf_method
45 44
46 45 case "$cf_method" in
47 46 1)
48 - read -rp " Π’ΡŠΠ²Π΅Π΄ΠΈ Tunnel Token: " cf_token
49 - [[ -n "$cf_token" ]] || error "Π’ΠΎΠΊΠ΅Π½ΡŠΡ‚ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ ΠΏΡ€Π°Π·Π΅Π½."
47 + read -rp " Vuvedete Tunnel Token: " cf_token
48 + [[ -n "$cf_token" ]] || error "Tokenat ne mozhe da e prazen."
50 49 CLOUDFLARED_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
51 50 CF_ENV_LINE=" - TUNNEL_TOKEN=\${TUNNEL_TOKEN}"
52 51 CF_TOKEN_IN_ENV="TUNNEL_TOKEN=$cf_token"
53 52 ;;
54 53 2)
55 - info "ΠŸΡ€ΠΈ стартиранС cloudflared Ρ‰Π΅ ΠΈΠ·Π²Π΅Π΄Π΅ URL Π·Π° автСнтикация."
54 + info "Pri startΠΈrane cloudflared shte izvede URL za avtentikaciya."
56 55 CLOUDFLARED_CMD='tunnel --no-autoupdate login'
57 56 CF_ENV_LINE=""
58 - CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° сС login ΠΌΠ΅Ρ‚ΠΎΠ΄)"
57 + CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (login method)"
59 58 cf_token=""
60 59 ;;
61 60 *)
62 - error "НСвалидСн ΠΈΠ·Π±ΠΎΡ€. Π’ΡŠΠ²Π΅Π΄ΠΈ 1 ΠΈΠ»ΠΈ 2."
61 + error "NevaliΠ΄Π΅Π½ izbor. Vuvedete 1 ili 2."
63 62 ;;
64 63 esac
65 64
66 - # ── 2. Uptime Kuma ────────────────────────────────────────────────────────────
65 + # -- [2/4] Uptime Kuma --------------------------------------------------------
67 66 echo -e "\n${BOLD}[2/4] Uptime Kuma${RESET}"
68 - read -rp "Π˜Π½ΡΡ‚Π°Π»ΠΈΡ€Π°ΠΉ Uptime Kuma? (y/n): " install_kuma
67 + read -rp "Instaliraj Uptime Kuma? (y/n): " install_kuma
69 68 validate_yn "$install_kuma"
70 - install_kuma="${install_kuma,,}" # lowercase
69 + install_kuma="${install_kuma,,}"
71 70
72 - # ── 3. WordPress сайтовС ──────────────────────────────────────────────────────
73 - echo -e "\n${BOLD}[3/4] WordPress сайтовС${RESET}"
74 - read -rp "Π‘Ρ€ΠΎΠΉ WordPress сайтовС? (0/1/2): " wp_count
71 + # -- [3/4] WordPress sites ----------------------------------------------------
72 + echo -e "\n${BOLD}[3/4] WordPress sajtove${RESET}"
73 + read -rp "Broy WordPress sajtove? (0/1/2): " wp_count
75 74 validate_count "$wp_count"
76 75
77 - # ── 4. Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»ΠΈ ───────────────────────────────────────────────────
78 - echo -e "\n${BOLD}[4/4] Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»ΠΈ...${RESET}"
76 + # -- [4/4] Generate passwords -------------------------------------------------
77 + echo -e "\n${BOLD}[4/4] Generirane na paroli...${RESET}"
79 78 DB_ROOT_PASS=$(gen_pass)
80 79 WP1_DB_PASS=$(gen_pass)
81 80 WP2_DB_PASS=$(gen_pass)
82 81
83 82 # =============================================================================
84 - # .env Ρ„Π°ΠΉΠ»
83 + # .env file
85 84 # =============================================================================
86 - cat > .env <<EOF
87 - # ── Cloudflare ────────────────────────────────────────────────────
85 + cat > .env <<ENVEOF
86 + # -- Cloudflare ---------------------------------------------------------------
88 87 $CF_TOKEN_IN_ENV
89 88
90 - # ── Π‘Π°Π·Π° Π΄Π°Π½Π½ΠΈ ────────────────────────────────────────────────────
89 + # -- Database -----------------------------------------------------------------
91 90 DB_ROOT_PASSWORD=$DB_ROOT_PASS
92 91 WP1_DB_PASSWORD=$WP1_DB_PASS
93 92 WP2_DB_PASSWORD=$WP2_DB_PASS
94 - EOF
93 + ENVEOF
94 +
95 95 chmod 600 .env
96 - success ".env създадСн (ΠΏΡ€Π°Π²Π°: 600)"
96 + success ".env created (chmod 600)"
97 97
98 98 # =============================================================================
99 - # Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° init SQL Π·Π° Π±Π°Π·ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ
99 + # DB init SQL
100 100 # =============================================================================
101 101 mkdir -p db-init
102 102
@@ -114,35 +114,35 @@ fi
114 114 SQL_CONTENT+="FLUSH PRIVILEGES;\n"
115 115
116 116 printf "%b" "$SQL_CONTENT" > db-init/01-init.sql
117 - success "db-init/01-init.sql създадСн"
117 + success "db-init/01-init.sql created"
118 118
119 119 # =============================================================================
120 120 # docker-compose.yml
121 121 # =============================================================================
122 - cat > docker-compose.yml <<EOF
122 + cat > docker-compose.yml <<DCEOF
123 123 services:
124 124
125 - # ── Cloudflare Tunnel ───────────────────────────────────────────
125 + # -- Cloudflare Tunnel -------------------------------------------------------
126 126 cloudflared:
127 127 image: cloudflare/cloudflared:latest
128 128 restart: always
129 129 command: $CLOUDFLARED_CMD
130 130 networks:
131 131 - internal
132 - EOF
132 + DCEOF
133 133
134 - # ДобавянС Π½Π° environment само ΠΏΡ€ΠΈ token ΠΌΠ΅Ρ‚ΠΎΠ΄
134 + # Add environment block only for token method
135 135 if [[ -n "$CF_ENV_LINE" ]]; then
136 - cat >> docker-compose.yml <<EOF
136 + cat >> docker-compose.yml <<DCEOF
137 137 environment:
138 138 $CF_ENV_LINE
139 - EOF
139 + DCEOF
140 140 fi
141 141
142 - # ── MariaDB ────────────────────────────────────────────────────────────────
143 - cat >> docker-compose.yml <<EOF
142 + # -- MariaDB ------------------------------------------------------------------
143 + cat >> docker-compose.yml <<DCEOF
144 144
145 - # ── Π‘Π°Π·Π° Π΄Π°Π½Π½ΠΈ ──────────────────────────────────────────────────
145 + # -- Database ----------------------------------------------------------------
146 146 db:
147 147 image: mariadb:10.6
148 148 restart: always
@@ -158,13 +158,13 @@ cat >> docker-compose.yml <<EOF
158 158 interval: 10s
159 159 timeout: 5s
160 160 retries: 5
161 - EOF
161 + DCEOF
162 162
163 - # ── Uptime Kuma ────────────────────────────────────────────────────────────
163 + # -- Uptime Kuma --------------------------------------------------------------
164 164 if [[ "$install_kuma" == "y" ]]; then
165 - cat >> docker-compose.yml <<EOF
165 + cat >> docker-compose.yml <<DCEOF
166 166
167 - # ── Uptime Kuma ─────────────────────────────────────────────────
167 + # -- Uptime Kuma -------------------------------------------------------------
168 168 uptime-kuma:
169 169 image: louislam/uptime-kuma:latest
170 170 container_name: uptime-kuma
@@ -173,14 +173,14 @@ cat >> docker-compose.yml <<EOF
173 173 - kuma_data:/app/data
174 174 networks:
175 175 - internal
176 - EOF
176 + DCEOF
177 177 fi
178 178
179 - # ── WordPress 1 ────────────────────────────────────────────────────────────
179 + # -- WordPress 1 --------------------------------------------------------------
180 180 if [[ "$wp_count" -ge 1 ]]; then
181 - cat >> docker-compose.yml <<EOF
181 + cat >> docker-compose.yml <<DCEOF
182 182
183 - # ── WordPress 1 ─────────────────────────────────────────────────
183 + # -- WordPress 1 -------------------------------------------------------------
184 184 wp1:
185 185 image: wordpress:latest
186 186 restart: always
@@ -196,14 +196,14 @@ cat >> docker-compose.yml <<EOF
196 196 - wp1_data:/var/www/html
197 197 networks:
198 198 - internal
199 - EOF
199 + DCEOF
200 200 fi
201 201
202 - # ── WordPress 2 ────────────────────────────────────────────────────────────
202 + # -- WordPress 2 --------------------------------------------------------------
203 203 if [[ "$wp_count" -ge 2 ]]; then
204 - cat >> docker-compose.yml <<EOF
204 + cat >> docker-compose.yml <<DCEOF
205 205
206 - # ── WordPress 2 ─────────────────────────────────────────────────
206 + # -- WordPress 2 -------------------------------------------------------------
207 207 wp2:
208 208 image: wordpress:latest
209 209 restart: always
@@ -219,11 +219,11 @@ cat >> docker-compose.yml <<EOF
219 219 - wp2_data:/var/www/html
220 220 networks:
221 221 - internal
222 - EOF
222 + DCEOF
223 223 fi
224 224
225 - # ── Networks & Volumes ─────────────────────────────────────────────────────
226 - cat >> docker-compose.yml <<EOF
225 + # -- Networks & Volumes -------------------------------------------------------
226 + cat >> docker-compose.yml <<DCEOF
227 227
228 228 networks:
229 229 internal:
@@ -231,32 +231,32 @@ networks:
231 231
232 232 volumes:
233 233 db_data:
234 - EOF
234 + DCEOF
235 235
236 236 [[ "$install_kuma" == "y" ]] && echo " kuma_data:" >> docker-compose.yml
237 237 [[ "$wp_count" -ge 1 ]] && echo " wp1_data:" >> docker-compose.yml
238 238 [[ "$wp_count" -ge 2 ]] && echo " wp2_data:" >> docker-compose.yml
239 239
240 - success "docker-compose.yml създадСн"
240 + success "docker-compose.yml created"
241 241
242 242 # =============================================================================
243 - # РСзюмС
243 + # Summary
244 244 # =============================================================================
245 245 echo ""
246 - echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
247 - echo -e "${BOLD} πŸ“‹ РСзюмС Π½Π° конфигурацията ${RESET}"
248 - echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
249 - echo -e " Cloudflare ΠΌΠ΅Ρ‚ΠΎΠ΄ : ${CYAN}$([ "$cf_method" == "1" ] && echo "Token" || echo "Login")${RESET}"
250 - echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Π”Π°" || echo "НС")${RESET}"
251 - echo -e " WordPress сайтовС: ${CYAN}$wp_count${RESET}"
246 + echo -e "${BOLD}================================================${RESET}"
247 + echo -e "${BOLD} Summary / Rezultat ${RESET}"
248 + echo -e "${BOLD}================================================${RESET}"
249 + echo -e " CF method : ${CYAN}$([ "$cf_method" == "1" ] && echo "Token" || echo "Login")${RESET}"
250 + echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Yes" || echo "No")${RESET}"
251 + echo -e " WordPress : ${CYAN}$wp_count site(s)${RESET}"
252 252 echo ""
253 - echo -e "${BOLD} Π€Π°ΠΉΠ»ΠΎΠ²Π΅:${RESET}"
254 - echo " πŸ“„ .env (chmod 600)"
255 - echo " πŸ“„ docker-compose.yml"
256 - echo " πŸ“„ db-init/01-init.sql"
253 + echo -e "${BOLD} Files created:${RESET}"
254 + echo " .env (chmod 600)"
255 + echo " docker-compose.yml"
256 + echo " db-init/01-init.sql"
257 257 echo ""
258 - echo -e "${BOLD} Π‘Π»Π΅Π΄Π²Π°Ρ‰Π° ΡΡ‚ΡŠΠΏΠΊΠ°:${RESET}"
258 + echo -e "${BOLD} Next step:${RESET}"
259 259 echo -e " ${GREEN}docker compose up -d${RESET}"
260 260 echo ""
261 - warn "Π—Π°ΠΏΠ°Π·ΠΈ .env Ρ„Π°ΠΉΠ»Π° Π½Π° сигурно място β€” ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΏΠ°Ρ€ΠΎΠ»ΠΈΡ‚Π΅!"
262 - echo -e "${BOLD}════════════════════════════════════════════════════${RESET}\n"
261 + warn "Keep .env in a safe place - it contains your passwords!"
262 + echo -e "${BOLD}================================================${RESET}\n"

urocibg hat die Gist bearbeitet 1 month ago. Zu Γ„nderung gehen

Keine Γ„nderungen

urocibg hat die Gist bearbeitet 1 month ago. Zu Γ„nderung gehen

1 file changed, 262 insertions

setup_hosting.sh(Datei erstellt)

@@ -0,0 +1,262 @@
1 + #!/bin/bash
2 + # =============================================================================
3 + # Настройка Π½Π° Π₯остинг ΡΡŠΡ€Π²ΡŠΡ€ с Cloudflare Tunnel
4 + # Автор: ЀСдя Π‘Π΅Ρ€Π°Ρ„ΠΈΠ΅Π² | itpraktika.com
5 + # =============================================================================
6 +
7 + set -euo pipefail
8 +
9 + # ── Π¦Π²Π΅Ρ‚ΠΎΠ²Π΅ ──────────────────────────────────────────────────────────────────
10 + RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
11 + CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
12 +
13 + info() { echo -e "${CYAN}ℹ️ $*${RESET}"; }
14 + success() { echo -e "${GREEN}βœ… $*${RESET}"; }
15 + warn() { echo -e "${YELLOW}⚠️ $*${RESET}"; }
16 + error() { echo -e "${RED}❌ $*${RESET}" >&2; exit 1; }
17 +
18 + # ── Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»Π° ─────────────────────────────────────────────────────
19 + gen_pass() {
20 + openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 24
21 + }
22 +
23 + # ── Валидация ─────────────────────────────────────────────────────────────────
24 + validate_yn() {
25 + local val="$1"
26 + [[ "$val" =~ ^[yYnN]$ ]] || error "Π’ΡŠΠ²Π΅Π΄ΠΈ 'y' ΠΈΠ»ΠΈ 'n'."
27 + }
28 +
29 + validate_count() {
30 + local val="$1"
31 + [[ "$val" =~ ^[0-2]$ ]] || error "Π’ΡŠΠ²Π΅Π΄ΠΈ 0, 1 ΠΈΠ»ΠΈ 2."
32 + }
33 +
34 + # =============================================================================
35 + echo -e "\n${BOLD}════════════════════════════════════════════════════${RESET}"
36 + echo -e "${BOLD} πŸš€ Настройка Π½Π° Π₯остинг с Cloudflare Tunnel ${RESET}"
37 + echo -e "${BOLD}════════════════════════════════════════════════════${RESET}\n"
38 +
39 + # ── 1. Π˜Π·Π±ΠΎΡ€ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° Cloudflare Tunnel ────────────────────────────────────
40 + echo -e "${BOLD}[1/4] Cloudflare Tunnel β€” ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅${RESET}"
41 + echo " 1) Token β€” въвСТдаш Π³ΠΎΡ‚ΠΎΠ² Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΡ‚ Cloudflare Dashboard"
42 + echo " 2) Login β€” cloudflared сС Π»ΠΎΠ³Π²Π° сам (Ρ‰Π΅ ΠΎΡ‚Π²ΠΎΡ€ΠΈ Π±Ρ€Π°ΡƒΠ·ΡŠΡ€ / URL)"
43 + echo ""
44 + read -rp "Π˜Π·Π±Π΅Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ [1/2]: " cf_method
45 +
46 + case "$cf_method" in
47 + 1)
48 + read -rp " Π’ΡŠΠ²Π΅Π΄ΠΈ Tunnel Token: " cf_token
49 + [[ -n "$cf_token" ]] || error "Π’ΠΎΠΊΠ΅Π½ΡŠΡ‚ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ ΠΏΡ€Π°Π·Π΅Π½."
50 + CLOUDFLARED_CMD='tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}'
51 + CF_ENV_LINE=" - TUNNEL_TOKEN=\${TUNNEL_TOKEN}"
52 + CF_TOKEN_IN_ENV="TUNNEL_TOKEN=$cf_token"
53 + ;;
54 + 2)
55 + info "ΠŸΡ€ΠΈ стартиранС cloudflared Ρ‰Π΅ ΠΈΠ·Π²Π΅Π΄Π΅ URL Π·Π° автСнтикация."
56 + CLOUDFLARED_CMD='tunnel --no-autoupdate login'
57 + CF_ENV_LINE=""
58 + CF_TOKEN_IN_ENV="# TUNNEL_TOKEN= (ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° сС login ΠΌΠ΅Ρ‚ΠΎΠ΄)"
59 + cf_token=""
60 + ;;
61 + *)
62 + error "НСвалидСн ΠΈΠ·Π±ΠΎΡ€. Π’ΡŠΠ²Π΅Π΄ΠΈ 1 ΠΈΠ»ΠΈ 2."
63 + ;;
64 + esac
65 +
66 + # ── 2. Uptime Kuma ────────────────────────────────────────────────────────────
67 + echo -e "\n${BOLD}[2/4] Uptime Kuma${RESET}"
68 + read -rp "Π˜Π½ΡΡ‚Π°Π»ΠΈΡ€Π°ΠΉ Uptime Kuma? (y/n): " install_kuma
69 + validate_yn "$install_kuma"
70 + install_kuma="${install_kuma,,}" # lowercase
71 +
72 + # ── 3. WordPress сайтовС ──────────────────────────────────────────────────────
73 + echo -e "\n${BOLD}[3/4] WordPress сайтовС${RESET}"
74 + read -rp "Π‘Ρ€ΠΎΠΉ WordPress сайтовС? (0/1/2): " wp_count
75 + validate_count "$wp_count"
76 +
77 + # ── 4. Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»ΠΈ ───────────────────────────────────────────────────
78 + echo -e "\n${BOLD}[4/4] Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€ΠΎΠ»ΠΈ...${RESET}"
79 + DB_ROOT_PASS=$(gen_pass)
80 + WP1_DB_PASS=$(gen_pass)
81 + WP2_DB_PASS=$(gen_pass)
82 +
83 + # =============================================================================
84 + # .env Ρ„Π°ΠΉΠ»
85 + # =============================================================================
86 + cat > .env <<EOF
87 + # ── Cloudflare ────────────────────────────────────────────────────
88 + $CF_TOKEN_IN_ENV
89 +
90 + # ── Π‘Π°Π·Π° Π΄Π°Π½Π½ΠΈ ────────────────────────────────────────────────────
91 + DB_ROOT_PASSWORD=$DB_ROOT_PASS
92 + WP1_DB_PASSWORD=$WP1_DB_PASS
93 + WP2_DB_PASSWORD=$WP2_DB_PASS
94 + EOF
95 + chmod 600 .env
96 + success ".env създадСн (ΠΏΡ€Π°Π²Π°: 600)"
97 +
98 + # =============================================================================
99 + # Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° init SQL Π·Π° Π±Π°Π·ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ
100 + # =============================================================================
101 + mkdir -p db-init
102 +
103 + SQL_CONTENT=""
104 + if [[ "$wp_count" -ge 1 ]]; then
105 + SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
106 + SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp1_user'@'%' IDENTIFIED BY '${WP1_DB_PASS}';\n"
107 + SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp1_db.* TO 'wp1_user'@'%';\n"
108 + fi
109 + if [[ "$wp_count" -ge 2 ]]; then
110 + SQL_CONTENT+="CREATE DATABASE IF NOT EXISTS wp2_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
111 + SQL_CONTENT+="CREATE USER IF NOT EXISTS 'wp2_user'@'%' IDENTIFIED BY '${WP2_DB_PASS}';\n"
112 + SQL_CONTENT+="GRANT ALL PRIVILEGES ON wp2_db.* TO 'wp2_user'@'%';\n"
113 + fi
114 + SQL_CONTENT+="FLUSH PRIVILEGES;\n"
115 +
116 + printf "%b" "$SQL_CONTENT" > db-init/01-init.sql
117 + success "db-init/01-init.sql създадСн"
118 +
119 + # =============================================================================
120 + # docker-compose.yml
121 + # =============================================================================
122 + cat > docker-compose.yml <<EOF
123 + services:
124 +
125 + # ── Cloudflare Tunnel ───────────────────────────────────────────
126 + cloudflared:
127 + image: cloudflare/cloudflared:latest
128 + restart: always
129 + command: $CLOUDFLARED_CMD
130 + networks:
131 + - internal
132 + EOF
133 +
134 + # ДобавянС Π½Π° environment само ΠΏΡ€ΠΈ token ΠΌΠ΅Ρ‚ΠΎΠ΄
135 + if [[ -n "$CF_ENV_LINE" ]]; then
136 + cat >> docker-compose.yml <<EOF
137 + environment:
138 + $CF_ENV_LINE
139 + EOF
140 + fi
141 +
142 + # ── MariaDB ────────────────────────────────────────────────────────────────
143 + cat >> docker-compose.yml <<EOF
144 +
145 + # ── Π‘Π°Π·Π° Π΄Π°Π½Π½ΠΈ ──────────────────────────────────────────────────
146 + db:
147 + image: mariadb:10.6
148 + restart: always
149 + environment:
150 + MYSQL_ROOT_PASSWORD: \${DB_ROOT_PASSWORD}
151 + volumes:
152 + - db_data:/var/lib/mysql
153 + - ./db-init:/docker-entrypoint-initdb.d:ro
154 + networks:
155 + - internal
156 + healthcheck:
157 + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
158 + interval: 10s
159 + timeout: 5s
160 + retries: 5
161 + EOF
162 +
163 + # ── Uptime Kuma ────────────────────────────────────────────────────────────
164 + if [[ "$install_kuma" == "y" ]]; then
165 + cat >> docker-compose.yml <<EOF
166 +
167 + # ── Uptime Kuma ─────────────────────────────────────────────────
168 + uptime-kuma:
169 + image: louislam/uptime-kuma:latest
170 + container_name: uptime-kuma
171 + restart: always
172 + volumes:
173 + - kuma_data:/app/data
174 + networks:
175 + - internal
176 + EOF
177 + fi
178 +
179 + # ── WordPress 1 ────────────────────────────────────────────────────────────
180 + if [[ "$wp_count" -ge 1 ]]; then
181 + cat >> docker-compose.yml <<EOF
182 +
183 + # ── WordPress 1 ─────────────────────────────────────────────────
184 + wp1:
185 + image: wordpress:latest
186 + restart: always
187 + depends_on:
188 + db:
189 + condition: service_healthy
190 + environment:
191 + WORDPRESS_DB_HOST: db
192 + WORDPRESS_DB_USER: wp1_user
193 + WORDPRESS_DB_PASSWORD: \${WP1_DB_PASSWORD}
194 + WORDPRESS_DB_NAME: wp1_db
195 + volumes:
196 + - wp1_data:/var/www/html
197 + networks:
198 + - internal
199 + EOF
200 + fi
201 +
202 + # ── WordPress 2 ────────────────────────────────────────────────────────────
203 + if [[ "$wp_count" -ge 2 ]]; then
204 + cat >> docker-compose.yml <<EOF
205 +
206 + # ── WordPress 2 ─────────────────────────────────────────────────
207 + wp2:
208 + image: wordpress:latest
209 + restart: always
210 + depends_on:
211 + db:
212 + condition: service_healthy
213 + environment:
214 + WORDPRESS_DB_HOST: db
215 + WORDPRESS_DB_USER: wp2_user
216 + WORDPRESS_DB_PASSWORD: \${WP2_DB_PASSWORD}
217 + WORDPRESS_DB_NAME: wp2_db
218 + volumes:
219 + - wp2_data:/var/www/html
220 + networks:
221 + - internal
222 + EOF
223 + fi
224 +
225 + # ── Networks & Volumes ─────────────────────────────────────────────────────
226 + cat >> docker-compose.yml <<EOF
227 +
228 + networks:
229 + internal:
230 + driver: bridge
231 +
232 + volumes:
233 + db_data:
234 + EOF
235 +
236 + [[ "$install_kuma" == "y" ]] && echo " kuma_data:" >> docker-compose.yml
237 + [[ "$wp_count" -ge 1 ]] && echo " wp1_data:" >> docker-compose.yml
238 + [[ "$wp_count" -ge 2 ]] && echo " wp2_data:" >> docker-compose.yml
239 +
240 + success "docker-compose.yml създадСн"
241 +
242 + # =============================================================================
243 + # РСзюмС
244 + # =============================================================================
245 + echo ""
246 + echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
247 + echo -e "${BOLD} πŸ“‹ РСзюмС Π½Π° конфигурацията ${RESET}"
248 + echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
249 + echo -e " Cloudflare ΠΌΠ΅Ρ‚ΠΎΠ΄ : ${CYAN}$([ "$cf_method" == "1" ] && echo "Token" || echo "Login")${RESET}"
250 + echo -e " Uptime Kuma : ${CYAN}$([ "$install_kuma" == "y" ] && echo "Π”Π°" || echo "НС")${RESET}"
251 + echo -e " WordPress сайтовС: ${CYAN}$wp_count${RESET}"
252 + echo ""
253 + echo -e "${BOLD} Π€Π°ΠΉΠ»ΠΎΠ²Π΅:${RESET}"
254 + echo " πŸ“„ .env (chmod 600)"
255 + echo " πŸ“„ docker-compose.yml"
256 + echo " πŸ“„ db-init/01-init.sql"
257 + echo ""
258 + echo -e "${BOLD} Π‘Π»Π΅Π΄Π²Π°Ρ‰Π° ΡΡ‚ΡŠΠΏΠΊΠ°:${RESET}"
259 + echo -e " ${GREEN}docker compose up -d${RESET}"
260 + echo ""
261 + warn "Π—Π°ΠΏΠ°Π·ΠΈ .env Ρ„Π°ΠΉΠ»Π° Π½Π° сигурно място β€” ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΏΠ°Ρ€ΠΎΠ»ΠΈΡ‚Π΅!"
262 + echo -e "${BOLD}════════════════════════════════════════════════════${RESET}\n"
Neuer Γ„lter