Refactor and enhance Archipelago setup and API

- Revamped GETTING_STARTED.md for clarity and completeness, detailing the Docker development environment and installation steps.
- Updated Cargo.lock and Cargo.toml to replace deprecated dependencies and add new ones, including hyper-ws-listener and env_logger.
- Improved WebSocket handling in the API to support upgrades and error management.
- Enhanced Neode UI scripts to manage Docker containers during development.
- Adjusted dummy app configurations for accurate LAN addresses.
- Sorted app entries in the UI for better organization and accessibility.
This commit is contained in:
Dorian 2026-01-27 22:47:51 +00:00
parent 4126aa0b33
commit 10fa19df66
17 changed files with 1370 additions and 450 deletions

302
DOCKER_DEV_SETUP.md Normal file
View File

@ -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 <address>`
### 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/)

View File

@ -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 <PID>
```
### 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`! 🚀**

167
core/Cargo.lock generated
View File

@ -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"

View File

@ -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

View File

@ -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<hyper::Body>,
) -> Result<Response<hyper::Body>> {
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)
}

View File

@ -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);

323
docker-compose.yml Normal file
View File

@ -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

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Endurain - Coming Soon</title>
<style>
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
text-align: center;
padding: 2rem;
}
h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
p {
font-size: 1.2rem;
opacity: 0.9;
}
.status {
display: inline-block;
background: rgba(255, 255, 255, 0.2);
padding: 0.5rem 1rem;
border-radius: 20px;
margin-top: 1rem;
}
</style>
</head>
<body>
<div class="container">
<h1>Endurain</h1>
<p>Application platform for decentralized services</p>
<div class="status">🚧 Coming Soon</div>
</div>
</body>
</html>

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MorphOS Server - Coming Soon</title>
<style>
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
text-align: center;
padding: 2rem;
}
h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
p {
font-size: 1.2rem;
opacity: 0.9;
}
.status {
display: inline-block;
background: rgba(255, 255, 255, 0.2);
padding: 0.5rem 1rem;
border-radius: 20px;
margin-top: 1rem;
}
</style>
</head>
<body>
<div class="container">
<h1>MorphOS Server</h1>
<p>Flexible server platform for applications and services</p>
<div class="status">🚧 Coming Soon</div>
</div>
</body>
</html>

View File

@ -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"), {

View File

@ -36,7 +36,7 @@ export const dummyApps: Record<string, PackageDataEntry> = {
'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<string, PackageDataEntry> = {
'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<string, PackageDataEntry> = {
'interface-addresses': {
main: {
'tor-address': 'lightning.onion',
'lan-address': 'http://localhost:9735'
'lan-address': 'http://localhost:8080'
}
},
status: ServiceStatus.Running

View File

@ -22,10 +22,10 @@
</div>
</div>
<!-- Apps Grid -->
<!-- Apps Grid (alphabetically by title, stable across run state) -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 pb-6">
<div
v-for="(pkg, id) in packages"
v-for="[id, pkg] in sortedPackageEntries"
:key="id"
class="glass-card p-6 transition-all hover:-translate-y-1 cursor-pointer relative"
@click="goToApp(id as string)"
@ -175,6 +175,14 @@ const packages = computed(() => {
// 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<string, { dev: string, prod: string }> = {
'atob': {
dev: 'http://localhost:8102',

View File

@ -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}"

View File

@ -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 ""

133
start-docker-apps.sh Executable file
View File

@ -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"

22
stop-docker-apps.sh Executable file
View File

@ -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"

22
test-docker-setup.sh Executable file
View File

@ -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 ""