diff --git a/DOCKER_DEV_SETUP.md b/DOCKER_DEV_SETUP.md new file mode 100644 index 00000000..5cfb0d2e --- /dev/null +++ b/DOCKER_DEV_SETUP.md @@ -0,0 +1,302 @@ +# Archipelago Docker Development Environment + +This setup provides a complete development environment with all apps running in Docker containers, mimicking the production environment as closely as possible. + +## Overview + +All apps from the "My Apps" page are prepackaged and run as Docker containers: + +- **Bitcoin Core** (regtest mode - no blockchain sync) +- **BTCPay Server** (Bitcoin payment processor) +- **Endurain** (placeholder) +- **Fedimint** (federated Bitcoin mint) +- **Grafana** (monitoring/analytics) +- **Home Assistant** (home automation) +- **Lightning Stack** (LND - Lightning Network) +- **Mempool** (blockchain explorer) +- **MorphOS Server** (placeholder) +- **Ollama** (local LLM) +- **OnlyOffice** (office suite) +- **Penpot** (design platform) +- **SearXNG** (privacy-respecting search) + +## Quick Start + +### Prerequisites + +- Docker Desktop installed and running +- Node.js 18+ installed +- ~4GB of free disk space for Docker images + +### Starting Development Environment + +From the `neode-ui` directory: + +```bash +npm start +``` + +This will: +1. Check and start Docker Desktop if needed +2. Start all Docker containers with apps +3. Start the mock backend API server (port 5959) +4. Start the Vite dev server (port 8100) + +### Stopping Everything + +From the `neode-ui` directory: + +```bash +npm stop +``` + +This stops all Node processes and Docker containers. + +## Manual Docker Control + +### Start all Docker apps + +```bash +./start-docker-apps.sh +``` + +### Stop all Docker apps + +```bash +./stop-docker-apps.sh +``` + +### View logs for a specific app + +```bash +docker compose logs -f [service-name] + +# Examples: +docker compose logs -f bitcoin +docker compose logs -f btcpay +docker compose logs -f lnd +``` + +### Restart a specific app + +```bash +docker compose restart [service-name] +``` + +### View all running containers + +```bash +docker compose ps +``` + +## App URLs + +All apps are accessible on localhost with unique ports: + +| App | URL | Notes | +|-----|-----|-------| +| Bitcoin Core | http://localhost:18443 | RPC only (regtest) | +| BTCPay Server | http://localhost:14142 | Full UI | +| Endurain | http://localhost:8084 | Placeholder | +| Fedimint | http://localhost:8173 | API | +| Grafana | http://localhost:3000 | UI (admin/admin) | +| Home Assistant | http://localhost:8123 | Full UI | +| Lightning (REST) | http://localhost:8080 | REST API | +| Lightning (gRPC) | localhost:10009 | gRPC | +| Mempool | http://localhost:4080 | Full UI | +| MorphOS | http://localhost:8081 | Placeholder | +| Ollama | http://localhost:11434 | API | +| OnlyOffice | http://localhost:8083 | Full UI | +| Penpot | http://localhost:9001 | Full UI | +| SearXNG | http://localhost:8082 | Full UI | + +## Architecture + +### Docker Compose Structure + +The `docker-compose.yml` file orchestrates all services: + +- **Networking**: All services run on a shared `archy-net` bridge network +- **Volumes**: Persistent data stored in Docker volumes +- **Dependencies**: Services with dependencies (e.g., BTCPay depends on Bitcoin Core) start in the correct order + +### Bitcoin & Lightning + +- **Bitcoin Core** runs in regtest mode (no mainnet/testnet sync) +- **LND** connects to Bitcoin Core for Lightning functionality +- Both are pre-configured to work together without blockchain sync +- Generate test blocks with: `docker exec archy-bitcoin bitcoin-cli -regtest -rpcuser=bitcoin -rpcpassword=bitcoinpass generatetoaddress 101
` + +### Database Services + +Some apps require databases: +- BTCPay Server โ†’ PostgreSQL +- Mempool โ†’ MariaDB +- Penpot โ†’ PostgreSQL + Redis + +These are automatically started as supporting services. + +## Development Workflow + +### Starting Development + +```bash +cd neode-ui +npm start +``` + +The UI will be available at http://localhost:8100 + +### Testing App Launch + +1. Open http://localhost:8100 in your browser +2. Navigate to "My Apps" +3. Apps appear alphabetically and stay in order regardless of state +4. Click "Launch" on any running app to open it in a new tab + +### Stop/Start Apps + +Use the UI buttons or manually: + +```bash +# Stop an app +docker compose stop bitcoin + +# Start an app +docker compose start bitcoin + +# Restart an app +docker compose restart bitcoin +``` + +### Viewing Logs + +Monitor app logs: + +```bash +# All logs +docker compose logs -f + +# Specific app +docker compose logs -f bitcoin + +# Last 50 lines +docker compose logs --tail=50 bitcoin +``` + +### Resetting Data + +Remove all app data and start fresh: + +```bash +./stop-docker-apps.sh +docker compose down -v # Remove volumes +./start-docker-apps.sh +``` + +## Configuration + +### Bitcoin Core (Regtest) + +Configuration is in `docker-compose.yml`: +- RPC user: `bitcoin` +- RPC password: `bitcoinpass` +- Ports: 18443 (RPC), 18444 (P2P) + +### Grafana + +Default credentials: +- Username: `admin` +- Password: `admin` + +### App Icons + +Icons are loaded from `/assets/img/app-icons/` in the UI. + +## Troubleshooting + +### Docker not starting + +```bash +# Check if Docker is running +docker ps + +# Start Docker Desktop manually +open -a Docker +``` + +### Port conflicts + +If a port is already in use, modify `docker-compose.yml`: + +```yaml +services: + bitcoin: + ports: + - "18443:18443" # Change left side to a free port +``` + +### App won't start + +Check logs: + +```bash +docker compose logs [service-name] +``` + +Restart the container: + +```bash +docker compose restart [service-name] +``` + +### Out of disk space + +Clean up unused Docker data: + +```bash +docker system prune -a --volumes +``` + +### Reset everything + +```bash +npm stop +docker compose down -v +docker system prune -a +npm start +``` + +## Production vs Development + +### Development + +- Bitcoin Core in regtest (no blockchain) +- LND without real channels +- All services on localhost +- Placeholder apps for unimplemented services + +### Production (Future) + +- Bitcoin Core syncing mainnet +- LND with real Lightning channels +- Services behind reverse proxy +- All apps fully functional +- Tor integration +- Hardware security + +## Next Steps + +- Implement real start/stop functionality in the UI +- Connect backend API to Docker API +- Add health checks and status monitoring +- Implement backup/restore for Docker volumes +- Add app configuration UI +- Integrate with Tor for privacy + +## Resources + +- [Docker Compose Documentation](https://docs.docker.com/compose/) +- [Bitcoin Core Documentation](https://bitcoin.org/en/bitcoin-core/) +- [LND Documentation](https://docs.lightning.engineering/) +- [BTCPay Server Documentation](https://docs.btcpayserver.org/) diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index 258b1508..414c7226 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -1,384 +1,335 @@ -# ๐Ÿš€ Archipelago - Getting Started +# Getting Started with Archipelago Docker Development -Welcome to Archipelago! This guide will get you up and running in minutes. +This guide will help you get the full Archipelago development environment running with all apps containerized. -## โšก Quick Start +## What You'll Get -### Step 1: Install Dependencies +A complete Bitcoin node OS with 13+ apps running in Docker: +- Bitcoin Core (regtest - no blockchain download) +- Lightning Network (LND) +- BTCPay Server +- Mempool Explorer +- Home Assistant +- Grafana +- Ollama (local AI) +- SearXNG +- OnlyOffice +- Penpot +- And more... -Run the automated installation script: +## Prerequisites + +1. **Docker Desktop** - [Download here](https://www.docker.com/products/docker-desktop/) + - Mac: 4GB RAM minimum, 8GB recommended + - Disk space: ~5GB for all images + +2. **Node.js 18+** - [Download here](https://nodejs.org/) + +3. **Git** (you probably have this) + +## Installation Steps + +### Step 1: Start Docker Desktop + +Make sure Docker Desktop is running: +- Mac: Look for the Docker icon in your menu bar +- If not running, open Docker Desktop from Applications + +### Step 2: Clone and Setup ```bash -./INSTALL.sh +cd ~/Projects +git clone [your-repo] archy +cd archy ``` -This installs everything you need: -- โœ… Rust (latest stable) -- โœ… Node.js 18+ -- โœ… Podman (container runtime) -- โœ… PostgreSQL 15 -- โœ… All project dependencies - -**Note:** The script requires administrator privileges for Homebrew and system tools. - -### Step 2: Verify Installation +### Step 3: Install UI Dependencies ```bash -./verify-install.sh -``` - -This checks that all dependencies are properly installed and configured. - -### Step 3: Configure (Optional) - -Copy environment files and adjust if needed: - -```bash -# Backend configuration -cp core/.env.example core/.env - -# Frontend configuration -cp neode-ui/.env.example neode-ui/.env -``` - -### Step 4: Start Development - -Open two terminal windows: - -**Terminal 1 - Backend:** -```bash -cd core -cargo run --bin archipelago -``` - -**Terminal 2 - Frontend:** -```bash -cd neode-ui -npm run dev -``` - -### Step 5: Open in Browser - -Navigate to: **http://localhost:8100** - ---- - -## ๐Ÿ“‹ What Gets Installed - -| Tool | Purpose | Version Required | -|------|---------|-----------------| -| **Rust** | Backend development | Latest stable (1.93+) | -| **Node.js** | Frontend & custom apps | v18 or higher | -| **Podman** | Container runtime | Latest | -| **PostgreSQL** | Database | v15 | -| **Homebrew** | Package manager (macOS) | Latest | - ---- - -## ๐ŸŽฏ Alternative: Manual Installation - -If you prefer to install manually or the script fails, follow these steps: - -### 1. Install Homebrew (if not installed) - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -``` - -### 2. Install Rust - -```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source "$HOME/.cargo/env" -``` - -### 3. Install Node.js, Podman, and PostgreSQL - -```bash -brew install node podman postgresql@15 -``` - -### 4. Initialize Podman - -```bash -podman machine init -podman machine start -``` - -### 5. Start PostgreSQL - -```bash -brew services start postgresql@15 -createdb archipelago_dev -``` - -### 6. Install Project Dependencies - -```bash -# Frontend cd neode-ui npm install - -# Custom apps -cd ../apps/did-wallet && npm install -cd ../endurain && npm install -cd ../morphos-server && npm install -cd ../router && npm install -cd ../web5-dwn && npm install - -# Backend (this may take a while) -cd ../../core -cargo build ``` ---- - -## ๐Ÿ” Verify Everything Works - -Run the verification script: +### Step 4: Start Everything ```bash -./verify-install.sh +npm start ``` -You should see all checkmarks (โœ“). If you see warnings (โš ) or errors (โœ—), follow the suggested commands to fix them. +This will: +1. Check if Docker is running +2. Download all Docker images (first time only, ~10-30 minutes) +3. Start all containers +4. Start the development UI server ---- +**First Time?** You'll be prompted to confirm the image download. Type `y` and press Enter. -## ๐Ÿƒ Development Modes +### Step 5: Open the UI -### Mode 1: Full Stack (Recommended) +Once everything starts, open your browser to: -Best for full-stack development with real backend API. +**http://localhost:8100** -**Terminal 1:** -```bash -cd core && cargo run --bin archipelago -``` +Navigate to "My Apps" to see all your apps running! -**Terminal 2:** -```bash -cd neode-ui && npm run dev -``` +## What's Running? -**URLs:** -- Frontend: http://localhost:8100 -- Backend: http://localhost:5959 +After startup, you'll have these services: -### Mode 2: Mock Backend (Fastest) +### Bitcoin & Lightning Network +- **Bitcoin Core** - Full node in regtest mode (no mainnet sync) +- **LND** - Lightning Network daemon +- **BTCPay Server** - Accept Bitcoin payments +- **Mempool** - Blockchain explorer +- **Fedimint** - Federated Bitcoin mint -Best for frontend-only development without backend setup. +### Self-Hosted Apps +- **Home Assistant** - Home automation +- **Grafana** - Monitoring and analytics +- **SearXNG** - Private search engine +- **Ollama** - Run AI models locally -**Single Terminal:** -```bash -cd neode-ui && npm run dev:mock -``` +### Collaboration Tools +- **OnlyOffice** - Office suite (docs, spreadsheets, presentations) +- **Penpot** - Design and prototyping (like Figma) -**URL:** -- Frontend: http://localhost:8100 -- Mock API: http://localhost:3000 +### Placeholders +- **Endurain** - Coming soon +- **MorphOS** - Coming soon -### Mode 3: Quick Dev Script +## Using the Apps -Uses convenience scripts for easy startup. +### From the UI + +1. Go to http://localhost:8100 +2. Click "My Apps" in the sidebar +3. All apps are listed alphabetically +4. Click "Launch" on any running app + +### Direct Access + +All apps have unique ports: + +| App | URL | +|-----|-----| +| Grafana | http://localhost:3000 | +| Home Assistant | http://localhost:8123 | +| SearXNG | http://localhost:8082 | +| Mempool | http://localhost:4080 | +| Penpot | http://localhost:9001 | +| OnlyOffice | http://localhost:8083 | +| BTCPay Server | http://localhost:14142 | + +See [DOCKER_DEV_SETUP.md](DOCKER_DEV_SETUP.md) for the complete list. + +## Managing Apps + +### Start/Stop Individual Apps ```bash -./scripts/dev.sh # Mock backend mode -# or -./scripts/dev-start.sh # Interactive mode +# Stop an app +docker compose stop bitcoin + +# Start an app +docker compose start bitcoin + +# Restart an app +docker compose restart bitcoin ``` ---- +### View Logs -## ๐Ÿ“ Project Structure +```bash +# All logs +docker compose logs -f + +# Specific app +docker compose logs -f bitcoin +docker compose logs -f btcpay +docker compose logs -f lnd +``` + +### Check Status + +```bash +docker compose ps +``` + +## Stopping Everything + +### Stop All Apps + +```bash +cd neode-ui +npm stop +``` + +This stops the UI and all Docker containers. + +### Stop Just Docker Apps + +```bash +cd .. # Go to project root +./stop-docker-apps.sh +``` + +### Remove All Data (Fresh Start) + +```bash +docker compose down -v +``` + +**Warning:** This deletes all app data! + +## Troubleshooting + +### Docker not starting + +```bash +# Check if Docker is running +docker ps + +# If not, start Docker Desktop +open -a Docker +``` + +### Port conflicts + +If you see port errors: +1. Check what's using the port: `lsof -i :PORT` +2. Stop that service or change the port in `docker-compose.yml` + +### App won't load + +1. Check if container is running: `docker compose ps` +2. View logs: `docker compose logs [app-name]` +3. Restart the container: `docker compose restart [app-name]` + +### Out of disk space + +Clean up Docker: + +```bash +docker system prune -a +``` + +### Complete reset + +```bash +cd neode-ui +npm stop +cd .. +docker compose down -v +docker system prune -a +cd neode-ui +npm start +``` + +## Development Tips + +### Making Changes + +The UI hot-reloads automatically. Just edit files in `neode-ui/src/` and refresh your browser. + +### Testing Bitcoin Stuff + +Bitcoin Core runs in regtest mode - you can generate blocks instantly: + +```bash +# Get a new address +docker exec archy-bitcoin bitcoin-cli -regtest -rpcuser=bitcoin -rpcpassword=bitcoinpass getnewaddress + +# Generate blocks to that address +docker exec archy-bitcoin bitcoin-cli -regtest -rpcuser=bitcoin -rpcpassword=bitcoinpass generatetoaddress 101 [address] +``` + +### Using Lightning + +LND connects to Bitcoin Core automatically. Access the REST API at http://localhost:8080. + +### Adding New Apps + +1. Add service to `docker-compose.yml` +2. Add entry to `neode-ui/src/utils/dummyApps.ts` +3. Restart: `npm stop && npm start` + +## File Structure ``` archy/ -โ”œโ”€โ”€ ๐Ÿ“„ INSTALL.sh # Install all dependencies -โ”œโ”€โ”€ ๐Ÿ“„ verify-install.sh # Verify installation -โ”œโ”€โ”€ ๐Ÿ“„ SETUP_GUIDE.md # Detailed setup guide -โ”œโ”€โ”€ ๐Ÿ“„ QUICK_REFERENCE.md # Command reference -โ”œโ”€โ”€ ๐Ÿ“„ README.md # Main documentation -โ”‚ -โ”œโ”€โ”€ ๐Ÿฆ€ core/ # Rust backend -โ”‚ โ”œโ”€โ”€ archipelago/ # Main binary -โ”‚ โ”œโ”€โ”€ container/ # Container management -โ”‚ โ”œโ”€โ”€ parmanode/ # Parmanode integration -โ”‚ โ”œโ”€โ”€ security/ # Security modules -โ”‚ โ””โ”€โ”€ performance/ # Performance optimization -โ”‚ -โ”œโ”€โ”€ ๐ŸŽจ neode-ui/ # Vue.js frontend -โ”‚ โ”œโ”€โ”€ src/ # Source files -โ”‚ โ”œโ”€โ”€ public/ # Static assets -โ”‚ โ””โ”€โ”€ package.json # Node dependencies -โ”‚ -โ”œโ”€โ”€ ๐Ÿ“ฆ apps/ # Containerized apps -โ”‚ โ”œโ”€โ”€ bitcoin-core/ # Bitcoin node -โ”‚ โ”œโ”€โ”€ lnd/ # Lightning Network -โ”‚ โ”œโ”€โ”€ router/ # Mesh router -โ”‚ โ”œโ”€โ”€ did-wallet/ # Web5 wallet -โ”‚ โ””โ”€โ”€ web5-dwn/ # Web5 DWN server -โ”‚ -โ”œโ”€โ”€ ๐Ÿ“š docs/ # Documentation -โ”‚ โ”œโ”€โ”€ development-setup.md -โ”‚ โ”œโ”€โ”€ architecture.md -โ”‚ โ””โ”€โ”€ app-manifest-spec.md -โ”‚ -โ””โ”€โ”€ ๐Ÿ”ง scripts/ # Development scripts - โ”œโ”€โ”€ dev.sh - โ””โ”€โ”€ dev-start.sh +โ”œโ”€โ”€ docker-compose.yml # All app definitions +โ”œโ”€โ”€ start-docker-apps.sh # Start all Docker apps +โ”œโ”€โ”€ stop-docker-apps.sh # Stop all Docker apps +โ”œโ”€โ”€ DOCKER_DEV_SETUP.md # Detailed documentation +โ”œโ”€โ”€ docker/ # Placeholder app HTML +โ”‚ โ”œโ”€โ”€ endurain-placeholder/ +โ”‚ โ””โ”€โ”€ morphos-placeholder/ +โ””โ”€โ”€ neode-ui/ # Vue.js UI + โ”œโ”€โ”€ package.json + โ”œโ”€โ”€ start-dev.sh # Main dev startup (npm start) + โ”œโ”€โ”€ stop-dev.sh # Stop everything (npm stop) + โ””โ”€โ”€ src/ + โ”œโ”€โ”€ views/Apps.vue # My Apps page + โ””โ”€โ”€ utils/dummyApps.ts # App definitions ``` +## Next Steps + +1. **Explore the apps** - Try opening different services +2. **Check the logs** - See what's happening: `docker compose logs -f` +3. **Read the docs** - See [DOCKER_DEV_SETUP.md](DOCKER_DEV_SETUP.md) for details +4. **Start building** - The UI and backend are ready for development! + +## Common Tasks + +### Update all images + +```bash +cd ~/Projects/archy +docker compose pull +docker compose up -d +``` + +### Backup data + +```bash +docker compose down +cp -r /var/lib/docker/volumes ~/docker-backup +``` + +### Check resource usage + +```bash +docker stats +``` + +### See all containers + +```bash +docker ps -a +``` + +## Getting Help + +- **Documentation**: See [DOCKER_DEV_SETUP.md](DOCKER_DEV_SETUP.md) +- **Logs**: `docker compose logs -f [service-name]` +- **Status**: `docker compose ps` +- **Docker issues**: Check Docker Desktop logs + +## Architecture + +This setup mimics production as closely as possible: + +- **Production**: Alpine Linux + Podman + Real apps +- **Development**: macOS/Linux + Docker + Same app images + +Key differences: +- Bitcoin in regtest (no blockchain sync) +- All on localhost (no Tor) +- Simpler networking (single bridge network) + +See [Architecture.md](.cursor/rules/Architecture.mdc) for the full production architecture. + --- -## ๐Ÿ› ๏ธ Common Commands - -### Development - -```bash -# Start backend -cd core && cargo run --bin archipelago - -# Start frontend -cd neode-ui && npm run dev - -# Start with mock backend -cd neode-ui && npm run dev:mock - -# Build for production -cd neode-ui && npm run build -cd core && cargo build --release -``` - -### Container Apps - -```bash -# Build all apps -cd apps && ./build.sh - -# Build specific app -cd apps && ./build.sh router -``` - -### Maintenance - -```bash -# Update Rust -rustup update - -# Update Node packages -cd neode-ui && npm update - -# Check PostgreSQL status -brew services list | grep postgresql - -# Check Podman status -podman machine list -``` - ---- - -## ๐Ÿ› Troubleshooting - -### Port Already in Use - -```bash -# Find what's using the port -lsof -i :5959 # Backend -lsof -i :8100 # Frontend - -# Kill the process -kill -9 -``` - -### Podman Not Running - -```bash -podman machine start -``` - -### PostgreSQL Not Running - -```bash -brew services start postgresql@15 -``` - -### Rust Compilation Errors - -```bash -# Clean and rebuild -cd core -cargo clean -cargo build -``` - -### Node Module Issues - -```bash -cd neode-ui -rm -rf node_modules package-lock.json -npm install -``` - ---- - -## ๐Ÿ“– Next Steps - -Once everything is running: - -1. **Explore the UI** at http://localhost:8100 -2. **Read the docs:** - - [SETUP_GUIDE.md](SETUP_GUIDE.md) - Detailed setup - - [QUICK_REFERENCE.md](QUICK_REFERENCE.md) - Command cheatsheet - - [docs/architecture.md](docs/architecture.md) - System architecture - - [apps/QUICKSTART.md](apps/QUICKSTART.md) - Build and run apps - -3. **Build containerized apps:** - ```bash - cd apps - ./build.sh - ``` - -4. **Install apps via UI** at http://localhost:8100 - ---- - -## ๐Ÿ’ก Tips - -- Use `cargo watch` for auto-reload: - ```bash - cargo install cargo-watch - cd core && cargo watch -x 'run --bin archipelago' - ``` - -- Frontend has hot module replacement (HMR) - changes reflect instantly - -- Keep PostgreSQL and Podman running in the background - -- Use the mock backend for quick UI prototyping - ---- - -## ๐Ÿ†˜ Getting Help - -1. Run `./verify-install.sh` to diagnose issues -2. Check the [SETUP_GUIDE.md](SETUP_GUIDE.md) for detailed instructions -3. Review [docs/](docs/) for specific topics -4. Make sure all services are running (PostgreSQL, Podman) - ---- - -## โœ… Success Checklist - -- [ ] Rust installed (`rustc --version`) -- [ ] Node.js installed (`node --version`) -- [ ] Podman installed and running (`podman machine list`) -- [ ] PostgreSQL running (`brew services list`) -- [ ] Frontend dependencies installed (`neode-ui/node_modules` exists) -- [ ] Backend compiles (`cd core && cargo build`) -- [ ] Can access frontend at http://localhost:8100 -- [ ] Can access backend at http://localhost:5959 - ---- - -**Welcome to Archipelago! Happy coding! ๐ŸŽ‰** +**Ready to build a Bitcoin node OS? Start with `npm start`! ๐Ÿš€** diff --git a/core/Cargo.lock b/core/Cargo.lock index 3905cca2..bfb9b3d3 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -40,15 +40,15 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 0.14.32", - "hyper-tungstenite", "hyper-util", + "hyper-ws-listener", "serde", "serde_json", "serde_yaml", "thiserror", "tokio", "tokio-test", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite", "toml", "tower", "tower-http", @@ -325,6 +325,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -549,6 +562,12 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "http" version = "0.2.12" @@ -616,6 +635,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + [[package]] name = "hyper" version = "0.14.32" @@ -676,19 +701,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "hyper-tungstenite" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226df6fd0aece319a325419d770aa9d947defa60463f142cd82b329121f906a3" -dependencies = [ - "hyper 0.14.32", - "pin-project", - "tokio", - "tokio-tungstenite 0.19.0", - "tungstenite 0.19.0", -] - [[package]] name = "hyper-util" version = "0.1.19" @@ -716,6 +728,23 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "hyper-ws-listener" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbfe4981e45b0a7403a55d4af12f8d30e173e722409658c3857243990e72180" +dependencies = [ + "anyhow", + "base64 0.21.7", + "env_logger", + "futures", + "hyper 0.14.32", + "log", + "sha-1", + "tokio", + "tokio-tungstenite", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -869,6 +898,17 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "itoa" version = "1.0.17" @@ -1070,26 +1110,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1189,6 +1209,18 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.4.13" @@ -1395,6 +1427,17 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1558,6 +1601,15 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -1657,18 +1709,6 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "tokio-tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.19.0", -] - [[package]] name = "tokio-tungstenite" version = "0.20.1" @@ -1677,10 +1717,8 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "native-tls", "tokio", - "tokio-native-tls", - "tungstenite 0.20.1", + "tungstenite", ] [[package]] @@ -1842,25 +1880,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 0.2.12", - "httparse", - "log", - "rand", - "sha1", - "thiserror", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.20.1" @@ -1873,7 +1892,6 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "native-tls", "rand", "sha1", "thiserror", @@ -2045,6 +2063,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "windows-core" version = "0.62.2" diff --git a/core/archipelago/Cargo.toml b/core/archipelago/Cargo.toml index 60607bd1..ee17b120 100644 --- a/core/archipelago/Cargo.toml +++ b/core/archipelago/Cargo.toml @@ -26,8 +26,8 @@ http-body-util = "0.1" http-body = "1.0" tower = "0.5" tower-http = { version = "0.6", features = ["cors", "trace"] } -tokio-tungstenite = { version = "0.20", features = ["native-tls"] } -hyper-tungstenite = { version = "0.10", default-features = false } +hyper-ws-listener = "0.3.0" +tokio-tungstenite = "0.20" futures-util = "0.3" # Our modules diff --git a/core/archipelago/src/api/handler.rs b/core/archipelago/src/api/handler.rs index 282f2788..92f46f51 100644 --- a/core/archipelago/src/api/handler.rs +++ b/core/archipelago/src/api/handler.rs @@ -3,9 +3,10 @@ use crate::config::Config; use anyhow::Result; use futures_util::{SinkExt, StreamExt}; use hyper::{Method, Request, Response, StatusCode}; -use hyper_tungstenite::tungstenite::Message; +use hyper_ws_listener::WsStream; use std::sync::Arc; -use tracing::{debug, error, info}; +use tokio_tungstenite::tungstenite::Message; +use tracing::{debug, info}; pub struct ApiHandler { _config: Config, @@ -58,40 +59,44 @@ impl ApiHandler { async fn handle_websocket( req: Request, ) -> Result> { - if !hyper_tungstenite::is_upgrade_request(&req) { - return Ok(Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(hyper::Body::from("Expected WebSocket upgrade"))?); - } - - let (response, ws_fut) = hyper_tungstenite::upgrade(req, None) + let (response, ws_fut_opt) = hyper_ws_listener::create_ws(req) .map_err(|e| anyhow::anyhow!("WebSocket upgrade failed: {}", e))?; - // Spawn a task to hold the connection open and avoid EPIPE when the UI connects - tokio::spawn(async move { - let mut ws_stream = match ws_fut.await { - Ok(s) => s, - Err(e) => { - error!("WebSocket handshake failed: {}", e); - return; - } - }; - info!("WebSocket /ws/db connected"); - // Keep connection open; UI may send/receive JSON patches. For now just accept and ignore. - while let Some(msg) = ws_stream.next().await { - match msg { - Ok(Message::Close(_)) => break, - Ok(Message::Ping(data)) => { - let _ = ws_stream.send(Message::Pong(data)).await; + // Spawn a task to hold the connection open if upgrade future exists + if let Some(ws_fut) = ws_fut_opt { + tokio::spawn(async move { + let ws_stream: WsStream = match ws_fut.await { + Ok(Ok(s)) => s, + Ok(Err(e)) => { + debug!("WebSocket handshake failed (hyper): {}", e); + return; } - Ok(_) => {} Err(e) => { - debug!("WebSocket stream error: {}", e); - break; + debug!("WebSocket task join failed: {}", e); + return; + } + }; + info!("WebSocket /ws/db connected"); + + let (mut tx, mut rx) = ws_stream.split(); + + // Keep connection open; UI may send/receive JSON patches. For now just accept and ignore. + while let Some(msg) = rx.next().await { + match msg { + Ok(Message::Close(_)) => break, + Ok(Message::Ping(data)) => { + let _ = tx.send(Message::Pong(data)).await; + } + Ok(_) => {} + Err(e) => { + debug!("WebSocket stream error: {}", e); + break; + } } } - } - }); + info!("WebSocket /ws/db disconnected"); + }); + } Ok(response) } diff --git a/core/archipelago/src/server.rs b/core/archipelago/src/server.rs index 8c9a6bd8..29c1e635 100644 --- a/core/archipelago/src/server.rs +++ b/core/archipelago/src/server.rs @@ -48,6 +48,7 @@ impl Server { if let Err(e) = Http::new() .serve_connection(stream, service) + .with_upgrades() .await { error!("Error serving connection from {}: {}", peer_addr, e); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..68e88645 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,323 @@ +services: + # Bitcoin Core - regtest mode (no blockchain sync) + bitcoin: + image: lncm/bitcoind:v27.0 + container_name: archy-bitcoin + ports: + - "18443:18443" # RPC + - "18444:18444" # P2P + volumes: + - bitcoin-data:/data/.bitcoin + command: | + -regtest + -server + -rpcuser=bitcoin + -rpcpassword=bitcoinpass + -rpcallowip=0.0.0.0/0 + -rpcbind=0.0.0.0 + -txindex=1 + -zmqpubrawblock=tcp://0.0.0.0:28332 + -zmqpubrawtx=tcp://0.0.0.0:28333 + restart: unless-stopped + networks: + - archy-net + + # BTCPay Server + btcpay: + image: btcpayserver/btcpayserver:1.13.5 + container_name: archy-btcpay + ports: + - "14142:49392" + environment: + BTCPAY_PROTOCOL: http + BTCPAY_HOST: localhost:14142 + BTCPAY_CHAINS: btc + BTCPAY_BTCEXPLORERURL: http://mempool:4080 + BTCPAY_BTCRPCURL: http://bitcoin:18443 + BTCPAY_BTCRPCUSER: bitcoin + BTCPAY_BTCRPCPASSWORD: bitcoinpass + depends_on: + - bitcoin + - postgres-btcpay + restart: unless-stopped + networks: + - archy-net + + postgres-btcpay: + image: postgres:15-alpine + container_name: archy-btcpay-db + environment: + POSTGRES_DB: btcpay + POSTGRES_USER: btcpay + POSTGRES_PASSWORD: btcpaypass + volumes: + - postgres-btcpay-data:/var/lib/postgresql/data + restart: unless-stopped + networks: + - archy-net + + # Home Assistant + homeassistant: + image: homeassistant/home-assistant:2024.1 + container_name: archy-homeassistant + ports: + - "8123:8123" + volumes: + - homeassistant-data:/config + environment: + TZ: America/New_York + restart: unless-stopped + networks: + - archy-net + + # Grafana + grafana: + image: grafana/grafana:10.2.0 + container_name: archy-grafana + ports: + - "3000:3000" + volumes: + - grafana-data:/var/lib/grafana + environment: + GF_SECURITY_ADMIN_PASSWORD: admin + GF_USERS_ALLOW_SIGN_UP: "false" + restart: unless-stopped + networks: + - archy-net + + # Fedimint (using guardians setup) + fedimint: + image: fedimint/fedimintd:v0.3.0 + container_name: archy-fedimint + ports: + - "8173:8173" + volumes: + - fedimint-data:/data + environment: + FM_BIND_P2P: 0.0.0.0:8173 + FM_BIND_API: 0.0.0.0:8174 + restart: unless-stopped + networks: + - archy-net + + # Lightning Network Daemon (LND) + lnd: + image: lightninglabs/lnd:v0.17.4-beta + container_name: archy-lnd + ports: + - "9735:9735" # P2P + - "8080:8080" # REST + - "10009:10009" # gRPC + volumes: + - lnd-data:/root/.lnd + command: | + --bitcoin.active + --bitcoin.regtest + --bitcoin.node=bitcoind + --bitcoind.rpchost=bitcoin:18443 + --bitcoind.rpcuser=bitcoin + --bitcoind.rpcpass=bitcoinpass + --bitcoind.zmqpubrawblock=tcp://bitcoin:28332 + --bitcoind.zmqpubrawtx=tcp://bitcoin:28333 + --debuglevel=info + --rpclisten=0.0.0.0:10009 + --restlisten=0.0.0.0:8080 + --noseedbackup + depends_on: + - bitcoin + restart: unless-stopped + networks: + - archy-net + + # Mempool Explorer + mempool-web: + image: mempool/frontend:v2.5.0 + container_name: archy-mempool-web + ports: + - "4080:8080" + environment: + FRONTEND_HTTP_PORT: 8080 + BACKEND_MAINNET_HTTP_HOST: mempool-api + depends_on: + - mempool-api + restart: unless-stopped + networks: + - archy-net + + mempool-api: + image: mempool/backend:v2.5.0 + container_name: archy-mempool-api + environment: + MEMPOOL_BACKEND: electrum + ELECTRUM_HOST: bitcoin + ELECTRUM_PORT: 50001 + ELECTRUM_TLS_ENABLED: "false" + CORE_RPC_HOST: bitcoin + CORE_RPC_PORT: 18443 + CORE_RPC_USERNAME: bitcoin + CORE_RPC_PASSWORD: bitcoinpass + DATABASE_ENABLED: "true" + DATABASE_HOST: mysql-mempool + DATABASE_DATABASE: mempool + DATABASE_USERNAME: mempool + DATABASE_PASSWORD: mempoolpass + depends_on: + - bitcoin + - mysql-mempool + restart: unless-stopped + networks: + - archy-net + + mysql-mempool: + image: mariadb:10.11 + container_name: archy-mempool-db + environment: + MYSQL_DATABASE: mempool + MYSQL_USER: mempool + MYSQL_PASSWORD: mempoolpass + MYSQL_ROOT_PASSWORD: rootpass + volumes: + - mysql-mempool-data:/var/lib/mysql + restart: unless-stopped + networks: + - archy-net + + # Ollama (Local LLM) + ollama: + image: ollama/ollama:latest + container_name: archy-ollama + ports: + - "11434:11434" + volumes: + - ollama-data:/root/.ollama + restart: unless-stopped + networks: + - archy-net + + # SearXNG + searxng: + image: searxng/searxng:latest + container_name: archy-searxng + ports: + - "8082:8080" + volumes: + - searxng-data:/etc/searxng + environment: + SEARXNG_BASE_URL: http://localhost:8082/ + restart: unless-stopped + networks: + - archy-net + + # OnlyOffice Document Server + onlyoffice: + image: onlyoffice/documentserver:7.5.1 + container_name: archy-onlyoffice + ports: + - "8083:80" + volumes: + - onlyoffice-data:/var/www/onlyoffice/Data + - onlyoffice-logs:/var/log/onlyoffice + environment: + JWT_ENABLED: "false" + restart: unless-stopped + networks: + - archy-net + + # Penpot + penpot-frontend: + image: penpotapp/frontend:latest + container_name: archy-penpot-frontend + ports: + - "9001:80" + environment: + PENPOT_FLAGS: enable-registration enable-login-with-password + PENPOT_BACKEND_URI: http://penpot-backend:6060 + depends_on: + - penpot-backend + restart: unless-stopped + networks: + - archy-net + + penpot-backend: + image: penpotapp/backend:latest + container_name: archy-penpot-backend + environment: + PENPOT_FLAGS: enable-registration enable-login-with-password disable-email-verification + PENPOT_DATABASE_URI: postgresql://postgres-penpot/penpot + PENPOT_DATABASE_USERNAME: penpot + PENPOT_DATABASE_PASSWORD: penpotpass + PENPOT_REDIS_URI: redis://redis-penpot/0 + PENPOT_ASSETS_STORAGE_BACKEND: assets-fs + PENPOT_STORAGE_ASSETS_FS_DIRECTORY: /opt/data/assets + volumes: + - penpot-assets:/opt/data/assets + depends_on: + - postgres-penpot + - redis-penpot + restart: unless-stopped + networks: + - archy-net + + postgres-penpot: + image: postgres:15-alpine + container_name: archy-penpot-db + environment: + POSTGRES_DB: penpot + POSTGRES_USER: penpot + POSTGRES_PASSWORD: penpotpass + volumes: + - postgres-penpot-data:/var/lib/postgresql/data + restart: unless-stopped + networks: + - archy-net + + redis-penpot: + image: redis:7-alpine + container_name: archy-penpot-redis + restart: unless-stopped + networks: + - archy-net + + # Placeholder services for apps without direct Docker images + # These will show "coming soon" pages or simple status pages + + endurain: + image: nginx:alpine + container_name: archy-endurain + ports: + - "8084:80" + volumes: + - ./docker/endurain-placeholder:/usr/share/nginx/html:ro + restart: unless-stopped + networks: + - archy-net + + morphos: + image: nginx:alpine + container_name: archy-morphos + ports: + - "8081:80" + volumes: + - ./docker/morphos-placeholder:/usr/share/nginx/html:ro + restart: unless-stopped + networks: + - archy-net + +volumes: + bitcoin-data: + postgres-btcpay-data: + homeassistant-data: + grafana-data: + fedimint-data: + lnd-data: + mysql-mempool-data: + ollama-data: + searxng-data: + onlyoffice-data: + onlyoffice-logs: + penpot-assets: + postgres-penpot-data: + +networks: + archy-net: + driver: bridge diff --git a/docker/endurain-placeholder/index.html b/docker/endurain-placeholder/index.html new file mode 100644 index 00000000..4b5f02ef --- /dev/null +++ b/docker/endurain-placeholder/index.html @@ -0,0 +1,47 @@ + + + + + + Endurain - Coming Soon + + + +
+

