Files
proxmox-ve-install-scripts/install/huly-install.sh
2025-06-14 01:53:52 +02:00

363 lines
11 KiB
Bash

#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: GitHub Copilot
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/hcengineering/huly-selfhost
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get update
$STD apt-get install -y curl git ca-certificates gnupg nginx lsb-release
msg_ok "Installed Dependencies"
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 "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 "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 "Configuring native Huly setup"
# Get server IP
SERVER_IP=$(hostname -I | awk '{print $1}')
# 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 <<EOF >/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"
# Remove default nginx site
$STD rm -f /etc/nginx/sites-enabled/default
# Create nginx configuration for native Huly
cat <<EOF >/etc/nginx/sites-available/huly.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Frontend
location / {
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;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
$STD ln -sf /etc/nginx/sites-available/huly.conf /etc/nginx/sites-enabled/huly.conf
# Test and reload nginx
if nginx -t >/dev/null 2>&1; then
$STD nginx -s reload
else
msg_error "nginx configuration test failed"
fi
msg_ok "nginx configured"
msg_info "Creating systemd services for Huly components"
# MinIO service
cat <<EOF >/etc/systemd/system/minio.service
[Unit]
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/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
LimitNOFILE=65536
TasksMax=infinity
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
EOF
# Frontend service
cat <<EOF >/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 <<EOF >/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 <<EOF >/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 <<EOF >/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 <<EOF >/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 minio huly-front huly-account huly-transactor huly-collaborator huly-rekoni
msg_ok "Created and started Huly services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
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}"