/
parkovki
/
frontend
Обзор
Документация
Войти
/
parkovki
/
frontend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
main
scripts/setup-server.sh
422 строки
13 KB
Ivan
feat: add INTERNAL_API_URL to .env.example and setup-server.sh docker-compose setup
11 авг 2026, 20:36
11 авг 2026, 20:36
f181e89
Код
Авторство
О чём код?
#!/usr/bin/env bash # ============================================================================== # Parkovki Application Stack — Autonomous 1-Click Server Setup Script # ============================================================================== # Supported OS: Ubuntu 22.04 / 24.04 LTS # Usage: # chmod +x setup-server.sh # ./setup-server.sh # ============================================================================== set -e # Colors for terminal output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}=====================================================${NC}" echo -e "${BLUE} Parkovki Stack — Automated Server Deployment ${NC}" echo -e "${BLUE}=====================================================${NC}" # Ensure root privileges if [ "$EUID" -ne 0 ]; then echo -e "${RED}[ERROR] This script must be run as root.${NC}" exit 1 fi INSTALL_DIR="/opt/parkovki" SERVER_IP=$(curl -s https://api.ipify.org || hostname -I | awk '{print $1}') BASIC_AUTH_PASS="${BASIC_AUTH_PASS:-[REDACTED]}" echo -e "${GREEN}--> Server IP detected: ${SERVER_IP}${NC}" echo -e "${GREEN}--> Target directory: ${INSTALL_DIR}${NC}" # Step 1: Install system packages & Docker Engine echo -e "\n${YELLOW}[1/6] Installing system packages & Docker...${NC}" apt-get update -y apt-get install -y curl wget git htop btop ufw ca-certificates gnupg openssl if ! command -v docker &> /dev/null; then echo -e "${GREEN}--> Setting up Docker repository...${NC}" install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME") echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu ${CODENAME} stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null apt-get update -y DEBIAN_FRONTEND=noninteractive apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fi echo -e "${GREEN}--> Docker version: $(docker --version)${NC}" # Step 2: Configure UFW Firewall echo -e "\n${YELLOW}[2/6] Configuring UFW Firewall...${NC}" ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw allow 9000/tcp echo "y" | ufw enable || true # Step 3: Clone or update repositories echo -e "\n${YELLOW}[3/6] Fetching source code repositories...${NC}" mkdir -p "$INSTALL_DIR" if [ -d "$INSTALL_DIR/backend/.git" ]; then echo -e "${GREEN}--> Updating Backend repository...${NC}" cd "$INSTALL_DIR/backend" && git pull else echo -e "${GREEN}--> Cloning Backend repository...${NC}" rm -rf "$INSTALL_DIR/backend" git clone https://gitverse.ru/parkovki/backend.git "$INSTALL_DIR/backend" fi if [ -d "$INSTALL_DIR/frontend/.git" ]; then echo -e "${GREEN}--> Updating Frontend repository...${NC}" cd "$INSTALL_DIR/frontend" && git pull else echo -e "${GREEN}--> Cloning Frontend repository...${NC}" rm -rf "$INSTALL_DIR/frontend" git clone https://gitverse.ru/parkovki/frontend.git "$INSTALL_DIR/frontend" fi # Step 4: Generate Configuration Files (.env, nginx.conf, htpasswd, docker-compose.yml) echo -e "\n${YELLOW}[4/6] Generating environment & proxy configurations...${NC}" cd "$INSTALL_DIR" # Generate .env if not present if [ ! -f "$INSTALL_DIR/.env" ]; then echo -e "${GREEN}--> Generating new secure .env secrets...${NC}" DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9') JWT_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9') ENCRYPT_KEY=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9') cat <<EOF > "$INSTALL_DIR/.env" NODE_ENV=production PORT=3000 # Frontend Yandex Integration Keys NG_APP_YANDEX_OAUTH_CLIENT_ID= NG_APP_YANDEX_MAPS_API_KEY= NG_APP_YANDEX_MAPS_SUGGEST_API_KEY= POSTGRES_DB=parkrent POSTGRES_USER=parkrent_user POSTGRES_PASSWORD=${DB_PASS} DB_HOST=postgres DB_PORT=5432 DB_USERNAME=parkrent_user DB_PASSWORD=${DB_PASS} DB_DATABASE=parkrent JWT_ACCESS_SECRET=${JWT_SECRET} PAYMENT_CONFIG_ENCRYPTION_KEY=${ENCRYPT_KEY} CORS_ORIGINS=http://${SERVER_IP},http://localhost EOF else echo -e "${GREEN}--> Preserving existing .env file.${NC}" fi # Create HTTP Basic Auth htpasswd openssl passwd -apr1 "${BASIC_AUTH_PASS}" > "$INSTALL_DIR/nginx.htpasswd.raw" echo -n 'admin:' > "$INSTALL_DIR/nginx.htpasswd" cat "$INSTALL_DIR/nginx.htpasswd.raw" >> "$INSTALL_DIR/nginx.htpasswd" rm -f "$INSTALL_DIR/nginx.htpasswd.raw" # Create Nginx configuration cat <<EOF > "$INSTALL_DIR/nginx.conf" events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; client_max_body_size 50M; upstream frontend { server frontend:4000; } upstream backend { server backend:3000; } upstream netdata { server netdata:19999; } upstream dozzle { server dozzle:8080; } server { listen 80; server_name _ xn--80aesgbwej.online xn--80aaf5abwej.space xn--80aaf5abwej.online *.online *.space; # Anti-indexing headers for search engine crawlers (Google, Yandex, Bing) add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive" always; # Robots.txt route blocking all bots location = /robots.txt { default_type text/plain; return 200 "User-agent: *\\nDisallow: /\\n"; } # Protected Swagger API Docs location ~ ^/v1/docs { auth_basic "Protected Staging Swagger Docs"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } # Redirect /logs to /logs/ location = /logs { return 301 /logs/; } # Protected Dozzle Live Logs Proxy (/logs/) location /logs/ { auth_basic "Protected Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://dozzle; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } # Protected Netdata Metrics Proxy (/netdata/) location /netdata/ { auth_basic "Protected Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://netdata/; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } # API requests location /v1/ { proxy_pass http://backend/v1/; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_cache_bypass \$http_upgrade; } # Frontend SSR requests location / { proxy_pass http://frontend; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_cache_bypass \$http_upgrade; } } } EOF # Create docker-compose.yml cat <<EOF > "$INSTALL_DIR/docker-compose.yml" services: postgres: image: postgres:16-alpine container_name: parkovki_postgres restart: always environment: POSTGRES_DB: \${POSTGRES_DB} POSTGRES_USER: \${POSTGRES_USER} POSTGRES_PASSWORD: \${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U \${POSTGRES_USER} -d \${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 10 backend: build: context: ./backend/parkrent_api dockerfile: Dockerfile container_name: parkovki_backend restart: always depends_on: postgres: condition: service_healthy env_file: - .env command: > sh -c "npx typeorm migration:run -d dist/data-source.js && node dist/main.js" expose: - "3000" frontend: build: context: ./frontend dockerfile: Dockerfile container_name: parkovki_frontend restart: always env_file: - .env environment: - PORT=4000 - INTERNAL_API_URL=${INTERNAL_API_URL:-http://backend:3000} expose: - "4000" nginx: image: nginx:alpine container_name: parkovki_nginx restart: always ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx.htpasswd:/etc/nginx/.htpasswd:ro depends_on: - backend - frontend portainer: image: portainer/portainer-ce:latest container_name: parkovki_portainer restart: always command: -H unix:///var/run/docker.sock ports: - "9000:9000" volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data dozzle: image: amir20/dozzle:latest container_name: parkovki_dozzle restart: always environment: DOZZLE_BASE: /logs expose: - "8080" ports: - "8888:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock netdata: image: netdata/netdata:stable container_name: parkovki_netdata restart: always hostname: parkovki-server environment: - NETDATA_UPDATE_EVERY=3 ports: - "19999:19999" cap_add: - SYS_PTRACE security_opt: - apparmor:unconfined volumes: - netdataconfig:/etc/netdata - netdatalib:/var/lib/netdata - netdatacache:/var/cache/netdata - /etc/passwd:/host/etc/passwd:ro - /etc/group:/host/etc/group:ro - /proc:/host/proc:ro - /sys:/host/sys:ro - /etc/os-release:/host/etc/os-release:ro - /var/run/docker.sock:/var/run/docker.sock:ro postfix: build: context: ./postfix dockerfile: Dockerfile container_name: parkovki_postfix restart: always dns: - 8.8.8.8 - 1.1.1.1 ports: - "25:25" - "587:587" volumes: - postfix_keys:/etc/opendkim/keys - ./postfix/main.cf:/etc/postfix/main.cf:ro - ./postfix/master.cf:/etc/postfix/master.cf:ro - ./postfix/recipient_bcc:/etc/postfix/recipient_bcc:ro minio: image: minio/minio:latest container_name: parkovki_minio restart: always command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - "9002:9000" - "9001:9001" volumes: - minio_data:/data volumes: postgres_data: portainer_data: netdataconfig: netdatalib: netdatacache: minio_data: postfix_keys: EOF # Step 5: Launch Containers echo -e "\n${YELLOW}[5/6] Building & launching Docker containers...${NC}" cd "$INSTALL_DIR" docker compose up -d --build # Create Netdata monitoring user in Postgres echo -e "\n${YELLOW}[6/6] Configuring Postgres Netdata monitoring role...${NC}" sleep 3 docker exec -i parkovki_postgres psql -U parkrent_user -d parkrent -c "CREATE USER netdata WITH PASSWORD 'netdata';" || true docker exec -i parkovki_postgres psql -U parkrent_user -d parkrent -c "GRANT pg_monitor TO netdata;" || true echo -e "\n${GREEN}=====================================================${NC}" echo -e "${GREEN} Parkovki Stack — Deployment Completed! ${NC}" echo -e "${GREEN}=====================================================${NC}" echo -e "Frontend: http://${SERVER_IP}/" echo -e "Backend API: http://${SERVER_IP}/v1/" echo -e "Swagger Docs: http://${SERVER_IP}/v1/docs (Auth: admin / ${BASIC_AUTH_PASS})" echo -e "Live Logs (Dozzle): http://${SERVER_IP}/logs (Auth: admin / ${BASIC_AUTH_PASS})" echo -e "Netdata Metrics: http://${SERVER_IP}/netdata/ (Auth: admin / ${BASIC_AUTH_PASS})" echo -e "Portainer: http://${SERVER_IP}:9000/" echo -e "${GREEN}=====================================================${NC}"