-
Notifications
You must be signed in to change notification settings - Fork 109
Add self-hosting support with remote server and GitHub Actions build #461
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| name: Build Self-Hosted | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| server_url: | ||
| description: 'Your server URL (e.g., http://myserver:3001)' | ||
| required: true | ||
| type: string | ||
| build_mac_arm64: | ||
| description: 'Build for macOS (Apple Silicon)' | ||
| default: true | ||
| type: boolean | ||
| build_mac_x64: | ||
| description: 'Build for macOS (Intel)' | ||
| default: false | ||
| type: boolean | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build-mac-arm64: | ||
| if: ${{ inputs.build_mac_arm64 }} | ||
| runs-on: macos-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Bun | ||
| uses: oven-sh/setup-bun@v1 | ||
|
|
||
| - name: Install dependencies | ||
| run: bun install | ||
|
|
||
| - name: Set up Rust | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| toolchain: stable | ||
| targets: 'aarch64-apple-darwin' | ||
|
|
||
| - name: Build native Rust modules (arm64) | ||
| run: | | ||
| for module in global-key-listener audio-recorder text-writer active-application selected-text-reader; do | ||
| echo "Building $module for arm64..." | ||
| cd native/$module | ||
| cargo build --release --target aarch64-apple-darwin | ||
| cd ../.. | ||
| done | ||
|
|
||
| - name: Set up environment for self-hosted | ||
| run: | | ||
| echo "VITE_GRPC_BASE_URL=\"${{ inputs.server_url }}\"" >> .env | ||
| echo "VITE_ITO_ENV=\"dev\"" >> .env | ||
| echo "ITO_ENV=\"dev\"" >> .env | ||
| echo "CSC_IDENTITY_AUTO_DISCOVERY=false" >> .env | ||
| cat .env | ||
|
|
||
| - name: Build Electron app | ||
| run: bun run electron-vite build | ||
|
|
||
| - name: Package macOS DMG (arm64) | ||
| env: | ||
| CSC_IDENTITY_AUTO_DISCOVERY: false | ||
| run: | | ||
| bunx electron-builder --config electron-builder.config.js --mac dmg --arm64 --publish=never | ||
|
|
||
| - name: Rename artifact with server info | ||
| run: | | ||
| # Extract hostname from URL for naming | ||
| SERVER_HOST=$(echo "${{ inputs.server_url }}" | sed 's|.*://||' | sed 's|:.*||' | sed 's|/.*||') | ||
| mv dist/Ito-Installer.dmg "dist/Ito-selfhosted-${SERVER_HOST}-arm64.dmg" || true | ||
| ls -la dist/*.dmg | ||
|
|
||
| - name: Upload macOS DMG (arm64) | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: Ito-macOS-arm64 | ||
| path: dist/*.dmg | ||
|
|
||
| build-mac-x64: | ||
| if: ${{ inputs.build_mac_x64 }} | ||
| runs-on: macos-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Bun | ||
| uses: oven-sh/setup-bun@v1 | ||
|
|
||
| - name: Install dependencies | ||
| run: bun install | ||
|
|
||
| - name: Set up Rust | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| toolchain: stable | ||
| targets: 'x86_64-apple-darwin' | ||
|
|
||
| - name: Build native Rust modules (x64) | ||
| run: | | ||
| for module in global-key-listener audio-recorder text-writer active-application selected-text-reader; do | ||
| echo "Building $module for x64..." | ||
| cd native/$module | ||
| cargo build --release --target x86_64-apple-darwin | ||
| cd ../.. | ||
| done | ||
|
|
||
| - name: Set up environment for self-hosted | ||
| run: | | ||
| echo "VITE_GRPC_BASE_URL=\"${{ inputs.server_url }}\"" >> .env | ||
| echo "VITE_ITO_ENV=\"dev\"" >> .env | ||
| echo "ITO_ENV=\"dev\"" >> .env | ||
| echo "CSC_IDENTITY_AUTO_DISCOVERY=false" >> .env | ||
| cat .env | ||
|
|
||
| - name: Build Electron app | ||
| run: bun run electron-vite build | ||
|
|
||
| - name: Package macOS DMG (x64) | ||
| env: | ||
| CSC_IDENTITY_AUTO_DISCOVERY: false | ||
| run: | | ||
| bunx electron-builder --config electron-builder.config.js --mac dmg --x64 --publish=never | ||
|
|
||
| - name: Rename artifact with server info | ||
| run: | | ||
| SERVER_HOST=$(echo "${{ inputs.server_url }}" | sed 's|.*://||' | sed 's|:.*||' | sed 's|/.*||') | ||
| mv dist/Ito-Installer.dmg "dist/Ito-selfhosted-${SERVER_HOST}-x64.dmg" || true | ||
| ls -la dist/*.dmg | ||
|
|
||
| - name: Upload macOS DMG (x64) | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: Ito-macOS-x64 | ||
| path: dist/*.dmg | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -249,6 +249,105 @@ bun run lint:fix # Fix linting issues | |
|
|
||
| --- | ||
|
|
||
| ## 🏠 Self-Hosting | ||
|
|
||
| This fork includes support for self-hosting Ito with a remote server. Instead of using the managed cloud service, you can run your own server and connect to it from anywhere. | ||
|
|
||
| ### Server Setup | ||
|
|
||
| 1. **Clone and configure the server**: | ||
| ```bash | ||
| git clone https://github.com/evoleinik/ito.git | ||
| cd ito/server | ||
| cp .env.example .env | ||
| ``` | ||
|
|
||
| 2. **Edit `.env`** with your settings: | ||
| ```bash | ||
| PORT=3001 # Use 3001 if 3000 is in use | ||
| DB_HOST=db | ||
| DB_USER=ito | ||
| DB_PASS=your-secure-password | ||
| GROQ_API_KEY=your-groq-api-key # Get from console.groq.com | ||
| S3_ENDPOINT=http://minio:9000 | ||
| REQUIRE_AUTH=false # For personal use | ||
| ``` | ||
|
|
||
| 3. **Start the server** (requires Docker): | ||
| ```bash | ||
| docker compose up -d --build | ||
| ``` | ||
|
|
||
| 4. **Run database migrations**: | ||
| ```bash | ||
| docker exec -it ito-server node ./node_modules/node-pg-migrate/bin/node-pg-migrate.js up | ||
| ``` | ||
|
Comment on lines
+283
to
+284
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Check if the migration script exists at the documented path
fd -t f "node-pg-migrate.js" server/Repository: heyito/ito Length of output: 36 🏁 Script executed: # Also check the overall directory structure and package.json
cat -n package.json | head -50Repository: heyito/ito Length of output: 2673 🏁 Script executed: # Look for node-pg-migrate in node_modules or check if it's installed
fd -t d "node-pg-migrate" . --max-depth 3Repository: heyito/ito Length of output: 36 🏁 Script executed: # Check the README around the context to understand the migration setup better
sed -n '270,300p' README.mdRepository: heyito/ito Length of output: 958 🏁 Script executed: # Search for node-pg-migrate in the entire repository
rg "node-pg-migrate" .Repository: heyito/ito Length of output: 5064 🏁 Script executed: # Check if there's a server package.json
fd -t f "package.json" server/Repository: heyito/ito Length of output: 99 🏁 Script executed: # Check Docker-related files for dependency installation
fd -t f "Dockerfile" . --max-depth 2Repository: heyito/ito Length of output: 73 🏁 Script executed: # Check docker-compose configuration
fd -t f "docker-compose.yml" . --max-depth 2Repository: heyito/ito Length of output: 81 🏁 Script executed: # Check Dockerfile for dependency installation
cat server/DockerfileRepository: heyito/ito Length of output: 569 🏁 Script executed: # Check the server-level npm scripts for migration commands
sed -n '20,50p' server/package.jsonRepository: heyito/ito Length of output: 1577 Add missing migrations directory argument to the Docker exec command. The Docker migration command should include the docker exec -it ito-server node ./node_modules/node-pg-migrate/bin/node-pg-migrate.js --migrations-dir src/migrations up🤖 Prompt for AI Agents |
||
|
|
||
| 5. **Verify the server is running**: | ||
| ```bash | ||
| curl http://localhost:3001 | ||
| # Should return: "Welcome to the Ito Connect RPC server!" | ||
| ``` | ||
|
|
||
| ### Building the Client (GitHub Actions) | ||
|
|
||
| The easiest way to build your own client is using GitHub Actions: | ||
|
|
||
| 1. **Fork this repository** to your GitHub account | ||
| 2. Go to **Actions** → **Build Self-Hosted** | ||
| 3. Click **Run workflow** | ||
| 4. Enter your server URL (e.g., `http://myserver:3001`) | ||
| 5. Select your platform (macOS arm64 or x64) | ||
| 6. Wait for the build to complete (~5-10 minutes) | ||
| 7. Download the DMG from **Artifacts** | ||
|
|
||
| ### Building the Client (Local) | ||
|
|
||
| Alternatively, build locally with your server URL: | ||
|
|
||
| ```bash | ||
| # Build with remote server URL (replace with your server address) | ||
| VITE_GRPC_BASE_URL=http://your-server:3001 \ | ||
| VITE_ITO_ENV=dev \ | ||
| CSC_IDENTITY_AUTO_DISCOVERY=false \ | ||
| bun run electron-vite build | ||
|
|
||
| # Create DMG (macOS, arm64 only to avoid electron-builder issues) | ||
| bunx electron-builder --config electron-builder.config.js --mac dmg --arm64 --publish=never | ||
| ``` | ||
|
|
||
| ### Installing the Client | ||
|
|
||
| 1. Mount the DMG from `dist/Ito-Installer.dmg` | ||
| 2. Drag `Ito.app` to Applications | ||
| 3. **Re-sign the app** (required for ad-hoc signed builds): | ||
| ```bash | ||
| xattr -cr /Applications/Ito.app | ||
| codesign --force --deep --sign - /Applications/Ito.app | ||
| ``` | ||
| 4. Launch the app | ||
|
|
||
| ### Network Setup | ||
|
|
||
| For remote access, you can use: | ||
| - **Tailscale**: Recommended for secure, zero-config networking. Install on both client and server machines, then use the Tailscale hostname (e.g., `http://box:3001`) | ||
| - **VPN**: Any VPN that gives you direct network access to your server | ||
| - **Port forwarding**: Expose port 3001 (not recommended for security reasons) | ||
|
|
||
| ### Server Auto-Start | ||
|
|
||
| The Docker services are configured with `restart: always`, so they'll automatically start on boot. Ensure Docker is enabled: | ||
|
|
||
| ```bash | ||
| # Linux | ||
| sudo systemctl enable docker | ||
|
|
||
| # Verify services are running | ||
| docker compose ps | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🏗️ Architecture | ||
|
|
||
| ### Client Architecture | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: heyito/ito
Length of output: 156
🏁 Script executed:
Repository: heyito/ito
Length of output: 2683
🏁 Script executed:
Repository: heyito/ito
Length of output: 77
🏁 Script executed:
Repository: heyito/ito
Length of output: 67
🏁 Script executed:
Repository: heyito/ito
Length of output: 2531
🏁 Script executed:
Repository: heyito/ito
Length of output: 442
🏁 Script executed:
Repository: heyito/ito
Length of output: 1807
🏁 Script executed:
Repository: heyito/ito
Length of output: 3294
🏁 Script executed:
Repository: heyito/ito
Length of output: 1049
🏁 Script executed:
Repository: heyito/ito
Length of output: 2818
🏁 Script executed:
Repository: heyito/ito
Length of output: 1010
Remove CSC_IDENTITY_AUTO_DISCOVERY from .env file—it's already set as an environment variable.
The
CSC_IDENTITY_AUTO_DISCOVERY=falsesetting is written to.env(line 57) but is also set directly as a shell environment variable in the electron-builder step (line 65). Since electron-builder reads this from the shell environment, the.enventry is redundant. Set it only via theenv:directive in the build step to avoid duplication.The quoted environment variables (e.g.,
VITE_GRPC_BASE_URL="...") are correctly formatted—Vite's dotenv parser automatically strips surrounding quotes.🤖 Prompt for AI Agents