diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a20c18b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +dist +.env +.env.test +.git +.github +recordings +*.db +*.db-shm +*.db-wal +test_out.nut diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..ffa23e8 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,30 @@ +name: Deploy to VPS + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Deploy via SSH + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.VPS_HOST }} + username: ${{ secrets.VPS_USERNAME }} + key: ${{ secrets.VPS_SSH_KEY }} + script: | + # Modify this path to where your project is stored on the VPS + cd /opt/imphenbot || exit + + # Pull latest changes + git pull origin main + + # Build and restart containers + docker-compose up -d --build diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..be1f94e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM node:22-bookworm-slim + +# Install dependencies required by node-canvas, ffmpeg, and yt-dlp +RUN apt-get update && apt-get install -y \ + ffmpeg \ + python3 \ + curl \ + git \ + make \ + g++ \ + && rm -rf /var/lib/apt/lists/* + +# Install yt-dlp +RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp && \ + chmod a+rx /usr/local/bin/yt-dlp + +# Enable pnpm +RUN corepack enable + +WORKDIR /app + +# Install dependencies first for better caching +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* ./ +RUN pnpm install --frozen-lockfile + +# Copy the rest of the application +COPY . . + +# Build step if required (e.g. build:web) +RUN pnpm run build:web || true + +# Set node environment +ENV NODE_ENV=production + +# Start the application +CMD ["pnpm", "run", "start"] diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..bebe215 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Configuration for CLI deployment +VPS_HOST="45.127.35.244" +VPS_USER="root" +# Find first available private key in ~/.ssh or use specific one if you want to hardcode +SSH_KEY_PATH=$(find ~/.ssh -name "id_rsa" -o -name "id_ed25519" | head -n 1) + +echo "🚀 Starting CLI deployment to $VPS_USER@$VPS_HOST..." + +if [ -z "$SSH_KEY_PATH" ]; then + echo "⚠️ No SSH key found in ~/.ssh. Falling back to default SSH behavior." + SSH_CMD="ssh -o StrictHostKeyChecking=no $VPS_USER@$VPS_HOST" + RSYNC_CMD="rsync -avz --exclude-from='.dockerignore' -e 'ssh -o StrictHostKeyChecking=no'" +else + echo "🔑 Using SSH key: $SSH_KEY_PATH" + SSH_CMD="ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no $VPS_USER@$VPS_HOST" + RSYNC_CMD="rsync -avz --exclude-from='.dockerignore' -e 'ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no'" +fi + +# Directory on the VPS where the app will be deployed +REMOTE_DIR="/opt/imphenbot" + +echo "📦 Syncing files to VPS..." +$SSH_CMD "mkdir -p $REMOTE_DIR" +eval "$RSYNC_CMD ./ $VPS_USER@$VPS_HOST:$REMOTE_DIR" + +echo "🔄 Rebuilding and restarting Docker containers..." +$SSH_CMD << EOF + cd $REMOTE_DIR + docker-compose up -d --build +EOF + +echo "✅ Deployment complete!" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2be7a40 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' + +services: + app: + build: . + container_name: imphenbot-app + restart: unless-stopped + env_file: + - .env + volumes: + - ./recordings:/app/recordings + # Mapping SQLite database files if needed, or storing them in a dedicated volume. + # Assuming default config uses root directory for DB. + - ./.muxer-queue.db:/app/.muxer-queue.db + - ./.muxer-queue.db-shm:/app/.muxer-queue.db-shm + - ./.muxer-queue.db-wal:/app/.muxer-queue.db-wal + labels: + - "traefik.enable=true" + - "traefik.http.routers.imphenbot.rule=Host(`imphnen.asepharyana.tech`)" + - "traefik.http.routers.imphenbot.entrypoints=websecure" + - "traefik.http.routers.imphenbot.tls=true" + # Expose port to traefik (adjust if WEBSERVER_PORT differs) + - "traefik.http.services.imphenbot.loadbalancer.server.port=3000" + networks: + - app-shared-net + +networks: + app-shared-net: + name: app-shared-net + external: true