300 lines
10 KiB
Bash
Executable file
300 lines
10 KiB
Bash
Executable file
#!/bin/bash
|
|
# Deploy a Veza service to Incus without Docker (native deployment)
|
|
# Usage: ./deploy-service-native.sh <service-name>
|
|
|
|
set -e
|
|
|
|
SERVICE=$1
|
|
PROJECT_NAME="veza"
|
|
NETWORK="veza-network"
|
|
PROFILE="veza-profile"
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
BUILD_DIR="${PROJECT_ROOT}/.build/incus"
|
|
|
|
if [ -z "$SERVICE" ]; then
|
|
echo "Usage: $0 <service-name>"
|
|
echo "Services: backend-api, chat-server, stream-server, web, haproxy, infra"
|
|
exit 1
|
|
fi
|
|
|
|
CONTAINER_NAME="${PROJECT_NAME}-${SERVICE}"
|
|
|
|
echo "📦 Deploying ${SERVICE} to Incus (native, no Docker)..."
|
|
|
|
# Check if network exists
|
|
if ! incus network show ${NETWORK} >/dev/null 2>&1; then
|
|
echo "Creating network ${NETWORK}..."
|
|
incus network create ${NETWORK} \
|
|
ipv4.address=10.10.10.1/24 \
|
|
ipv4.nat=true
|
|
fi
|
|
|
|
# Check if profile exists
|
|
if ! incus profile show ${PROFILE} >/dev/null 2>&1; then
|
|
echo "Creating profile ${PROFILE}..."
|
|
incus profile create ${PROFILE}
|
|
incus profile device add ${PROFILE} eth0 nic network=${NETWORK}
|
|
fi
|
|
|
|
# Delete existing container if it exists
|
|
if incus list -c n --format csv | grep -q "^${CONTAINER_NAME}$"; then
|
|
echo "Removing existing container ${CONTAINER_NAME}..."
|
|
incus delete ${CONTAINER_NAME} --force
|
|
fi
|
|
|
|
# Create and start container
|
|
echo "Creating container ${CONTAINER_NAME}..."
|
|
incus init images:ubuntu/22.04 ${CONTAINER_NAME} --profile ${PROFILE}
|
|
incus start ${CONTAINER_NAME}
|
|
|
|
# Wait for container to be ready
|
|
echo "Waiting for container to be ready..."
|
|
sleep 5
|
|
|
|
# Configure static IP based on service
|
|
case ${SERVICE} in
|
|
backend-api)
|
|
STATIC_IP="10.10.10.2"
|
|
;;
|
|
chat-server)
|
|
STATIC_IP="10.10.10.3"
|
|
;;
|
|
stream-server)
|
|
STATIC_IP="10.10.10.4"
|
|
;;
|
|
web)
|
|
STATIC_IP="10.10.10.5"
|
|
;;
|
|
haproxy)
|
|
STATIC_IP="10.10.10.6"
|
|
;;
|
|
infra)
|
|
STATIC_IP="10.10.10.10"
|
|
;;
|
|
*)
|
|
STATIC_IP=""
|
|
;;
|
|
esac
|
|
|
|
# Set static IP if configured
|
|
if [ -n "${STATIC_IP}" ]; then
|
|
echo "Configuring static IP ${STATIC_IP}..."
|
|
incus config device set ${CONTAINER_NAME} eth0 ipv4.address=${STATIC_IP}
|
|
incus restart ${CONTAINER_NAME}
|
|
sleep 3
|
|
fi
|
|
|
|
# Install base dependencies
|
|
echo "Installing base dependencies..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y -qq curl wget ca-certificates systemd systemd-sysv
|
|
"
|
|
|
|
# Service-specific deployment
|
|
case ${SERVICE} in
|
|
backend-api)
|
|
echo "Installing Go runtime dependencies..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq ca-certificates libc6
|
|
"
|
|
|
|
# Copy binary
|
|
echo "Copying backend-api binary..."
|
|
if [ ! -f "${BUILD_DIR}/veza-backend-api" ]; then
|
|
echo "ERROR: Binary not found at ${BUILD_DIR}/veza-backend-api"
|
|
echo "Please run: make build-all-native or ./config/incus/build-native.sh backend-api"
|
|
exit 1
|
|
fi
|
|
incus file push "${BUILD_DIR}/veza-backend-api" ${CONTAINER_NAME}/usr/local/bin/veza-backend-api
|
|
incus exec ${CONTAINER_NAME} -- chmod +x /usr/local/bin/veza-backend-api
|
|
|
|
# Create directories
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
mkdir -p /opt/veza/backend-api
|
|
mkdir -p /var/log/veza
|
|
mkdir -p /etc/veza
|
|
"
|
|
|
|
# Copy systemd service
|
|
incus file push "${PROJECT_ROOT}/config/incus/systemd/veza-backend-api.service" \
|
|
${CONTAINER_NAME}/etc/systemd/system/veza-backend-api.service
|
|
|
|
# Copy environment file template
|
|
incus file push "${PROJECT_ROOT}/config/incus/env/backend-api.env" \
|
|
${CONTAINER_NAME}/etc/veza/backend-api.env 2>/dev/null || true
|
|
|
|
# Enable and start service
|
|
incus exec ${CONTAINER_NAME} -- systemctl daemon-reload
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable veza-backend-api
|
|
;;
|
|
|
|
chat-server)
|
|
echo "Installing Rust runtime dependencies..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq ca-certificates libc6 libssl3
|
|
"
|
|
|
|
# Copy binary
|
|
echo "Copying chat-server binary..."
|
|
if [ ! -f "${BUILD_DIR}/veza-chat-server" ]; then
|
|
echo "ERROR: Binary not found at ${BUILD_DIR}/veza-chat-server"
|
|
echo "Please run: make build-all-native or ./config/incus/build-native.sh chat-server"
|
|
exit 1
|
|
fi
|
|
incus file push "${BUILD_DIR}/veza-chat-server" ${CONTAINER_NAME}/usr/local/bin/veza-chat-server
|
|
incus exec ${CONTAINER_NAME} -- chmod +x /usr/local/bin/veza-chat-server
|
|
|
|
# Create directories
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
mkdir -p /opt/veza/chat-server
|
|
mkdir -p /var/log/veza
|
|
mkdir -p /etc/veza
|
|
"
|
|
|
|
# Copy systemd service
|
|
incus file push "${PROJECT_ROOT}/config/incus/systemd/veza-chat-server.service" \
|
|
${CONTAINER_NAME}/etc/systemd/system/veza-chat-server.service
|
|
|
|
# Copy environment file template
|
|
incus file push "${PROJECT_ROOT}/config/incus/env/chat-server.env" \
|
|
${CONTAINER_NAME}/etc/veza/chat-server.env 2>/dev/null || true
|
|
|
|
# Enable and start service
|
|
incus exec ${CONTAINER_NAME} -- systemctl daemon-reload
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable veza-chat-server
|
|
;;
|
|
|
|
stream-server)
|
|
echo "Installing Rust runtime dependencies..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq ca-certificates libc6 libssl3
|
|
"
|
|
|
|
# Copy binary
|
|
echo "Copying stream-server binary..."
|
|
if [ ! -f "${BUILD_DIR}/veza-stream-server" ]; then
|
|
echo "ERROR: Binary not found at ${BUILD_DIR}/veza-stream-server"
|
|
echo "Please run: make build-all-native or ./config/incus/build-native.sh stream-server"
|
|
exit 1
|
|
fi
|
|
incus file push "${BUILD_DIR}/veza-stream-server" ${CONTAINER_NAME}/usr/local/bin/veza-stream-server
|
|
incus exec ${CONTAINER_NAME} -- chmod +x /usr/local/bin/veza-stream-server
|
|
|
|
# Create directories
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
mkdir -p /opt/veza/stream-server
|
|
mkdir -p /opt/veza/stream-server/audio
|
|
mkdir -p /var/log/veza
|
|
mkdir -p /etc/veza
|
|
"
|
|
|
|
# Copy systemd service
|
|
incus file push "${PROJECT_ROOT}/config/incus/systemd/veza-stream-server.service" \
|
|
${CONTAINER_NAME}/etc/systemd/system/veza-stream-server.service
|
|
|
|
# Copy environment file template
|
|
incus file push "${PROJECT_ROOT}/config/incus/env/stream-server.env" \
|
|
${CONTAINER_NAME}/etc/veza/stream-server.env 2>/dev/null || true
|
|
|
|
# Enable and start service
|
|
incus exec ${CONTAINER_NAME} -- systemctl daemon-reload
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable veza-stream-server
|
|
;;
|
|
|
|
web)
|
|
echo "Installing web server (Apache/httpd)..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq apache2
|
|
"
|
|
|
|
# Copy web files
|
|
echo "Copying web frontend files..."
|
|
if [ ! -d "${BUILD_DIR}/web" ] || [ ! -f "${BUILD_DIR}/web/index.html" ]; then
|
|
echo "ERROR: Web build not found at ${BUILD_DIR}/web"
|
|
echo "Please run: make build-all-native or ./config/incus/build-native.sh web"
|
|
exit 1
|
|
fi
|
|
incus exec ${CONTAINER_NAME} -- mkdir -p /var/www/veza
|
|
incus file push -r "${BUILD_DIR}/web"/* ${CONTAINER_NAME}/var/www/veza/
|
|
|
|
# Copy Apache config
|
|
incus file push "${PROJECT_ROOT}/config/incus/apache/veza-web.conf" \
|
|
${CONTAINER_NAME}/etc/apache2/sites-available/veza-web.conf
|
|
|
|
# Enable Apache site and modules
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
a2enmod rewrite
|
|
a2enmod headers
|
|
a2enmod expires
|
|
a2enmod deflate
|
|
a2dissite 000-default
|
|
a2ensite veza-web
|
|
apache2ctl configtest
|
|
"
|
|
|
|
# Enable and start Apache
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable apache2
|
|
;;
|
|
|
|
haproxy)
|
|
echo "Installing HAProxy..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq haproxy
|
|
"
|
|
|
|
# Copy HAProxy config (Incus-specific)
|
|
incus file push "${PROJECT_ROOT}/config/incus/haproxy.cfg" \
|
|
${CONTAINER_NAME}/etc/haproxy/haproxy.cfg
|
|
|
|
# Configure HAProxy to start
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
echo 'ENABLED=1' > /etc/default/haproxy
|
|
"
|
|
|
|
# Enable and start HAProxy
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable haproxy
|
|
;;
|
|
|
|
infra)
|
|
echo "Installing infrastructure services (PostgreSQL, Redis)..."
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq postgresql redis-server
|
|
"
|
|
|
|
# Configure PostgreSQL
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
sudo -u postgres psql -c \"CREATE USER veza WITH PASSWORD 'password';\" || true
|
|
sudo -u postgres psql -c \"CREATE DATABASE veza OWNER veza;\" || true
|
|
sudo -u postgres psql -c \"GRANT ALL PRIVILEGES ON DATABASE veza TO veza;\" || true
|
|
"
|
|
|
|
# Configure Redis
|
|
incus exec ${CONTAINER_NAME} -- bash -c "
|
|
sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' /etc/redis/redis.conf || true
|
|
"
|
|
|
|
# Enable services
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable postgresql
|
|
incus exec ${CONTAINER_NAME} -- systemctl enable redis-server
|
|
;;
|
|
|
|
*)
|
|
echo "Unknown service: ${SERVICE}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo "✅ ${SERVICE} deployed successfully!"
|
|
echo "Container: ${CONTAINER_NAME}"
|
|
echo "Access: incus exec ${CONTAINER_NAME} -- bash"
|
|
echo ""
|
|
echo "To start the service:"
|
|
echo " incus exec ${CONTAINER_NAME} -- systemctl start veza-${SERVICE}"
|