From 13be980aa593cf4dc469f9d7d097aa9f6241a06a Mon Sep 17 00:00:00 2001 From: minimax Date: Sat, 1 Nov 2025 05:05:56 +0800 Subject: [PATCH 1/3] Sync with matrix message 329285348413640 --- .gitignore | 906 ++++++++++++++++++++++++++++++++++++++++++++++++++++- go.mod | 2 +- 2 files changed, 898 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 14e0bdd..031b03e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,897 @@ -# Build artifacts -/bd-ui -/beady -*.exe -bin/ - -# IDE files -*.swp -*.swo +# ============================================================================== +# COMPREHENSIVE .GITIGNORE TEMPLATE +# ============================================================================== +# This template covers most common development scenarios and tools +# Generated patterns use ** to match any subdirectory depth + +# ============================================================================== +# PYTHON +# ============================================================================== +**/__pycache__/ +**/*.py[cod] +**/*$py.class +**/*.so +**/.Python +**/build/ +**/develop-eggs/ +**/dist/ +**/downloads/ +**/eggs/ +**/.eggs/ +**/lib/ +**/lib64/ +**/parts/ +**/sdist/ +**/var/ +**/wheels/ +**/share/python-wheels/ +**/*.egg-info/ +**/.installed.cfg +**/*.egg +**/MANIFEST + +# PyInstaller +**/*.manifest +**/*.spec + +# Installer logs +**/pip-log.txt +**/pip-delete-this-directory.txt + +# Unit test / coverage reports +**/htmlcov/ +**/.tox/ +**/.nox/ +**/.coverage +**/.coverage.* +**/.cache +**/nosetests.xml +**/coverage.xml +**/*.cover +**/*.py,cover +**/.hypothesis/ +**/.pytest_cache/ +**/cover/ + +# Translations +**/*.mo +**/*.pot + +# Django stuff: +**/*.log +**/local_settings.py +**/db.sqlite3 +**/db.sqlite3-journal + +# Flask stuff: +**/instance/ +**/.webassets-cache + +# Scrapy stuff: +**/.scrapy + +# Sphinx documentation +**/docs/_build/ + +# PyBuilder +**/.pybuilder/ +**/target/ + +# Jupyter Notebook +**/.ipynb_checkpoints + +# IPython +**/profile_default/ +**/ipython_config.py + +# pyenv +**/.python-version + +# pipenv +**/Pipfile.lock + +# poetry +**/poetry.lock + +# pdm +**/.pdm.toml +**/.pdm-python +**/.pdm-build/ + +# PEP 582 +**/__pypackages__/ + +# Celery stuff +**/celerybeat-schedule +**/celerybeat.pid + +# SageMath parsed files +**/*.sage.py + +# Environments +**/.env +**/.venv +**/env/ +**/venv/ +**/ENV/ +**/env.bak/ +**/venv.bak/ + +# Spyder project settings +**/.spyderproject +**/.spyproject + +# Rope project settings +**/.ropeproject + +# mkdocs documentation +**/site/ + +# mypy +**/.mypy_cache/ +**/.dmypy.json +**/dmypy.json + +# Pyre type checker +**/.pyre/ + +# pytype static type analyzer +**/.pytype/ + +# Cython debug symbols +**/cython_debug/ + +# PyCharm +**/.idea/ + +# ============================================================================== +# NODE.JS / JAVASCRIPT / TYPESCRIPT +# ============================================================================== +**/node_modules/ +**/npm-debug.log* +**/yarn-debug.log* +**/yarn-error.log* +**/lerna-debug.log* +**/.pnpm-debug.log* + +# Runtime data +**/pids/ +**/*.pid +**/*.seed +**/*.pid.lock + +# Coverage directory used by tools like istanbul +**/coverage/ +**/.nyc_output + +# Grunt intermediate storage +**/.grunt + +# Bower dependency directory +**/bower_components + +# node-waf configuration +**/.lock-wscript + +# Compiled binary addons +**/build/Release + +# Dependency directories +**/jspm_packages/ + +# Snowpack dependency directory +**/web_modules/ + +# TypeScript cache +**/*.tsbuildinfo + +# Optional npm cache directory +**/.npm + +# Optional eslint cache +**/.eslintcache + +# Optional stylelint cache +**/.stylelintcache + +# Microbundle cache +**/.rpt2_cache/ +**/.rts2_cache_cjs/ +**/.rts2_cache_es/ +**/.rts2_cache_umd/ + +# Optional REPL history +**/.node_repl_history + +# Output of 'npm pack' +**/*.tgz + +# Yarn Integrity file +**/.yarn-integrity + +# dotenv environment variable files +**/.env +**/.env.development.local +**/.env.test.local +**/.env.production.local +**/.env.local + +# parcel-bundler cache +**/.cache +**/.parcel-cache + +# Next.js build output +**/.next +**/out/ + +# Nuxt.js build / generate output +**/.nuxt +**/dist + +# Gatsby files +**/.cache/ +**/public + +# Vue.js +**/dist/ +**/.tmp +**/.cache + +# Vuepress build output +**/.vuepress/dist + +# Serverless directories +**/.serverless/ + +# FuseBox cache +**/.fusebox/ + +# DynamoDB Local files +**/.dynamodb/ + +# TernJS port file +**/.tern-port + +# Stores VSCode versions used for testing VSCode extensions +**/.vscode-test + +# yarn v2 +**/.yarn/cache +**/.yarn/unplugged +**/.yarn/build-state.yml +**/.yarn/install-state.gz +**/.pnp.* + +# Storybook +**/.storybook-out +**/storybook-static + +# Angular +**/e2e/ +**/.angular/ + +# React Native +**/ios/Pods/ +**/android/app/build/ + +# Expo +**/.expo/ +**/dist/ +**/npm-debug.* +**/yarn-error.* +**/.expo-shared + +# ============================================================================== +# JAVA +# ============================================================================== +**/*.class +**/*.log +**/*.ctxt +**/.mtj.tmp/ +**/*.jar +**/*.war +**/*.nar +**/*.ear +**/*.zip +**/*.tar.gz +**/*.rar +**/hs_err_pid* +**/replay_pid* + +# Maven +**/target/ +**/pom.xml.tag +**/pom.xml.releaseBackup +**/pom.xml.versionsBackup +**/pom.xml.next +**/release.properties +**/dependency-reduced-pom.xml +**/buildNumber.properties +**/.mvn/timing.properties +**/.mvn/wrapper/maven-wrapper.jar + +# Gradle +**/.gradle/ +**/build/ +**/.gradletasknamecache +**/gradle-app.setting + +# IntelliJ IDEA +**/.idea/ +**/*.iws +**/*.iml +**/*.ipr +**/out/ + +# Eclipse +**/.apt_generated +**/.classpath +**/.factorypath +**/.project +**/.settings +**/.springBeans +**/.sts4-cache +**/bin/ +**/tmp/ +**/*.tmp +**/*.bak +**/*.swp +**/*~.nib +**/local.properties +**/.metadata +**/.loadpath +**/.recommenders + +# NetBeans +**/nbproject/private/ +**/.nbbuild/ +**/dist/ +**/nbdist/ +**/.nb-gradle/ + +# VS Code +**/.vscode/ + +# ============================================================================== +# C / C++ +# ============================================================================== +# Prerequisites +**/*.d + +# Object files +**/*.o +**/*.ko +**/*.obj +**/*.elf + +# Linker output +**/*.ilk +**/*.map +**/*.exp + +# Precompiled Headers +**/*.gch +**/*.pch + +# Libraries +**/*.lib +**/*.a +**/*.la +**/*.lo + +# Shared objects (inc. Windows DLLs) +**/*.dll +**/*.so +**/*.so.* +**/*.dylib + +# Executables +**/*.exe +**/*.out +**/*.app +**/*.i*86 +**/*.x86_64 +**/*.hex + +# Debug files +**/*.dSYM/ +**/*.su +**/*.idb +**/*.pdb + +# Kernel Module Compile Results +**/*.mod* +**/*.cmd +**/.tmp_versions/ +**/modules.order +**/Module.symvers +**/Mkfile.old +**/dkms.conf + +# CMake +**/CMakeLists.txt.user +**/CMakeCache.txt +**/CMakeFiles +**/CMakeScripts +**/Testing +**/Makefile +**/cmake_install.cmake +**/install_manifest.txt +**/compile_commands.json +**/CTestTestfile.cmake +**/_deps + +# Conan +**/conanfile.txt +**/conandata.yml +**/conan.lock +**/.conan/ + +# ============================================================================== +# C# / .NET +# ============================================================================== +**/bin/ +**/obj/ +**/out/ +**/*.user +**/*.suo +**/*.sln.docstates +**/*.userprefs +**/*.pidb +**/*.booproj +**/.vs/ +**/packages/ +**/TestResults/ +**/*.Cache +**/ClientBin/ +**/*_i.c +**/*_p.c +**/*_h.h +**/*.ilk +**/*.meta +**/*.obj +**/*.iobj +**/*.pch +**/*.pdb +**/*.ipdb +**/*.pgc +**/*.pgd +**/*.rsp +**/*.sbr +**/*.tlb +**/*.tli +**/*.tlh +**/*.tmp +**/*.tmp_proj +**/*_wpftmp.csproj +**/*.log +**/*.vspscc +**/*.vssscc +**/.builds +**/*.pidb +**/*.svclog +**/*.scc + +# ============================================================================== +# GO +# ============================================================================== +# Binaries for programs and plugins +**/*.exe +**/*.exe~ +**/*.dll +**/*.so +**/*.dylib + +# Test binary, built with `go test -c` +**/*.test + +# Output of the go coverage tool +**/*.out + +# Dependency directories +**/vendor/ + +# Go workspace file +**/go.work + +# ============================================================================== +# RUST +# ============================================================================== +# Generated by Cargo +**/target/ + +# Remove Cargo.lock from gitignore if creating an executable +# Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc +**/*.pdb + +# ============================================================================== +# PHP +# ============================================================================== +**/vendor/ +**/node_modules/ +**/npm-debug.log +**/yarn-error.log + +# Laravel specific +**/.env +**/storage/*.key +**/Homestead.yaml +**/Homestead.json +**/.vagrant +**/.phpunit.result.cache + +# Symfony specific +**/.env.local +**/.env.local.php +**/.env.*.local +**/config/secrets/prod/prod.decrypt.private.php +**/public/bundles/ +**/var/ +**/vendor/ + +# Composer +**/composer.phar +**/composer.lock + +# ============================================================================== +# RUBY +# ============================================================================== +**/*.gem +**/*.rbc +**/.config +**/coverage/ +**/InstalledFiles +**/pkg/ +**/spec/reports/ +**/spec/examples.txt +**/test/tmp/ +**/test/version_tmp/ +**/tmp/ +**/.yardoc/ +**/_yardoc/ +**/doc/ +**/.bundle/ +**/vendor/bundle +**/lib/bundler/man/ +**/.rbenv-version +**/.rvmrc +**/.ruby-version +**/.ruby-gemset +**/Gemfile.lock + +# Rails +**/log/ +**/tmp/ +**/db/*.sqlite3 +**/db/*.sqlite3-journal +**/db/*.sqlite3-* +**/public/system/ +**/coverage/ +**/spec/tmp/ +**/.sass-cache/ +**/capybara-*.html +**/.rspec +**/.generators +**/.rakeTasks + +# ============================================================================== +# DATABASES +# ============================================================================== +**/*.db +**/*.sqlite +**/*.sqlite3 +**/*.db-shm +**/*.db-wal + +# MySQL +**/mysql-bin.* + +# PostgreSQL +**/*.backup +**/*.sql + +# MongoDB +**/dump/ + +# Redis +**/dump.rdb + +# ============================================================================== +# DEVOPS & CONTAINERS +# ============================================================================== +# Docker +**/Dockerfile* +**/.dockerignore +**/docker-compose*.yml +**/.docker/ + +# Kubernetes +**/*.kubeconfig + +# Terraform +**/*.tfstate +**/*.tfstate.* +**/.terraform/ +**/.terraform.lock.hcl +**/terraform.tfvars +**/terraform.tfvars.json +**/*.tfplan +**/*.tfstate.backup + +# Vagrant +**/.vagrant/ +**/*.box + +# Ansible +**/retry files +**/*.retry + +# ============================================================================== +# OPERATING SYSTEMS +# ============================================================================== +# Windows +**/Thumbs.db +**/Thumbs.db:encryptable +**/ehthumbs.db +**/ehthumbs_vista.db +**/*.stackdump +**/$RECYCLE.BIN/ +**/Desktop.ini + +# macOS +**/.DS_Store +**/.AppleDouble +**/.LSOverride +**/Icon +**/.DocumentRevisions-V100 +**/.fseventsd +**/.Spotlight-V100 +**/.TemporaryItems +**/.Trashes +**/.VolumeIcon.icns +**/.com.apple.timemachine.donotpresent +**/.AppleDB +**/.AppleDesktop +**/Network Trash Folder +**/Temporary Items +**/.apdisk + +# Linux +**/*~ +**/.fuse_hidden* +**/.directory +**/.Trash-* +**/.nfs* + +# ============================================================================== +# IDEs & EDITORS +# ============================================================================== +# Visual Studio Code +**/.vscode/ +**/*.code-workspace +**/.history/ + +# Visual Studio +**/.vs/ +**/bin/ +**/obj/ +**/*.user +**/*.suo + +# IntelliJ IDEA +**/.idea/ +**/*.iws +**/*.iml +**/*.ipr + +# Eclipse +**/.metadata +**/bin/ +**/tmp/ +**/*.tmp +**/*.bak +**/*.swp +**/*~.nib +**/local.properties +**/.settings/ +**/.loadpath +**/.recommenders +**/.apt_generated/ +**/.apt_generated_test/ +**/.cache-main +**/.scala_dependencies +**/.worksheet + +# NetBeans +**/nbproject/private/ +**/.nbbuild/ +**/dist/ +**/nbdist/ +**/.nb-gradle/ +**/build/ + +# Sublime Text +**/*.sublime-workspace +**/*.sublime-project + +# Vim +**/*.swp +**/*.swo +**/*~ +**/.netrwhist +**/tags + +# Emacs +**/*~ +**/#*# +**/.#* +**/.emacs.desktop +**/.emacs.desktop.lock +**/*.elc +**/auto-save-list +**/tramp +**/.org-id-locations +**/*_archive +**/*_flymake.* +**/flycheck_*.el +**/.dir-locals.el +**/.projectile + +# Atom +**/.atom/ + +# ============================================================================== +# LOGS & TEMPORARY FILES +# ============================================================================== +**/logs/ +**/*.log +**/log/ +**/debug/ +**/tmp/ +**/temp/ +**/.tmp/ +**/.temp/ +**/crash.log +**/error.log +**/access.log +**/combined.log +**/npm-debug.log* +**/yarn-debug.log* +**/yarn-error.log* + +# ============================================================================== +# SECURITY & CREDENTIALS +# ============================================================================== +**/.env* +!**/.env.example +!**/.env.template +**/*.pem +**/*.key +**/*.p12 +**/*.pfx +**/*.jks +**/*.keystore +**/secrets/ +**/credentials/ +**/.secrets/ +**/.credentials/ +**/auth.json +**/service-account*.json +**/.gcloud/ +**/.aws/ +**/.azure/ + +# ============================================================================== +# BACKUP & ARCHIVE FILES +# ============================================================================== +**/*.bak +**/*.backup +**/*.old +**/*.orig +**/*.rej +**/*.swp +**/*.swo +**/*~ +**/*.tmp +**/*.temp +**/.DS_Store? +**/._* +**/*.zip +**/*.rar +**/*.7z +**/*.tar +**/*.gz +**/*.tgz +**/*.tar.gz +**/*.tar.bz2 +**/*.tar.xz + +# ============================================================================== +# CACHE & BUILD ARTIFACTS +# ============================================================================== +**/.cache/ +**/cache/ +**/build/ +**/dist/ +**/out/ +**/target/ +**/.next/ +**/.nuxt/ +**/.vuepress/dist/ +**/public/build/ +**/public/hot +**/public/storage +**/storage/*.key +**/bootstrap/cache/ + +# ============================================================================== +# PACKAGE MANAGERS +# ============================================================================== +# npm +**/node_modules/ +**/package-lock.json +**/.npm/ + +# Yarn +**/yarn.lock +**/.yarn/ +**/.pnp.* + +# pnpm +**/pnpm-lock.yaml +**/.pnpm-store/ + +# Bower +**/bower_components/ + +# Composer (PHP) +**/vendor/ +**/composer.lock + +# Bundler (Ruby) +**/vendor/bundle/ +**/Gemfile.lock + +# Maven (Java) +**/target/ + +# Gradle (Java/Android) +**/.gradle/ +**/build/ + +# Cargo (Rust) +**/target/ +**/Cargo.lock + +# ============================================================================== +# MISC +# ============================================================================== +# Thumbnails +**/*.jpg:large +**/*.jpeg:large +**/*.png:large +**/*.gif:large + +# Archive files +**/*.7z +**/*.dmg +**/*.iso +**/*.jar +**/*.rar +**/*.tar +**/*.zip + +# ============================================================================== +# PROJECT SPECIFIC +# ============================================================================== +# Add your project-specific ignores here +# workspace/ +# data/ +# uploads/ +# downloads/ + diff --git a/go.mod b/go.mod index 54695a3..49fbfda 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/maphew/beady -go 1.24.0 +go 1.22.9 require ( github.com/fsnotify/fsnotify v1.9.0 From 3b8c8e28a59daa9a0a43868c9e581448e46c3136 Mon Sep 17 00:00:00 2001 From: minimax Date: Sat, 1 Nov 2025 05:49:41 +0800 Subject: [PATCH 2/3] Sync with matrix message 329295910453464 --- fly.toml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 fly.toml diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..7353f57 --- /dev/null +++ b/fly.toml @@ -0,0 +1,54 @@ +# Fly.io Configuration for Beady +# Cloud backup/sync endpoint for local-first Beads issue tracker + +app = 'beady-backup' +primary_region = 'iad' # Ashburn, Virginia (change to your preferred region) + +[build] + dockerfile = "Dockerfile" + +[env] + PORT = "8080" + BEADS_DIR = "/data/.beads" + +# HTTP Service Configuration +[http_service] + internal_port = 8080 + force_https = true + auto_stop_machines = 'stop' # Stop machines when idle to save costs + auto_start_machines = true # Auto-start on new requests + min_machines_running = 0 # No always-on machines (cost optimization) + + # Concurrency settings + [http_service.concurrency] + type = "connections" + hard_limit = 25 + soft_limit = 20 + + # Health check + [[http_service.checks]] + grace_period = "10s" + interval = "30s" + timeout = "5s" + method = "GET" + path = "/" + protocol = "http" + +# Volume mount for persistent Beads database +[[mounts]] + source = "beady_data" + destination = "/data" + initial_size = "1gb" # 1GB free tier + snapshot_retention = 5 # Keep snapshots for 5 days + scheduled_snapshots = true # Enable automatic daily snapshots + + # Auto-extend configuration (optional) + auto_extend_size_threshold = 80 # Extend at 80% usage + auto_extend_size_increment = "1GB" + auto_extend_size_limit = "3GB" # Max size limit + +# VM Configuration (free tier) +[vm] + size = 'shared-cpu-1x' # 1 shared vCPU, 256MB RAM (free tier) + memory = '256mb' + cpus = 1 From fea2c112c2006a3741543a548dc4e63bbbdd7430 Mon Sep 17 00:00:00 2001 From: maphew Date: Sat, 1 Nov 2025 05:59:56 +0800 Subject: [PATCH 3/3] Add Fly.io deployment support with automated scripts - Add Dockerfile for Fly.io deployment (multi-stage Go build) - Add deployment automation scripts: - deploy-to-flyio.sh: Automated deployment to Fly.io - sync-local-to-cloud.sh: Push local database to cloud - sync-cloud-to-local.sh: Pull cloud database to local - check-cloud-status.sh: Monitor cloud deployment health - Add comprehensive Fly.io deployment documentation - Supports local-first architecture with cloud backup - Free tier eligible (~$0-5/month with auto-scaling) --- Dockerfile | 57 ++++ docs/deployment/FLY-IO-DEPLOYMENT.md | 411 +++++++++++++++++++++++++++ scripts/check-cloud-status.sh | 79 +++++ scripts/deploy-to-flyio.sh | 78 +++++ scripts/sync-cloud-to-local.sh | 56 ++++ scripts/sync-local-to-cloud.sh | 57 ++++ 6 files changed, 738 insertions(+) create mode 100644 Dockerfile create mode 100644 docs/deployment/FLY-IO-DEPLOYMENT.md create mode 100644 scripts/check-cloud-status.sh create mode 100644 scripts/deploy-to-flyio.sh create mode 100644 scripts/sync-cloud-to-local.sh create mode 100644 scripts/sync-local-to-cloud.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b48c64b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,57 @@ +# Multi-stage Dockerfile for beady +# Stage 1: Build the Go application +FROM golang:1.24.9-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache git ca-certificates tzdata + +# Set working directory +WORKDIR /build + +# Copy go.mod and go.sum for dependency caching +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY . . + +# Build the application +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o beady cmd/beady/*.go + +# Stage 2: Create minimal runtime image +FROM alpine:latest + +# Install runtime dependencies +RUN apk --no-cache add ca-certificates tzdata + +# Install Beads CLI for write operations +RUN apk --no-cache add go git && \ + export GOPATH=/tmp/go && \ + go install github.com/steveyegge/beads@latest && \ + mv /tmp/go/bin/beads /usr/local/bin/bd && \ + rm -rf /tmp/go && \ + apk del go git + +# Create app directory +WORKDIR /app + +# Copy binary from builder +COPY --from=builder /build/beady /app/beady + +# Copy assets (if any) +COPY --from=builder /build/assets /app/assets + +# Create data directory for Beads database +RUN mkdir -p /data/.beads + +# Set environment variables +ENV PORT=8080 +ENV BEADS_DIR=/data/.beads + +# Expose port +EXPOSE 8080 + +# Run beady +CMD ["/app/beady", "--port", "8080"] diff --git a/docs/deployment/FLY-IO-DEPLOYMENT.md b/docs/deployment/FLY-IO-DEPLOYMENT.md new file mode 100644 index 0000000..3ef4f4c --- /dev/null +++ b/docs/deployment/FLY-IO-DEPLOYMENT.md @@ -0,0 +1,411 @@ +# Fly.io Deployment Guide for Beady +## Cloud Backup/Sync Endpoint Setup + +This guide covers deploying beady to Fly.io as a cloud backup and sync endpoint for your local-first beady deployment. + +--- + +## Prerequisites + +### 1. Install Fly.io CLI (flyctl) +```bash +# Linux +curl -L https://fly.io/install.sh | sh + +# macOS +brew install flyctl + +# Verify installation +flyctl version +``` + +### 2. Sign up / Log in to Fly.io +```bash +# If you have an account +flyctl auth login + +# If you need to sign up +flyctl auth signup +``` + +### 3. Verify Free Tier Eligibility +```bash +# Check your account status +flyctl status + +# This deployment is configured to stay within the free tier: +# - 1 shared-cpu-1x VM (256MB RAM) +# - 1GB persistent volume +# - Auto-stop when idle (no ongoing costs) +``` + +--- + +## Deployment Steps + +### Step 1: Navigate to beady directory +```bash +cd /workspace/beady +``` + +### Step 2: Create Fly.io App +```bash +# Create app (change app name if needed) +flyctl apps create beady-backup + +# Or let Fly.io generate a unique name +flyctl apps create +``` + +### Step 3: Create Persistent Volume +```bash +# Create 1GB volume in your primary region +flyctl volumes create beady_data --region iad --size 1 + +# Verify volume creation +flyctl volumes list +``` + +### Step 4: Deploy Application +```bash +# Deploy to Fly.io +flyctl deploy + +# This will: +# 1. Build Docker image from Dockerfile +# 2. Push image to Fly.io registry +# 3. Create and start the Machine +# 4. Mount the volume to /data +``` + +### Step 5: Verify Deployment +```bash +# Check app status +flyctl status + +# View app URL +flyctl info + +# Access logs +flyctl logs + +# Open in browser +flyctl open +``` + +--- + +## Configuration Details + +### App Settings (fly.toml) +- **App Name**: beady-backup (customize as needed) +- **Region**: iad (Ashburn, Virginia) +- **VM Size**: shared-cpu-1x (256MB RAM, 1 vCPU) +- **Port**: 8080 (internal), 443 (external HTTPS) +- **Auto-scaling**: Stops when idle, starts on request + +### Volume Configuration +- **Name**: beady_data +- **Size**: 1GB (free tier) +- **Mount Point**: /data +- **Database Path**: /data/.beads/ +- **Snapshots**: Daily, retained for 5 days +- **Auto-extend**: Enabled at 80% usage + +### Cost Optimization +This configuration is designed to minimize costs: +- ✅ Auto-stop when idle (no traffic) +- ✅ Auto-start on new requests +- ✅ No always-on machines (min_machines_running = 0) +- ✅ 1GB volume (within free tier) +- ✅ Shared CPU (cost-effective) + +**Expected Monthly Cost**: $0-5 with light usage + +--- + +## Database Initialization + +### Option 1: Initialize Fresh Database +After first deployment, the cloud instance will have an empty database. Initialize it: + +```bash +# SSH into the Fly.io machine +flyctl ssh console + +# Inside the machine +cd /data/.beads +bd init --prefix retirement-project + +# Exit SSH +exit +``` + +### Option 2: Sync from Local Database +See the "Sync Strategies" section below to push your local database to the cloud. + +--- + +## Sync Strategies + +### 1. Git-Based Sync (Recommended) + +The Beads database uses `beads.jsonl` as the source of truth, which is perfect for Git sync. + +#### Setup Git Sync +```bash +# On local machine +cd ~/.beads +git init +git add beads.jsonl +git commit -m "Initial beady database" + +# Add remote (GitHub, GitLab, etc.) +git remote add origin YOUR_GIT_REPO_URL +git push -u origin main +``` + +#### Sync Local → Cloud +```bash +# On local machine +cd ~/.beads +git add beads.jsonl +git commit -m "Update beads database" +git push + +# On Fly.io machine (via SSH) +flyctl ssh console +cd /data/.beads +git pull +exit + +# Restart beady to reload data +flyctl apps restart beady-backup +``` + +#### Sync Cloud → Local +```bash +# On Fly.io machine (via SSH) +flyctl ssh console +cd /data/.beads +git add beads.jsonl +git commit -m "Update from cloud" +git push +exit + +# On local machine +cd ~/.beads +git pull +``` + +### 2. Manual File Sync + +#### Push Local Database to Cloud +```bash +# Copy beads.jsonl to cloud +flyctl ssh console -C "mkdir -p /data/.beads" +flyctl ssh sftp shell + +# In SFTP shell +put ~/.beads/beads.jsonl /data/.beads/beads.jsonl +bye + +# Restart beady +flyctl apps restart beady-backup +``` + +#### Pull Cloud Database to Local +```bash +# Download beads.jsonl from cloud +flyctl ssh sftp shell + +# In SFTP shell +get /data/.beads/beads.jsonl ~/.beads/beads.jsonl +bye + +# Restart local beady +pkill beady +cd ~/.beads && beady --port 8081 & +``` + +--- + +## Testing the Deployment + +### 1. Test Web UI Access +```bash +# Get your app URL +flyctl info + +# Visit the URL in browser (will auto-start the machine) +# Example: https://beady-backup.fly.dev +``` + +### 2. Test Auto-Stop/Start +```bash +# The machine should stop after ~5 minutes of inactivity +flyctl status + +# Visit the URL again - machine should auto-start +``` + +### 3. Test Data Persistence +```bash +# Create an issue via the web UI +# Restart the app +flyctl apps restart beady-backup + +# Verify the issue still exists (data persisted to volume) +``` + +--- + +## Backup and Recovery + +### Volume Snapshots +Fly.io automatically creates daily snapshots of your volume: + +```bash +# List snapshots +flyctl volumes snapshots list beady_data + +# Create manual snapshot +flyctl volumes snapshots create beady_data + +# Restore from snapshot +flyctl volumes create beady_data_restore --snapshot-id SNAPSHOT_ID +``` + +### Database Backup +```bash +# Download beads.jsonl for local backup +flyctl ssh sftp shell +get /data/.beads/beads.jsonl ~/backups/beads-backup-$(date +%Y%m%d).jsonl +bye +``` + +--- + +## Monitoring and Maintenance + +### View Logs +```bash +# Real-time logs +flyctl logs + +# Specific time range +flyctl logs --since 1h +``` + +### Resource Usage +```bash +# App metrics +flyctl status + +# Volume usage +flyctl volumes list +``` + +### Scaling (if needed) +```bash +# Increase VM size +flyctl scale vm shared-cpu-2x + +# Increase memory +flyctl scale memory 512 + +# Extend volume +flyctl volumes extend beady_data --size 2 +``` + +--- + +## Troubleshooting + +### Machine Won't Start +```bash +# Check logs +flyctl logs + +# Restart machine +flyctl apps restart beady-backup + +# SSH and debug +flyctl ssh console +``` + +### Database Not Persisting +```bash +# Verify volume mount +flyctl ssh console +ls -la /data/.beads/ + +# Check volume status +flyctl volumes list +``` + +### Out of Memory +```bash +# Increase memory allocation +flyctl scale memory 512 +``` + +--- + +## Security Considerations + +### 1. Make App Private (Optional) +If you only need cloud backup, not public access: + +```bash +# Remove public IP (private only) +flyctl ips list +flyctl ips release +``` + +### 2. Add Authentication (Future Enhancement) +Consider adding basic auth or OAuth if exposing publicly. + +### 3. Git Repository Access +- Use private Git repositories for sensitive data +- Configure SSH keys or tokens for automated sync + +--- + +## Next Steps + +After successful deployment: + +1. ✅ Test cloud access from mobile devices +2. ✅ Set up automated Git sync (cron job or GitHub Actions) +3. ✅ Configure backup rotation strategy +4. ✅ Test failover scenarios (local down, use cloud) +5. ✅ Document restore procedures + +--- + +## Cleanup (if needed) + +To remove the Fly.io deployment: + +```bash +# Delete the app and all resources +flyctl apps destroy beady-backup + +# This will also delete the volume and all data +``` + +--- + +## Cost Summary + +**Free Tier Limits** (as of 2025): +- Up to $5/month in compute usage +- 3GB persistent volume storage (1GB used) +- Outbound data transfer limits + +**This Deployment**: +- ~$0-2/month with auto-stop enabled +- Additional costs only if high traffic + +**To stay free**: Ensure `auto_stop_machines = 'stop'` and `min_machines_running = 0` in fly.toml. diff --git a/scripts/check-cloud-status.sh b/scripts/check-cloud-status.sh new file mode 100644 index 0000000..cd2cf71 --- /dev/null +++ b/scripts/check-cloud-status.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Check Fly.io deployment status and health +# This script provides a comprehensive status check of the cloud deployment + +set -e + +# Configuration +APP_NAME="${1:-beady-backup}" + +echo "=== Beady Cloud Deployment Status ===" +echo "" + +# Check if flyctl is installed +if ! command -v flyctl &> /dev/null; then + echo "ERROR: flyctl not found" + exit 1 +fi + +# App information +echo "📱 App Information:" +flyctl info -a "$APP_NAME" 2>/dev/null || { + echo " ❌ App not found: $APP_NAME" + exit 1 +} +echo "" + +# Machine status +echo "🖥️ Machine Status:" +flyctl status -a "$APP_NAME" +echo "" + +# Volume information +echo "💾 Volume Information:" +flyctl volumes list -a "$APP_NAME" +echo "" + +# Recent logs +echo "📋 Recent Logs (last 20 lines):" +flyctl logs -a "$APP_NAME" --lines 20 +echo "" + +# Database status +echo "🗄️ Database Status:" +echo "Checking database files on cloud..." +flyctl ssh console -a "$APP_NAME" -C "ls -lh /data/.beads/" 2>/dev/null || { + echo " ❌ Cannot access database directory" +} +echo "" + +# Issue count +echo "📊 Issue Count:" +ISSUE_COUNT=$(flyctl ssh console -a "$APP_NAME" -C "cd /data/.beads && bd list --all 2>/dev/null | wc -l" 2>/dev/null || echo "0") +echo " Total issues: $ISSUE_COUNT" +echo "" + +# Health check +echo "🏥 Health Check:" +APP_URL=$(flyctl info -a "$APP_NAME" --json 2>/dev/null | jq -r '.Hostname' 2>/dev/null || echo "unknown") +if [ "$APP_URL" != "unknown" ]; then + echo " Testing: https://$APP_URL" + if curl -f -s -o /dev/null -w "%{http_code}" "https://$APP_URL" 2>/dev/null | grep -q "200"; then + echo " ✅ App is healthy and responding" + else + echo " ⚠️ App may be stopped (will auto-start on first request)" + fi +else + echo " ⚠️ Cannot determine app URL" +fi +echo "" + +# Quick actions +echo "🔧 Quick Actions:" +echo " View full logs: flyctl logs -a $APP_NAME" +echo " SSH into machine: flyctl ssh console -a $APP_NAME" +echo " Open in browser: flyctl open -a $APP_NAME" +echo " Restart app: flyctl apps restart $APP_NAME" +echo " Sync to local: bash scripts/sync-cloud-to-local.sh $APP_NAME" +echo " Sync from local: bash scripts/sync-local-to-cloud.sh $APP_NAME" +echo "" \ No newline at end of file diff --git a/scripts/deploy-to-flyio.sh b/scripts/deploy-to-flyio.sh new file mode 100644 index 0000000..6cc60d1 --- /dev/null +++ b/scripts/deploy-to-flyio.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Deploy beady to Fly.io as cloud backup endpoint +# This script automates the Fly.io deployment process + +set -e + +echo "=== Beady Fly.io Deployment Script ===" +echo "" + +# Configuration +APP_NAME="${1:-beady-backup}" +REGION="${2:-iad}" +VOLUME_SIZE="1" + +echo "Configuration:" +echo " App Name: $APP_NAME" +echo " Region: $REGION (Ashburn, Virginia)" +echo " Volume Size: ${VOLUME_SIZE}GB" +echo "" + +# Check if flyctl is installed +if ! command -v flyctl &> /dev/null; then + echo "ERROR: flyctl not found" + echo "Install it from: https://fly.io/docs/flyctl/install/" + exit 1 +fi + +# Check if logged in +if ! flyctl auth whoami &> /dev/null; then + echo "Not logged in to Fly.io" + echo "Running: flyctl auth login" + flyctl auth login +fi + +echo "Step 1: Creating Fly.io app..." +if flyctl apps list | grep -q "$APP_NAME"; then + echo "App $APP_NAME already exists" +else + flyctl apps create "$APP_NAME" || { + echo "Failed to create app. Trying with auto-generated name..." + APP_NAME=$(flyctl apps create --json | jq -r '.Name') + echo "Created app with name: $APP_NAME" + } +fi + +echo "" +echo "Step 2: Creating persistent volume..." +if flyctl volumes list -a "$APP_NAME" 2>/dev/null | grep -q "beady_data"; then + echo "Volume beady_data already exists" +else + flyctl volumes create beady_data --region "$REGION" --size "$VOLUME_SIZE" -a "$APP_NAME" +fi + +echo "" +echo "Step 3: Deploying application..." +cd /workspace/beady +flyctl deploy -a "$APP_NAME" + +echo "" +echo "Step 4: Verifying deployment..." +flyctl status -a "$APP_NAME" + +echo "" +echo "=== Deployment Complete! ===" +echo "" +echo "App URL: https://${APP_NAME}.fly.dev" +echo "" +echo "Useful commands:" +echo " flyctl status -a $APP_NAME # Check app status" +echo " flyctl logs -a $APP_NAME # View logs" +echo " flyctl open -a $APP_NAME # Open in browser" +echo " flyctl ssh console -a $APP_NAME # SSH into machine" +echo "" +echo "Next steps:" +echo "1. Initialize database on cloud (if not syncing from local)" +echo "2. Set up Git sync for automated backup" +echo "3. Test access from mobile devices" +echo "" \ No newline at end of file diff --git a/scripts/sync-cloud-to-local.sh b/scripts/sync-cloud-to-local.sh new file mode 100644 index 0000000..5ce166a --- /dev/null +++ b/scripts/sync-cloud-to-local.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Sync Fly.io cloud database to local Beads backup +# This script pulls beads.jsonl from cloud to local + +set -e + +# Configuration +APP_NAME="${1:-beady-backup}" +LOCAL_BEADS_DIR="${2:-$HOME/.beads}" + +echo "=== Sync Cloud → Local ===" +echo " App: $APP_NAME" +echo " Local DB: $LOCAL_BEADS_DIR" +echo "" + +# Check if flyctl is installed +if ! command -v flyctl &> /dev/null; then + echo "ERROR: flyctl not found" + exit 1 +fi + +# Create backup of local database first +if [ -f "$LOCAL_BEADS_DIR/beads.jsonl" ]; then + echo "Step 1: Creating backup of local database..." + BACKUP_FILE="$LOCAL_BEADS_DIR/beads-local-backup-$(date +%Y%m%d-%H%M%S).jsonl" + cp "$LOCAL_BEADS_DIR/beads.jsonl" "$BACKUP_FILE" + echo "Local backup saved to: $BACKUP_FILE" +fi + +# Create local directory if not exists +mkdir -p "$LOCAL_BEADS_DIR" + +# Download cloud database +echo "Step 2: Downloading cloud database..." +flyctl ssh console -a "$APP_NAME" -C "cat /data/.beads/beads.jsonl" > "$LOCAL_BEADS_DIR/beads.jsonl" + +# Download config file +echo "Step 3: Downloading config.json..." +flyctl ssh console -a "$APP_NAME" -C "cat /data/.beads/config.json" > "$LOCAL_BEADS_DIR/config.json" 2>/dev/null || { + echo "No config.json found on cloud (this is OK)" +} + +# Restart local beady if running +echo "Step 4: Restarting local beady (if running)..." +pkill beady 2>/dev/null || echo "Local beady not running" + +echo "" +echo "=== Sync Complete! ===" +echo "Cloud database synced to local" +echo "Local database: $LOCAL_BEADS_DIR/beads.jsonl" +if [ -f "$BACKUP_FILE" ]; then + echo "Previous local backup: $BACKUP_FILE" +fi +echo "" +echo "To start local beady:" +echo " cd $LOCAL_BEADS_DIR && beady --port 8081" diff --git a/scripts/sync-local-to-cloud.sh b/scripts/sync-local-to-cloud.sh new file mode 100644 index 0000000..5f135a1 --- /dev/null +++ b/scripts/sync-local-to-cloud.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# Sync local Beads database to Fly.io cloud backup +# This script pushes beads.jsonl from local to cloud + +set -e + +# Configuration +APP_NAME="${1:-beady-backup}" +LOCAL_BEADS_DIR="${2:-$HOME/.beads}" + +echo "=== Sync Local → Cloud ===" +echo " App: $APP_NAME" +echo " Local DB: $LOCAL_BEADS_DIR" +echo "" + +# Check if flyctl is installed +if ! command -v flyctl &> /dev/null; then + echo "ERROR: flyctl not found" + exit 1 +fi + +# Check if local database exists +if [ ! -f "$LOCAL_BEADS_DIR/beads.jsonl" ]; then + echo "ERROR: Local database not found at $LOCAL_BEADS_DIR/beads.jsonl" + exit 1 +fi + +# Create backup of cloud database first +echo "Step 1: Creating backup of cloud database..." +BACKUP_FILE="/tmp/beads-cloud-backup-$(date +%Y%m%d-%H%M%S).jsonl" +flyctl ssh console -a "$APP_NAME" -C "cat /data/.beads/beads.jsonl" > "$BACKUP_FILE" 2>/dev/null || { + echo "No existing cloud database found (this is OK for first sync)" +} + +# Upload local database to cloud +echo "Step 2: Uploading local database to cloud..." +flyctl ssh console -a "$APP_NAME" -C "mkdir -p /data/.beads" +cat "$LOCAL_BEADS_DIR/beads.jsonl" | flyctl ssh console -a "$APP_NAME" -C "cat > /data/.beads/beads.jsonl" + +# Copy config file if exists +if [ -f "$LOCAL_BEADS_DIR/config.json" ]; then + echo "Step 3: Uploading config.json..." + cat "$LOCAL_BEADS_DIR/config.json" | flyctl ssh console -a "$APP_NAME" -C "cat > /data/.beads/config.json" +fi + +# Restart the app to reload data +echo "Step 4: Restarting cloud app..." +flyctl apps restart "$APP_NAME" + +echo "" +echo "=== Sync Complete! ===" +echo "Local database synced to cloud" +if [ -f "$BACKUP_FILE" ]; then + echo "Cloud backup saved to: $BACKUP_FILE" +fi +echo "" +echo "Verify at: https://${APP_NAME}.fly.dev"