Endurain

+

Application platform for decentralized services

+
๐Ÿšง Coming Soon
+
+ + diff --git a/docker/morphos-placeholder/index.html b/docker/morphos-placeholder/index.html new file mode 100644 index 00000000..af1c2191 --- /dev/null +++ b/docker/morphos-placeholder/index.html @@ -0,0 +1,47 @@ + + + + + + MorphOS Server - Coming Soon + + + +
+

MorphOS Server

+

Flexible server platform for applications and services

+
๐Ÿšง Coming Soon
+
+ + diff --git a/neode-ui/dev-dist/sw.js b/neode-ui/dev-dist/sw.js index 303b8aa1..fdd9dc63 100644 --- a/neode-ui/dev-dist/sw.js +++ b/neode-ui/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.79uml52ju7g" + "revision": "0.6sndaq9c8b" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/neode-ui/src/utils/dummyApps.ts b/neode-ui/src/utils/dummyApps.ts index c4f6b21c..c07716f6 100644 --- a/neode-ui/src/utils/dummyApps.ts +++ b/neode-ui/src/utils/dummyApps.ts @@ -36,7 +36,7 @@ export const dummyApps: Record = { 'interface-addresses': { main: { 'tor-address': 'bitcoin.onion', - 'lan-address': 'http://localhost:8332' + 'lan-address': 'http://localhost:18443' } }, status: ServiceStatus.Running @@ -180,7 +180,7 @@ export const dummyApps: Record = { 'interface-addresses': { main: { 'tor-address': 'endurain.onion', - 'lan-address': 'http://localhost:8080' + 'lan-address': 'http://localhost:8084' } }, status: ServiceStatus.Stopped @@ -288,7 +288,7 @@ export const dummyApps: Record = { 'interface-addresses': { main: { 'tor-address': 'lightning.onion', - 'lan-address': 'http://localhost:9735' + 'lan-address': 'http://localhost:8080' } }, status: ServiceStatus.Running diff --git a/neode-ui/src/views/Apps.vue b/neode-ui/src/views/Apps.vue index 8238a39d..60eff8f8 100644 --- a/neode-ui/src/views/Apps.vue +++ b/neode-ui/src/views/Apps.vue @@ -22,10 +22,10 @@ - +
{ // return realPackages }) +// Sorted by manifest title, case-insensitive; order stable regardless of running/stopped +const sortedPackageEntries = computed(() => { + const entries = Object.entries(packages.value) + return entries.sort(([, a], [, b]) => + (a.manifest?.title ?? '').localeCompare(b.manifest?.title ?? '', undefined, { sensitivity: 'base' }) + ) +}) + const uninstallModal = ref({ show: false, appId: '', @@ -191,8 +199,17 @@ function canLaunch(pkg: any): boolean { function launchApp(id: string) { const isDev = import.meta.env.DEV + const pkg = packages.value[id] - // Special handling for apps with Docker containers + // Get the LAN address from the package manifest + const lanAddress = pkg?.installed?.['interface-addresses']?.main?.['lan-address'] + + if (lanAddress) { + window.open(lanAddress, '_blank', 'noopener,noreferrer') + return + } + + // Fallback: Special handling for apps with Docker containers const appUrls: Record = { 'atob': { dev: 'http://localhost:8102', diff --git a/neode-ui/start-dev.sh b/neode-ui/start-dev.sh index 6561751b..6af5205e 100755 --- a/neode-ui/start-dev.sh +++ b/neode-ui/start-dev.sh @@ -96,6 +96,18 @@ else fi echo "" +# Start Docker apps +if /usr/local/bin/docker ps > /dev/null 2>&1; then + echo -e "${BLUE}๐Ÿ๏ธ Starting Archipelago Docker apps...${NC}" + cd .. + ./start-docker-apps.sh + cd neode-ui + echo "" +else + echo -e "${YELLOW}โš ๏ธ Skipping Docker apps (Docker not available)${NC}" + echo "" +fi + # Check if node_modules exists if [ ! -d "node_modules" ]; then echo -e "${YELLOW}โš ๏ธ node_modules not found. Running npm install...${NC}" diff --git a/neode-ui/stop-dev.sh b/neode-ui/stop-dev.sh index 36c0b627..69418665 100755 --- a/neode-ui/stop-dev.sh +++ b/neode-ui/stop-dev.sh @@ -63,3 +63,14 @@ echo "" echo -e "${GREEN}โœ… All Neode development servers stopped!${NC}" echo "" +# Stop Docker containers +echo -e "${BLUE}๐Ÿณ Stopping Docker containers...${NC}" +if /usr/local/bin/docker ps > /dev/null 2>&1; then + cd .. + ./stop-docker-apps.sh + cd neode-ui +else + echo -e "${YELLOW} โ„น๏ธ Docker not running${NC}" +fi +echo "" + diff --git a/start-docker-apps.sh b/start-docker-apps.sh new file mode 100755 index 00000000..d11df25d --- /dev/null +++ b/start-docker-apps.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +# Archipelago Docker Environment Startup Script +# This script starts all the containerized apps for development + +set -e + +echo "๐Ÿ๏ธ Starting Archipelago Docker Environment..." +echo "" + +# Check if Docker is running +if ! docker info > /dev/null 2>&1; then + echo "โŒ Docker is not running. Please start Docker Desktop and try again." + exit 1 +fi + +# Check if docker-compose is available +if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null 2>&1; then + echo "โŒ docker-compose not found. Please install docker-compose." + exit 1 +fi + +# Use docker compose (new) or docker-compose (old) +if docker compose version &> /dev/null 2>&1; then + COMPOSE_CMD="docker compose" +else + COMPOSE_CMD="docker-compose" +fi + +# Check if this is first run (no images pulled) +FIRST_RUN=false +if ! docker images | grep -q "lncm/bitcoind\|homeassistant/home-assistant\|grafana/grafana"; then + FIRST_RUN=true + echo "๐Ÿ“ฅ First run detected! This will download Docker images (~3-5GB)." + echo " This may take 10-30 minutes depending on your internet speed." + echo "" + read -p " Continue? (y/N) " -n 1 -r + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Cancelled." + exit 0 + fi +fi + +if [ "$FIRST_RUN" = true ]; then + echo "๐Ÿ“ฆ Pulling Docker images (this will take a while)..." + echo "" + + # Pull in stages to show progress + echo " [1/4] Pulling Bitcoin & Lightning..." + $COMPOSE_CMD pull bitcoin lnd + + echo " [2/4] Pulling Web Apps..." + $COMPOSE_CMD pull homeassistant grafana searxng ollama + + echo " [3/4] Pulling Bitcoin Services..." + $COMPOSE_CMD pull btcpay mempool-web mempool-api fedimint + + echo " [4/4] Pulling Collaboration Tools..." + $COMPOSE_CMD pull onlyoffice penpot-frontend penpot-backend endurain morphos + + echo "" + echo "โœ… All images downloaded!" +else + echo "๐Ÿ“ฆ Checking for image updates..." + $COMPOSE_CMD pull --quiet +fi + +echo "" +echo "๐Ÿš€ Starting all containers..." +$COMPOSE_CMD up -d + +echo "" +echo "โณ Waiting for services to be ready..." +sleep 5 + +# Check health of key services +echo "" +echo "๐Ÿ” Checking service health..." +READY_COUNT=0 +TOTAL_SERVICES=13 + +check_service() { + local name=$1 + local url=$2 + if curl -sf "$url" > /dev/null 2>&1; then + echo " โœ… $name is ready" + ((READY_COUNT++)) + else + echo " โณ $name is starting..." + fi +} + +check_service "Grafana" "http://localhost:3000" +check_service "SearXNG" "http://localhost:8082" +check_service "Endurain" "http://localhost:8084" +check_service "MorphOS" "http://localhost:8081" + +echo "" +echo "๐Ÿ“Š Container Status:" +$COMPOSE_CMD ps + +echo "" +echo "๐ŸŒ Apps are available at:" +echo "" +echo " ๐Ÿ’ฐ Bitcoin & Lightning:" +echo " โ€ข Bitcoin Core (regtest): RPC at localhost:18443" +echo " โ€ข Lightning (LND REST): http://localhost:8080" +echo " โ€ข BTCPay Server: http://localhost:14142" +echo " โ€ข Mempool Explorer: http://localhost:4080" +echo " โ€ข Fedimint: http://localhost:8173" +echo "" +echo " ๐Ÿ  Self-Hosted Services:" +echo " โ€ข Home Assistant: http://localhost:8123" +echo " โ€ข Grafana: http://localhost:3000 (admin/admin)" +echo " โ€ข SearXNG: http://localhost:8082" +echo " โ€ข Ollama (API): http://localhost:11434" +echo "" +echo " ๐Ÿ“ Collaboration:" +echo " โ€ข OnlyOffice: http://localhost:8083" +echo " โ€ข Penpot: http://localhost:9001" +echo "" +echo " ๐Ÿšง Placeholders:" +echo " โ€ข Endurain: http://localhost:8084" +echo " โ€ข MorphOS Server: http://localhost:8081" +echo "" +echo "๐Ÿ’ก Tips:" +echo " โ€ข View logs: $COMPOSE_CMD logs -f [service-name]" +echo " โ€ข Stop all: $COMPOSE_CMD down" +echo " โ€ข Restart service: $COMPOSE_CMD restart [service-name]" +echo " โ€ข Check status: $COMPOSE_CMD ps" +echo "" +echo "๐ŸŽ‰ Ready! Open http://localhost:8100 to access the Neode UI" diff --git a/stop-docker-apps.sh b/stop-docker-apps.sh new file mode 100755 index 00000000..e64e4373 --- /dev/null +++ b/stop-docker-apps.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Archipelago Docker Environment Stop Script +# This script stops all the containerized apps + +set -e + +echo "๐Ÿ›‘ Stopping Archipelago Docker Environment..." + +# Use docker compose (new) or docker-compose (old) +if docker compose version &> /dev/null 2>&1; then + COMPOSE_CMD="docker compose" +else + COMPOSE_CMD="docker-compose" +fi + +$COMPOSE_CMD down + +echo "" +echo "โœ… All containers stopped successfully!" +echo "" +echo "๐Ÿ’ก To remove volumes (data), run: $COMPOSE_CMD down -v" diff --git a/test-docker-setup.sh b/test-docker-setup.sh new file mode 100755 index 00000000..b7decc06 --- /dev/null +++ b/test-docker-setup.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Quick test script to start a few lightweight apps +# This validates the Docker setup without pulling large images + +set -e + +echo "๐Ÿงช Testing Docker setup with lightweight apps..." +echo "" + +# Start just the placeholder apps and a few small services +docker compose up -d endurain morphos grafana searxng + +echo "" +echo "โœ… Test apps started!" +echo "" +echo "Test these URLs:" +echo " โ€ข Endurain: http://localhost:8084" +echo " โ€ข MorphOS: http://localhost:8081" +echo " โ€ข Grafana: http://localhost:3000" +echo " โ€ข SearXNG: http://localhost:8082" +echo ""