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:
parent
4126aa0b33
commit
10fa19df66
302
DOCKER_DEV_SETUP.md
Normal file
302
DOCKER_DEV_SETUP.md
Normal 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/)
|
||||||
@ -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
|
```bash
|
||||||
./INSTALL.sh
|
cd ~/Projects
|
||||||
|
git clone [your-repo] archy
|
||||||
|
cd archy
|
||||||
```
|
```
|
||||||
|
|
||||||
This installs everything you need:
|
### Step 3: Install UI Dependencies
|
||||||
- ✅ 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
|
|
||||||
|
|
||||||
```bash
|
```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
|
cd neode-ui
|
||||||
npm install
|
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
### Step 4: Start Everything
|
||||||
|
|
||||||
## 🔍 Verify Everything Works
|
|
||||||
|
|
||||||
Run the verification script:
|
|
||||||
|
|
||||||
```bash
|
```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:**
|
Navigate to "My Apps" to see all your apps running!
|
||||||
```bash
|
|
||||||
cd core && cargo run --bin archipelago
|
|
||||||
```
|
|
||||||
|
|
||||||
**Terminal 2:**
|
## What's Running?
|
||||||
```bash
|
|
||||||
cd neode-ui && npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
**URLs:**
|
After startup, you'll have these services:
|
||||||
- Frontend: http://localhost:8100
|
|
||||||
- Backend: http://localhost:5959
|
|
||||||
|
|
||||||
### 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:**
|
### Collaboration Tools
|
||||||
```bash
|
- **OnlyOffice** - Office suite (docs, spreadsheets, presentations)
|
||||||
cd neode-ui && npm run dev:mock
|
- **Penpot** - Design and prototyping (like Figma)
|
||||||
```
|
|
||||||
|
|
||||||
**URL:**
|
### Placeholders
|
||||||
- Frontend: http://localhost:8100
|
- **Endurain** - Coming soon
|
||||||
- Mock API: http://localhost:3000
|
- **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
|
```bash
|
||||||
./scripts/dev.sh # Mock backend mode
|
# Stop an app
|
||||||
# or
|
docker compose stop bitcoin
|
||||||
./scripts/dev-start.sh # Interactive mode
|
|
||||||
|
# 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/
|
archy/
|
||||||
├── 📄 INSTALL.sh # Install all dependencies
|
├── docker-compose.yml # All app definitions
|
||||||
├── 📄 verify-install.sh # Verify installation
|
├── start-docker-apps.sh # Start all Docker apps
|
||||||
├── 📄 SETUP_GUIDE.md # Detailed setup guide
|
├── stop-docker-apps.sh # Stop all Docker apps
|
||||||
├── 📄 QUICK_REFERENCE.md # Command reference
|
├── DOCKER_DEV_SETUP.md # Detailed documentation
|
||||||
├── 📄 README.md # Main documentation
|
├── docker/ # Placeholder app HTML
|
||||||
│
|
│ ├── endurain-placeholder/
|
||||||
├── 🦀 core/ # Rust backend
|
│ └── morphos-placeholder/
|
||||||
│ ├── archipelago/ # Main binary
|
└── neode-ui/ # Vue.js UI
|
||||||
│ ├── container/ # Container management
|
├── package.json
|
||||||
│ ├── parmanode/ # Parmanode integration
|
├── start-dev.sh # Main dev startup (npm start)
|
||||||
│ ├── security/ # Security modules
|
├── stop-dev.sh # Stop everything (npm stop)
|
||||||
│ └── performance/ # Performance optimization
|
└── src/
|
||||||
│
|
├── views/Apps.vue # My Apps page
|
||||||
├── 🎨 neode-ui/ # Vue.js frontend
|
└── utils/dummyApps.ts # App definitions
|
||||||
│ ├── 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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 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
|
**Ready to build a Bitcoin node OS? Start with `npm start`! 🚀**
|
||||||
|
|
||||||
### 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! 🎉**
|
|
||||||
|
|||||||
167
core/Cargo.lock
generated
167
core/Cargo.lock
generated
@ -40,15 +40,15 @@ dependencies = [
|
|||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 0.14.32",
|
"hyper 0.14.32",
|
||||||
"hyper-tungstenite",
|
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
|
"hyper-ws-listener",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"tokio-tungstenite 0.20.1",
|
"tokio-tungstenite",
|
||||||
"toml",
|
"toml",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
@ -325,6 +325,19 @@ dependencies = [
|
|||||||
"cfg-if",
|
"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]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -549,6 +562,12 @@ version = "0.16.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@ -616,6 +635,12 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.32"
|
version = "0.14.32"
|
||||||
@ -676,19 +701,6 @@ dependencies = [
|
|||||||
"tokio-native-tls",
|
"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]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
@ -716,6 +728,23 @@ dependencies = [
|
|||||||
"windows-registry",
|
"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]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.64"
|
version = "0.1.64"
|
||||||
@ -869,6 +898,17 @@ version = "2.11.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
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]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
@ -1070,26 +1110,6 @@ version = "2.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
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]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -1189,6 +1209,18 @@ dependencies = [
|
|||||||
"bitflags 2.10.0",
|
"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]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
@ -1395,6 +1427,17 @@ dependencies = [
|
|||||||
"unsafe-libyaml",
|
"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]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -1558,6 +1601,15 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"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]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.69"
|
version = "1.0.69"
|
||||||
@ -1657,18 +1709,6 @@ dependencies = [
|
|||||||
"tokio-stream",
|
"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]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.20.1"
|
version = "0.20.1"
|
||||||
@ -1677,10 +1717,8 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tungstenite",
|
||||||
"tungstenite 0.20.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1842,25 +1880,6 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
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]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.20.1"
|
version = "0.20.1"
|
||||||
@ -1873,7 +1892,6 @@ dependencies = [
|
|||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
|
||||||
"rand",
|
"rand",
|
||||||
"sha1",
|
"sha1",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@ -2045,6 +2063,15 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"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]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.2"
|
version = "0.62.2"
|
||||||
|
|||||||
@ -26,8 +26,8 @@ http-body-util = "0.1"
|
|||||||
http-body = "1.0"
|
http-body = "1.0"
|
||||||
tower = "0.5"
|
tower = "0.5"
|
||||||
tower-http = { version = "0.6", features = ["cors", "trace"] }
|
tower-http = { version = "0.6", features = ["cors", "trace"] }
|
||||||
tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
|
hyper-ws-listener = "0.3.0"
|
||||||
hyper-tungstenite = { version = "0.10", default-features = false }
|
tokio-tungstenite = "0.20"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
|
|
||||||
# Our modules
|
# Our modules
|
||||||
|
|||||||
@ -3,9 +3,10 @@ use crate::config::Config;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
use hyper::{Method, Request, Response, StatusCode};
|
use hyper::{Method, Request, Response, StatusCode};
|
||||||
use hyper_tungstenite::tungstenite::Message;
|
use hyper_ws_listener::WsStream;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{debug, error, info};
|
use tokio_tungstenite::tungstenite::Message;
|
||||||
|
use tracing::{debug, info};
|
||||||
|
|
||||||
pub struct ApiHandler {
|
pub struct ApiHandler {
|
||||||
_config: Config,
|
_config: Config,
|
||||||
@ -58,31 +59,33 @@ impl ApiHandler {
|
|||||||
async fn handle_websocket(
|
async fn handle_websocket(
|
||||||
req: Request<hyper::Body>,
|
req: Request<hyper::Body>,
|
||||||
) -> Result<Response<hyper::Body>> {
|
) -> Result<Response<hyper::Body>> {
|
||||||
if !hyper_tungstenite::is_upgrade_request(&req) {
|
let (response, ws_fut_opt) = hyper_ws_listener::create_ws(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)
|
|
||||||
.map_err(|e| anyhow::anyhow!("WebSocket upgrade failed: {}", e))?;
|
.map_err(|e| anyhow::anyhow!("WebSocket upgrade failed: {}", e))?;
|
||||||
|
|
||||||
// Spawn a task to hold the connection open and avoid EPIPE when the UI connects
|
// Spawn a task to hold the connection open if upgrade future exists
|
||||||
|
if let Some(ws_fut) = ws_fut_opt {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut ws_stream = match ws_fut.await {
|
let ws_stream: WsStream = match ws_fut.await {
|
||||||
Ok(s) => s,
|
Ok(Ok(s)) => s,
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
debug!("WebSocket handshake failed (hyper): {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("WebSocket handshake failed: {}", e);
|
debug!("WebSocket task join failed: {}", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
info!("WebSocket /ws/db connected");
|
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.
|
// Keep connection open; UI may send/receive JSON patches. For now just accept and ignore.
|
||||||
while let Some(msg) = ws_stream.next().await {
|
while let Some(msg) = rx.next().await {
|
||||||
match msg {
|
match msg {
|
||||||
Ok(Message::Close(_)) => break,
|
Ok(Message::Close(_)) => break,
|
||||||
Ok(Message::Ping(data)) => {
|
Ok(Message::Ping(data)) => {
|
||||||
let _ = ws_stream.send(Message::Pong(data)).await;
|
let _ = tx.send(Message::Pong(data)).await;
|
||||||
}
|
}
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -91,7 +94,9 @@ impl ApiHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info!("WebSocket /ws/db disconnected");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ impl Server {
|
|||||||
|
|
||||||
if let Err(e) = Http::new()
|
if let Err(e) = Http::new()
|
||||||
.serve_connection(stream, service)
|
.serve_connection(stream, service)
|
||||||
|
.with_upgrades()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
error!("Error serving connection from {}: {}", peer_addr, e);
|
error!("Error serving connection from {}: {}", peer_addr, e);
|
||||||
|
|||||||
323
docker-compose.yml
Normal file
323
docker-compose.yml
Normal 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
|
||||||
47
docker/endurain-placeholder/index.html
Normal file
47
docker/endurain-placeholder/index.html
Normal 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>
|
||||||
47
docker/morphos-placeholder/index.html
Normal file
47
docker/morphos-placeholder/index.html
Normal 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>
|
||||||
@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
|
|||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.79uml52ju7g"
|
"revision": "0.6sndaq9c8b"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export const dummyApps: Record<string, PackageDataEntry> = {
|
|||||||
'interface-addresses': {
|
'interface-addresses': {
|
||||||
main: {
|
main: {
|
||||||
'tor-address': 'bitcoin.onion',
|
'tor-address': 'bitcoin.onion',
|
||||||
'lan-address': 'http://localhost:8332'
|
'lan-address': 'http://localhost:18443'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
status: ServiceStatus.Running
|
status: ServiceStatus.Running
|
||||||
@ -180,7 +180,7 @@ export const dummyApps: Record<string, PackageDataEntry> = {
|
|||||||
'interface-addresses': {
|
'interface-addresses': {
|
||||||
main: {
|
main: {
|
||||||
'tor-address': 'endurain.onion',
|
'tor-address': 'endurain.onion',
|
||||||
'lan-address': 'http://localhost:8080'
|
'lan-address': 'http://localhost:8084'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
status: ServiceStatus.Stopped
|
status: ServiceStatus.Stopped
|
||||||
@ -288,7 +288,7 @@ export const dummyApps: Record<string, PackageDataEntry> = {
|
|||||||
'interface-addresses': {
|
'interface-addresses': {
|
||||||
main: {
|
main: {
|
||||||
'tor-address': 'lightning.onion',
|
'tor-address': 'lightning.onion',
|
||||||
'lan-address': 'http://localhost:9735'
|
'lan-address': 'http://localhost:8080'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
status: ServiceStatus.Running
|
status: ServiceStatus.Running
|
||||||
|
|||||||
@ -22,10 +22,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</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 class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 pb-6">
|
||||||
<div
|
<div
|
||||||
v-for="(pkg, id) in packages"
|
v-for="[id, pkg] in sortedPackageEntries"
|
||||||
:key="id"
|
:key="id"
|
||||||
class="glass-card p-6 transition-all hover:-translate-y-1 cursor-pointer relative"
|
class="glass-card p-6 transition-all hover:-translate-y-1 cursor-pointer relative"
|
||||||
@click="goToApp(id as string)"
|
@click="goToApp(id as string)"
|
||||||
@ -175,6 +175,14 @@ const packages = computed(() => {
|
|||||||
// return realPackages
|
// 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({
|
const uninstallModal = ref({
|
||||||
show: false,
|
show: false,
|
||||||
appId: '',
|
appId: '',
|
||||||
@ -191,8 +199,17 @@ function canLaunch(pkg: any): boolean {
|
|||||||
|
|
||||||
function launchApp(id: string) {
|
function launchApp(id: string) {
|
||||||
const isDev = import.meta.env.DEV
|
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 }> = {
|
const appUrls: Record<string, { dev: string, prod: string }> = {
|
||||||
'atob': {
|
'atob': {
|
||||||
dev: 'http://localhost:8102',
|
dev: 'http://localhost:8102',
|
||||||
|
|||||||
@ -96,6 +96,18 @@ else
|
|||||||
fi
|
fi
|
||||||
echo ""
|
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
|
# Check if node_modules exists
|
||||||
if [ ! -d "node_modules" ]; then
|
if [ ! -d "node_modules" ]; then
|
||||||
echo -e "${YELLOW}⚠️ node_modules not found. Running npm install...${NC}"
|
echo -e "${YELLOW}⚠️ node_modules not found. Running npm install...${NC}"
|
||||||
|
|||||||
@ -63,3 +63,14 @@ echo ""
|
|||||||
echo -e "${GREEN}✅ All Neode development servers stopped!${NC}"
|
echo -e "${GREEN}✅ All Neode development servers stopped!${NC}"
|
||||||
echo ""
|
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
133
start-docker-apps.sh
Executable 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
22
stop-docker-apps.sh
Executable 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
22
test-docker-setup.sh
Executable 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 ""
|
||||||
Loading…
x
Reference in New Issue
Block a user