From e0e329925f5c954fdaa7bbac190e01eb09c25575 Mon Sep 17 00:00:00 2001 From: bilulib Date: Sat, 14 Jun 2025 01:53:52 +0200 Subject: [PATCH] reafctored the whole script --- ct/huly.sh | 36 +++-- install/huly-install.sh | 343 ++++++++++++++++++++++++++++++++++------ json/huly.json | 8 +- 3 files changed, 331 insertions(+), 56 deletions(-) diff --git a/ct/huly.sh b/ct/huly.sh index 134f305..e3830c5 100644 --- a/ct/huly.sh +++ b/ct/huly.sh @@ -23,19 +23,37 @@ function update_script() { header_info check_container_storage check_container_resources - if [[ ! -d /opt/huly-selfhost ]]; then + if [[ ! -d /opt/huly ]]; then msg_error "No ${APP} Installation Found!" exit fi msg_info "Updating $APP" - cd /opt/huly-selfhost || exit - $STD git pull - if [[ -f .env ]]; then - $STD ./config.sh - $STD ./nginx.sh - fi - msg_info "Restarting $APP services" - systemctl restart huly || true + + # Update Huly services by pulling new Docker images and extracting them + $STD systemctl stop minio huly-front huly-account huly-transactor huly-collaborator huly-rekoni + + # Temporarily install Docker for updates + $STD apt-get update + $STD apt-get install -y docker.io + $STD systemctl start docker + + # Update each component + for component in front account transactor collaborator rekoni; do + msg_info "Updating huly-$component" + $STD docker pull hardcoreeng/$component:latest + $STD docker create --name huly-$component-update hardcoreeng/$component:latest + $STD rm -rf /opt/huly/$component/* + $STD docker cp huly-$component-update:/usr/src/app/. /opt/huly/$component/ + $STD docker rm huly-$component-update + done + + # Remove Docker again + $STD systemctl stop docker + $STD apt-get remove -y docker.io + + # Restart services + $STD systemctl start minio huly-front huly-account huly-transactor huly-collaborator huly-rekoni + msg_ok "Updated $APP" exit } diff --git a/install/huly-install.sh b/install/huly-install.sh index f852432..ce58504 100644 --- a/install/huly-install.sh +++ b/install/huly-install.sh @@ -12,50 +12,172 @@ setting_up_container network_check update_os -REPO_URL="https://github.com/hcengineering/huly-selfhost.git" - msg_info "Installing Dependencies" $STD apt-get update -$STD apt-get install -y curl git ca-certificates gnupg nginx python3 python3-venv python3-pip nodejs npm jq build-essential +$STD apt-get install -y curl git ca-certificates gnupg nginx lsb-release msg_ok "Installed Dependencies" -msg_info "Cloning Huly repository" -$STD git clone "$REPO_URL" /opt/huly-selfhost -cd /opt/huly-selfhost || exit 1 -msg_ok "Cloned Huly repository" +msg_info "Installing MongoDB" +# Install MongoDB natively +$STD curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /etc/apt/keyrings/mongodb-server-7.0.gpg +$STD echo "deb [ arch=amd64,arm64 signed-by=/etc/apt/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/debian $(lsb_release -cs)/mongodb-org/7.0 main" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list +$STD apt-get update +$STD apt-get install -y mongodb-org +$STD systemctl enable --now mongod +msg_ok "Installed MongoDB" -msg_info "Setup uv" -setup_uv -msg_ok "Setup uv" +msg_info "Installing Node.js" +# Install Node.js for running Huly services +NODE_VERSION=20 install_node_and_modules +$STD npm install -g web-push +msg_ok "Installed Node.js" -msg_info "Setting up Python environment" -$STD uv venv venv -if [ -f requirements.txt ]; then - $STD uv pip install --python venv/bin/python -r requirements.txt -fi -msg_ok "Python environment ready" +msg_info "Installing Docker temporarily (for extraction)" +# We need Docker temporarily to extract Huly applications +$STD mkdir -p /etc/apt/keyrings +$STD curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg +$STD echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null +$STD apt-get update +$STD apt-get install -y docker-ce docker-ce-cli containerd.io +$STD systemctl start docker +msg_ok "Installed Docker temporarily" -msg_info "Setting up Node.js dependencies (if needed)" -if [ -f package.json ]; then - $STD npm install --omit=dev || true -fi -msg_ok "Node.js dependencies ready" +msg_info "Configuring native Huly setup" +# Get server IP +SERVER_IP=$(hostname -I | awk '{print $1}') -msg_info "Configuring Huly" -if [ -f config.sh ]; then - $STD ./config.sh -fi -msg_ok "Huly configured" +# Generate VAPID keys for push notifications +VAPID_OUTPUT=$(web-push generate-vapid-keys) +PUBLIC_KEY=$(echo "$VAPID_OUTPUT" | grep "Public Key:" | cut -d ":" -f2 | tr -d ' ') +PRIVATE_KEY=$(echo "$VAPID_OUTPUT" | grep "Private Key:" | cut -d ":" -f2 | tr -d ' ') + +# Create MongoDB database and user for Huly +$STD mongosh --eval " +use huly; +db.createUser({ + user: 'huly', + pwd: 'hulypassword123', + roles: [{role: 'readWrite', db: 'huly'}] +}); +" + +# Save configuration and VAPID keys +mkdir -p /opt/huly-selfhost +{ + echo "# Huly Native Configuration" + echo "SERVER_IP=$SERVER_IP" + echo "MONGO_URL=mongodb://huly:hulypassword123@localhost:27017/huly" + echo "MINIO_ENDPOINT=localhost:9000" + echo "MINIO_ACCESS_KEY=minioadmin" + echo "MINIO_SECRET_KEY=minioadmin" + echo "" + echo "# VAPID Keys for Push Notifications" + echo "VAPID_PUBLIC_KEY=$PUBLIC_KEY" + echo "VAPID_PRIVATE_KEY=$PRIVATE_KEY" + echo "" + echo "# Service Ports" + echo "FRONT_PORT=3000" + echo "ACCOUNT_PORT=3001" + echo "TRANSACTOR_PORT=3002" + echo "COLLABORATOR_PORT=3078" + echo "REKONI_PORT=4004" +} >/opt/huly-selfhost/native.conf + +msg_ok "Configured Huly" + +msg_info "Extracting Huly applications from Docker images" +# Create directories for Huly components +mkdir -p /opt/huly/{front,account,transactor,collaborator,rekoni,elastic,minio} + +# Extract Frontend +$STD docker create --name huly-front hardcoreeng/front:latest +$STD docker cp huly-front:/usr/src/app/. /opt/huly/front/ +$STD docker rm huly-front + +# Extract Account Service +$STD docker create --name huly-account hardcoreeng/account:latest +$STD docker cp huly-account:/usr/src/app/. /opt/huly/account/ +$STD docker rm huly-account + +# Extract Transactor +$STD docker create --name huly-transactor hardcoreeng/transactor:latest +$STD docker cp huly-transactor:/usr/src/app/. /opt/huly/transactor/ +$STD docker rm huly-transactor + +# Extract Collaborator (for document collaboration) +$STD docker create --name huly-collaborator hardcoreeng/collaborator:latest +$STD docker cp huly-collaborator:/usr/src/app/. /opt/huly/collaborator/ +$STD docker rm huly-collaborator + +# Extract Rekoni (for file indexing) +$STD docker create --name huly-rekoni hardcoreeng/rekoni:latest +$STD docker cp huly-rekoni:/usr/src/app/. /opt/huly/rekoni/ +$STD docker rm huly-rekoni + +msg_ok "Extracted Huly applications" + +msg_info "Installing MinIO for object storage" +# Download MinIO binary +MINIO_VERSION="RELEASE.2024-06-13T22-53-53Z" +$STD curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.${MINIO_VERSION}" -o /usr/local/bin/minio +$STD chmod +x /usr/local/bin/minio + +# Create MinIO user and directories +useradd -r -s /bin/false minio || true +mkdir -p /opt/minio/data /etc/minio +chown -R minio:minio /opt/minio /etc/minio + +# Create MinIO configuration +cat </etc/minio/minio.conf +MINIO_ROOT_USER=minioadmin +MINIO_ROOT_PASSWORD=minioadmin +MINIO_VOLUMES="/opt/minio/data" +MINIO_OPTS="--console-address :9001" +EOF +msg_ok "Installed MinIO" + +msg_info "Removing Docker" +# Stop and remove Docker since we only needed it for extraction +$STD systemctl stop docker +$STD apt-get remove -y docker-ce docker-ce-cli containerd.io +$STD rm -rf /var/lib/docker +$STD rm -f /etc/apt/sources.list.d/docker.list /etc/apt/keyrings/docker.gpg +msg_ok "Removed Docker" msg_info "Configuring nginx" -# Create our own nginx configuration +# Remove default nginx site +$STD rm -f /etc/nginx/sites-enabled/default + +# Create nginx configuration for native Huly cat </etc/nginx/sites-available/huly.conf server { - listen 80; + listen 80 default_server; + listen [::]:80 default_server; server_name _; + # Frontend location / { - proxy_pass http://127.0.0.1:8080; + proxy_pass http://127.0.0.1:3000; + 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_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Account service + location /account/ { + proxy_pass http://127.0.0.1:3001/; + 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; + } + + # MinIO (file storage) + location /files/ { + proxy_pass http://127.0.0.1:9000/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; @@ -64,35 +186,159 @@ server { } EOF -# Enable the site $STD ln -sf /etc/nginx/sites-available/huly.conf /etc/nginx/sites-enabled/huly.conf -# Test nginx configuration before reloading +# Test and reload nginx if nginx -t >/dev/null 2>&1; then $STD nginx -s reload else - msg_error "nginx configuration test failed, skipping reload" + msg_error "nginx configuration test failed" fi msg_ok "nginx configured" -msg_info "Creating systemd service for Huly" -cat </etc/systemd/system/huly.service +msg_info "Creating systemd services for Huly components" + +# MinIO service +cat </etc/systemd/system/minio.service [Unit] -Description=Huly Web Service -After=network.target +Description=MinIO Object Storage +Documentation=https://docs.min.io +Wants=network-online.target +After=network-online.target +AssertFileIsExecutable=/usr/local/bin/minio [Service] -WorkingDirectory=/opt/huly-selfhost -ExecStart=/usr/bin/python3 -m http.server 8080 +WorkingDirectory=/opt/minio +User=minio +Group=minio +EnvironmentFile=/etc/minio/minio.conf +ExecStartPre=/bin/bash -c "if [ -z \"\${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/minio/minio.conf\"; exit 1; fi" +ExecStart=/usr/local/bin/minio server \$MINIO_OPTS \$MINIO_VOLUMES Restart=always -User=root +LimitNOFILE=65536 +TasksMax=infinity +TimeoutStopSec=infinity +SendSIGKILL=no [Install] WantedBy=multi-user.target EOF + +# Frontend service +cat </etc/systemd/system/huly-front.service +[Unit] +Description=Huly Frontend Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/huly/front +ExecStart=/usr/bin/node dist/bundle.js +Restart=always +User=root +Environment=PORT=3000 +Environment=NODE_ENV=production +Environment=ACCOUNTS_URL=http://localhost:3001 +Environment=UPLOAD_URL=http://localhost:8086/files +Environment=ELASTIC_URL=http://localhost:9200 +Environment=GMAIL_URL=http://localhost:8087 +Environment=CALENDAR_URL=http://localhost:8095 +Environment=REKONI_URL=http://localhost:4004 + +[Install] +WantedBy=multi-user.target +EOF + +# Account service +cat </etc/systemd/system/huly-account.service +[Unit] +Description=Huly Account Service +After=network.target mongod.service +Requires=mongod.service + +[Service] +Type=simple +WorkingDirectory=/opt/huly/account +ExecStart=/usr/bin/node bundle.js +Restart=always +User=root +Environment=PORT=3001 +Environment=MONGO_URL=mongodb://huly:hulypassword123@localhost:27017/huly +Environment=TRANSACTOR_URL=ws://localhost:3002 +Environment=SECRET=secret + +[Install] +WantedBy=multi-user.target +EOF + +# Transactor service +cat </etc/systemd/system/huly-transactor.service +[Unit] +Description=Huly Transactor Service +After=network.target mongod.service minio.service +Requires=mongod.service minio.service + +[Service] +Type=simple +WorkingDirectory=/opt/huly/transactor +ExecStart=/usr/bin/node bundle.js +Restart=always +User=root +Environment=PORT=3002 +Environment=MONGO_URL=mongodb://huly:hulypassword123@localhost:27017/huly +Environment=STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin +Environment=SECRET=secret +Environment=ACCOUNTS_URL=http://localhost:3001 +Environment=REKONI_URL=http://localhost:4004 + +[Install] +WantedBy=multi-user.target +EOF + +# Collaborator service +cat </etc/systemd/system/huly-collaborator.service +[Unit] +Description=Huly Collaborator Service +After=network.target mongod.service +Requires=mongod.service + +[Service] +Type=simple +WorkingDirectory=/opt/huly/collaborator +ExecStart=/usr/bin/node dist/bundle.js +Restart=always +User=root +Environment=PORT=3078 +Environment=MONGO_URL=mongodb://huly:hulypassword123@localhost:27017/huly +Environment=SECRET=secret + +[Install] +WantedBy=multi-user.target +EOF + +# Rekoni service (file processing) +cat </etc/systemd/system/huly-rekoni.service +[Unit] +Description=Huly Rekoni Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/huly/rekoni +ExecStart=/usr/bin/node bundle.js +Restart=always +User=root +Environment=PORT=4004 +Environment=SECRET=secret + +[Install] +WantedBy=multi-user.target +EOF + +# Enable and start all services systemctl daemon-reload -systemctl enable --now huly -msg_ok "Created and started Huly service" +systemctl enable --now minio huly-front huly-account huly-transactor huly-collaborator huly-rekoni +msg_ok "Created and started Huly services" motd_ssh customize @@ -102,6 +348,15 @@ $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" -echo -e "${INFO}${YW} Your Huly instance is now running!${CL}" -echo -e "${INFO}${YW} Access it at: http://$(hostname -I | awk '{print $1}')${CL}" -echo -e "${INFO}${YW} For additional configuration, see /opt/huly-selfhost and the official docs.${CL}" +echo -e "${INFO}${YW} Huly native installation completed successfully!${CL}" +echo -e "${INFO}${YW} Access URL: http://$SERVER_IP${CL}" +echo -e "${INFO}${YW} Services may take a few minutes to fully start.${CL}" +echo -e "" +echo -e "${INFO}${YW} Service Status Commands:${CL}" +echo -e "${INFO}${YW} • Check all services: systemctl status minio huly-front huly-account huly-transactor${CL}" +echo -e "${INFO}${YW} • View frontend logs: journalctl -f -u huly-front${CL}" +echo -e "${INFO}${YW} • View account logs: journalctl -f -u huly-account${CL}" +echo -e "${INFO}${YW} • MinIO Console: http://$SERVER_IP:9001 (minioadmin/minioadmin)${CL}" +echo -e "" +echo -e "${INFO}${YW} Configuration saved to: /opt/huly-selfhost/native.conf${CL}" +echo -e "${INFO}${YW} VAPID keys included in configuration for push notifications${CL}" diff --git a/json/huly.json b/json/huly.json index 7e6f206..a58b5ce 100644 --- a/json/huly.json +++ b/json/huly.json @@ -10,7 +10,7 @@ "documentation": "https://github.com/hcengineering/huly-selfhost", "website": "https://github.com/hcengineering/huly-selfhost", "logo": "https://raw.githubusercontent.com/hcengineering/huly-selfhost/master/logo.png", - "description": "Self-hosted collaboration platform with chat, video calls, and AI-powered features. This helper installs Huly directly in an LXC without Docker.", + "description": "Self-hosted collaboration platform with chat, video calls, and AI-powered features. Native installation without Docker.", "install_methods": [ { "type": "default", @@ -30,7 +30,9 @@ }, "notes": [ "Huly is resource-intensive. At least 2 vCPUs and 4GB RAM are recommended.", - "After installation, configure email, audio/video, and AI features as described in the documentation.", - "This script installs Huly directly in the LXC, not via Docker." + "This installation runs Huly natively without Docker containers.", + "Includes MongoDB, MinIO object storage, and all Huly microservices.", + "Services: Frontend (3000), Account (3001), Transactor (3002), Collaborator (3078), Rekoni (4004)", + "MinIO console available at port 9001 (minioadmin/minioadmin)" ] }