mid code commit
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# Archipelago Apps - Development Guide
|
||||
|
||||
This directory contains all prepackaged containerized applications for Archipelago NodeOS.
|
||||
|
||||
## App Overview
|
||||
|
||||
### Bitcoin & Lightning
|
||||
- **bitcoin-core**: Full Bitcoin node (ports: 8332, 8333)
|
||||
- **lnd**: Lightning Network Daemon (ports: 9735, 10009, 8080)
|
||||
- **core-lightning**: Core Lightning implementation (ports: 9736, 9835)
|
||||
- **btcpay-server**: Bitcoin payment processor (ports: 80, 443)
|
||||
|
||||
### Nostr Relays
|
||||
- **nostr-rs-relay**: High-performance Rust relay (port: 8081)
|
||||
- **strfry**: Lightweight C++ relay (port: 8082)
|
||||
|
||||
### Web5 & Decentralized Protocols
|
||||
- **web5-dwn**: Decentralized Web Node (port: 3000)
|
||||
- **did-wallet**: Web5 DID Wallet (port: 8083)
|
||||
|
||||
### Mesh Networking
|
||||
- **router**: Mesh routing and network management (ports: 8084, 5353, 1900)
|
||||
- **meshtastic**: LoRa mesh networking (ports: 4403, 1883)
|
||||
|
||||
## Port Assignments
|
||||
|
||||
All apps use unique base ports. In development mode, ports are offset by 10000 (configurable).
|
||||
|
||||
| App | Base Ports | Dev Ports (offset +10000) |
|
||||
|-----|------------|---------------------------|
|
||||
| bitcoin-core | 8332, 8333 | 18332, 18333 |
|
||||
| lnd | 9735, 10009, 8080 | 19735, 20009, 18080 |
|
||||
| core-lightning | 9736, 9835 | 19736, 19835 |
|
||||
| btcpay-server | 80, 443 | 10080, 10443 |
|
||||
| nostr-rs-relay | 8081 | 18081 |
|
||||
| strfry | 8082 | 18082 |
|
||||
| did-wallet | 8083 | 18083 |
|
||||
| router | 8084, 5353, 1900 | 18084, 15353, 11900 |
|
||||
| web5-dwn | 3000 | 13000 |
|
||||
| meshtastic | 4403, 1883 | 14403, 11883 |
|
||||
|
||||
## Building Apps
|
||||
|
||||
### Build All Apps
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
### Build Specific App
|
||||
|
||||
```bash
|
||||
./build.sh <app-id>
|
||||
```
|
||||
|
||||
### Build for Development
|
||||
|
||||
```bash
|
||||
./build.sh <app-id> --dev
|
||||
```
|
||||
|
||||
## App Structure
|
||||
|
||||
Each app directory contains:
|
||||
|
||||
- `manifest.yml` - App manifest defining container configuration
|
||||
- `Dockerfile` - Container image definition
|
||||
- `README.md` - App-specific documentation (for custom apps)
|
||||
- Source code (for custom apps: router, did-wallet, web5-dwn)
|
||||
|
||||
## Custom Apps
|
||||
|
||||
The following apps have custom implementations:
|
||||
|
||||
1. **router** - TypeScript/Node.js mesh router
|
||||
2. **did-wallet** - TypeScript/Node.js Web5 wallet
|
||||
3. **web5-dwn** - TypeScript/Node.js DWN server
|
||||
|
||||
These apps can be developed locally:
|
||||
|
||||
```bash
|
||||
cd apps/<app-id>
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Standard Apps
|
||||
|
||||
The following apps use official Docker images:
|
||||
|
||||
- bitcoin-core (bitcoin/bitcoin:26.0)
|
||||
- lnd (lightninglabs/lnd:v0.18.0)
|
||||
- core-lightning (elementsproject/lightningd:v23.08.2)
|
||||
- btcpay-server (btcpayserver/btcpayserver:1.12.0)
|
||||
- nostr-rs-relay (scsibug/nostr-rs-relay:latest)
|
||||
- strfry (strfry/strfry:latest)
|
||||
- meshtastic (meshtastic/meshtastic:latest)
|
||||
|
||||
## Running in Development
|
||||
|
||||
### Using Archipelago Backend
|
||||
|
||||
The Archipelago backend will automatically:
|
||||
1. Build local images if they don't exist
|
||||
2. Apply port offsets in dev mode
|
||||
3. Map volumes to `/tmp/archipelago-dev/<app-id>`
|
||||
4. Start containers with proper networking
|
||||
|
||||
### Manual Testing
|
||||
|
||||
You can test apps manually:
|
||||
|
||||
```bash
|
||||
# Build the app
|
||||
./build.sh <app-id>
|
||||
|
||||
# Run with Docker/Podman
|
||||
docker run -p <host-port>:<container-port> \
|
||||
-v /tmp/archipelago-dev/<app-id>:/data \
|
||||
archipelago/<app-id>:latest
|
||||
```
|
||||
|
||||
## Integration with Archipelago
|
||||
|
||||
Apps are integrated via:
|
||||
|
||||
1. **Manifest files** - Define app configuration
|
||||
2. **Container runtime** - Podman/Docker for execution
|
||||
3. **Port manager** - Handles port allocation and offsets
|
||||
4. **Dev orchestrator** - Manages containers in development
|
||||
|
||||
## Next Steps
|
||||
|
||||
When building the OS image, these apps will be:
|
||||
1. Built into container images
|
||||
2. Included in the OS image
|
||||
3. Available for installation via the UI
|
||||
4. Pre-configured with proper networking and security
|
||||
@@ -0,0 +1,57 @@
|
||||
# Port Assignments Reference
|
||||
|
||||
This document lists all port assignments for Archipelago apps.
|
||||
|
||||
## Production Ports
|
||||
|
||||
| App | Port(s) | Protocol | Service |
|
||||
|-----|---------|----------|---------|
|
||||
| bitcoin-core | 8332, 8333 | TCP | RPC, P2P |
|
||||
| lnd | 9735, 10009, 8080 | TCP | P2P, gRPC, REST |
|
||||
| core-lightning | 9736, 9835 | TCP | P2P, gRPC |
|
||||
| btcpay-server | 80, 443 | TCP | HTTP, HTTPS |
|
||||
| nostr-rs-relay | 8081 | TCP | HTTP/WebSocket |
|
||||
| strfry | 8082 | TCP | HTTP/WebSocket |
|
||||
| did-wallet | 8083 | TCP | Web UI |
|
||||
| router | 8084, 5353, 1900 | TCP/UDP | Web UI, mDNS, SSDP |
|
||||
| web5-dwn | 3000 | TCP | HTTP API |
|
||||
| meshtastic | 4403, 1883 | TCP | HTTP API, MQTT |
|
||||
|
||||
## Development Ports (Offset: +10000)
|
||||
|
||||
In development mode, all ports are offset by 10000 to avoid conflicts with production services.
|
||||
|
||||
| App | Dev Port(s) | Access URL |
|
||||
|-----|-------------|------------|
|
||||
| bitcoin-core | 18332, 18333 | http://localhost:18332 |
|
||||
| lnd | 19735, 20009, 18080 | http://localhost:18080 |
|
||||
| core-lightning | 19736, 19835 | http://localhost:19835 |
|
||||
| btcpay-server | 10080, 10443 | http://localhost:10080 |
|
||||
| nostr-rs-relay | 18081 | http://localhost:18081 |
|
||||
| strfry | 18082 | http://localhost:18082 |
|
||||
| did-wallet | 18083 | http://localhost:18083 |
|
||||
| router | 18084, 15353, 11900 | http://localhost:18084 |
|
||||
| web5-dwn | 13000 | http://localhost:13000 |
|
||||
| meshtastic | 14403, 11883 | http://localhost:14403 |
|
||||
|
||||
## Port Conflict Resolution
|
||||
|
||||
All apps use unique base ports to prevent conflicts. The port offset system ensures:
|
||||
- No conflicts in production (each app has unique ports)
|
||||
- No conflicts in development (offset applied automatically)
|
||||
- Easy port management via PortManager
|
||||
|
||||
## Changing Port Offset
|
||||
|
||||
The port offset is configurable via environment variable:
|
||||
|
||||
```bash
|
||||
ARCHIPELAGO_PORT_OFFSET=10000
|
||||
```
|
||||
|
||||
Or in the Archipelago config:
|
||||
|
||||
```toml
|
||||
[dev]
|
||||
port_offset = 10000
|
||||
```
|
||||
@@ -0,0 +1,109 @@
|
||||
# Quick Start Guide - Archipelago Apps
|
||||
|
||||
This guide will help you get all prepackaged apps running in your development environment.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Container Runtime**: Podman or Docker
|
||||
```bash
|
||||
# Check if available
|
||||
podman --version # or docker --version
|
||||
```
|
||||
|
||||
2. **Node.js** (for custom apps): v18+
|
||||
```bash
|
||||
node --version
|
||||
```
|
||||
|
||||
3. **Archipelago Backend**: Running in dev mode
|
||||
```bash
|
||||
cd core
|
||||
ARCHIPELAGO_DEV_MODE=true cargo run --bin archipelago
|
||||
```
|
||||
|
||||
## Building Apps
|
||||
|
||||
### Build All Apps
|
||||
|
||||
```bash
|
||||
cd apps
|
||||
./build.sh
|
||||
```
|
||||
|
||||
This will build all apps that have Dockerfiles. Standard apps (bitcoin-core, lnd, etc.) will use their official images, while custom apps (router, did-wallet, web5-dwn) will be built from source.
|
||||
|
||||
### Build Specific App
|
||||
|
||||
```bash
|
||||
./build.sh router
|
||||
./build.sh did-wallet
|
||||
./build.sh web5-dwn
|
||||
```
|
||||
|
||||
## Running Apps via Archipelago
|
||||
|
||||
Once the backend is running, you can install and start apps via:
|
||||
|
||||
1. **UI**: Navigate to http://localhost:8100 and use the Apps/Marketplace interface
|
||||
2. **RPC**: Use the container-install RPC method
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5959/rpc/v1 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"method": "container-install",
|
||||
"params": {
|
||||
"manifest_path": "apps/router/manifest.yml"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Port Access
|
||||
|
||||
In development mode, apps are accessible on offset ports:
|
||||
|
||||
- **Router**: http://localhost:18084
|
||||
- **DID Wallet**: http://localhost:18083
|
||||
- **Web5 DWN**: http://localhost:13000
|
||||
- **Nostr RS Relay**: http://localhost:18081
|
||||
- **Strfry**: http://localhost:18082
|
||||
|
||||
See [PORTS.md](./PORTS.md) for complete port mapping.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### For Custom Apps (router, did-wallet, web5-dwn)
|
||||
|
||||
1. **Make changes** to source code in `apps/<app-id>/src/`
|
||||
2. **Rebuild** the container:
|
||||
```bash
|
||||
./build.sh <app-id>
|
||||
```
|
||||
3. **Restart** the container via Archipelago UI or RPC
|
||||
|
||||
### For Standard Apps
|
||||
|
||||
Standard apps use official images. To customize:
|
||||
1. Create a custom Dockerfile that extends the official image
|
||||
2. Add your customizations
|
||||
3. Update the manifest to use your custom image
|
||||
|
||||
## Testing Locally
|
||||
|
||||
You can test apps directly without Archipelago:
|
||||
|
||||
```bash
|
||||
# Build
|
||||
./build.sh router
|
||||
|
||||
# Run
|
||||
docker run -p 18084:8080 \
|
||||
-v /tmp/archipelago-dev/router:/app/data \
|
||||
archipelago/router:latest
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Read [DEVELOPMENT.md](./DEVELOPMENT.md) for detailed development information
|
||||
- Check [PORTS.md](./PORTS.md) for port assignments
|
||||
- Review individual app READMEs for app-specific details
|
||||
@@ -0,0 +1,5 @@
|
||||
# Bitcoin Core - uses official image
|
||||
FROM bitcoin/bitcoin:24.0
|
||||
|
||||
# Default user is already 'bitcoin'
|
||||
# No additional setup needed
|
||||
@@ -1,11 +1,11 @@
|
||||
app:
|
||||
id: bitcoin-core
|
||||
name: Bitcoin Core
|
||||
version: 26.0.0
|
||||
version: 24.0.0
|
||||
description: Full Bitcoin node implementation. The reference implementation of the Bitcoin protocol.
|
||||
|
||||
container:
|
||||
image: bitcoin/bitcoin:26.0
|
||||
image: bitcoin/bitcoin:24.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# BTCPay Server - uses official image
|
||||
FROM btcpayserver/btcpayserver:1.12.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# Build script for Archipelago apps
|
||||
# Usage: ./build.sh [app-id] [--dev]
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
APPS_DIR="$SCRIPT_DIR"
|
||||
|
||||
# Determine container runtime
|
||||
RUNTIME="auto"
|
||||
if command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
|
||||
RUNTIME="podman"
|
||||
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||
RUNTIME="docker"
|
||||
else
|
||||
echo "❌ No container runtime available (Podman or Docker required)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🐳 Using runtime: $RUNTIME"
|
||||
|
||||
# Build function
|
||||
build_app() {
|
||||
local app_id=$1
|
||||
local app_dir="$APPS_DIR/$app_id"
|
||||
local dev_mode=$2
|
||||
|
||||
if [ ! -d "$app_dir" ]; then
|
||||
echo "❌ App directory not found: $app_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$app_dir/Dockerfile" ]; then
|
||||
echo "⚠️ No Dockerfile found for $app_id, skipping..."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔨 Building $app_id..."
|
||||
|
||||
local image_tag="archipelago/$app_id:latest"
|
||||
if [ "$dev_mode" = "--dev" ]; then
|
||||
image_tag="archipelago/$app_id:dev"
|
||||
fi
|
||||
|
||||
cd "$app_dir"
|
||||
|
||||
# For Node.js apps, install dependencies first
|
||||
if [ -f "package.json" ]; then
|
||||
echo " Installing Node.js dependencies..."
|
||||
npm install --production=false
|
||||
fi
|
||||
|
||||
# Build the image
|
||||
echo " Building container image: $image_tag"
|
||||
$RUNTIME build -t "$image_tag" .
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $app_id built successfully: $image_tag"
|
||||
else
|
||||
echo "❌ Failed to build $app_id"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main logic
|
||||
if [ $# -eq 0 ]; then
|
||||
# Build all apps
|
||||
echo "🔨 Building all Archipelago apps..."
|
||||
for app_dir in "$APPS_DIR"/*/; do
|
||||
if [ -d "$app_dir" ] && [ -f "$app_dir/manifest.yml" ]; then
|
||||
app_id=$(basename "$app_dir")
|
||||
build_app "$app_id" "$@"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Build specific app
|
||||
app_id=$1
|
||||
shift
|
||||
build_app "$app_id" "$@"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Build complete!"
|
||||
@@ -0,0 +1,5 @@
|
||||
# Core Lightning - uses official image
|
||||
FROM elementsproject/lightningd:v23.08.2
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -25,9 +25,9 @@ app:
|
||||
apparmor_profile: core-lightning
|
||||
|
||||
ports:
|
||||
- host: 9735
|
||||
- host: 9736
|
||||
container: 9735
|
||||
protocol: tcp # P2P
|
||||
protocol: tcp # P2P (using 9736 to avoid conflict with LND)
|
||||
- host: 9835
|
||||
container: 9835
|
||||
protocol: tcp # gRPC
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
@@ -0,0 +1,39 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/wallet && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV WALLET_STORAGE=/app/wallet
|
||||
ENV DWN_ENDPOINT=http://web5-dwn:3000
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
@@ -0,0 +1,35 @@
|
||||
# DID Wallet
|
||||
|
||||
Web5 wallet with Decentralized Identifier (DID) support.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh did-wallet
|
||||
|
||||
# Or manually
|
||||
cd did-wallet
|
||||
docker build -t archipelago/did-wallet:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd did-wallet
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **8083**: Web UI (dev: 18083)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 8083:8080 \
|
||||
-v /tmp/archipelago-dev/did-wallet:/app/wallet \
|
||||
-e DWN_ENDPOINT=http://localhost:13000 \
|
||||
archipelago/did-wallet:latest
|
||||
```
|
||||
@@ -5,9 +5,9 @@ app:
|
||||
description: Web5 wallet with Decentralized Identifier (DID) support. Manage your digital identity and Web5 assets.
|
||||
|
||||
container:
|
||||
image: tbd/web5-wallet:latest
|
||||
image: archipelago/did-wallet:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: web5-dwn
|
||||
@@ -26,7 +26,7 @@ app:
|
||||
apparmor_profile: did-wallet
|
||||
|
||||
ports:
|
||||
- host: 8080
|
||||
- host: 8083
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
@@ -42,7 +42,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8083
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "did-wallet",
|
||||
"version": "1.0.0",
|
||||
"description": "Web5 DID Wallet for Archipelago",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"@web5/api": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DID Wallet</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Web5 DID Wallet</h1>
|
||||
<p>Decentralized Identity Wallet for Archipelago</p>
|
||||
<div id="app">
|
||||
<p>Wallet interface coming soon...</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,38 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'did-wallet' });
|
||||
});
|
||||
|
||||
// Wallet API endpoints
|
||||
app.get('/api/wallet/info', (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
wallet: {
|
||||
dids: [],
|
||||
balance: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/api/wallet/did/create', async (req, res) => {
|
||||
// Placeholder for DID creation
|
||||
res.json({
|
||||
status: 'ok',
|
||||
did: 'did:key:placeholder'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`DID Wallet listening on port ${port}`);
|
||||
console.log(`DWN endpoint: ${process.env.DWN_ENDPOINT || 'http://web5-dwn:3000'}`);
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
@@ -0,0 +1,37 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV ENDURAIN_DATA_DIR=/app/data
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
@@ -0,0 +1,47 @@
|
||||
app:
|
||||
id: endurain
|
||||
name: Endurain
|
||||
version: 1.0.0
|
||||
description: Endurain application platform. Custom application runtime.
|
||||
|
||||
container:
|
||||
image: archipelago/endurain:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 2Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 1Gi
|
||||
disk_limit: 2Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: endurain
|
||||
|
||||
ports:
|
||||
- host: 8085
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/endurain
|
||||
target: /app/data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- ENDURAIN_ENV=production
|
||||
- ENDURAIN_DATA_DIR=/app/data
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8085
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "endurain",
|
||||
"version": "1.0.0",
|
||||
"description": "Endurain application platform",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'endurain', version: '1.0.0' });
|
||||
});
|
||||
|
||||
// API endpoints
|
||||
app.get('/api/info', (req, res) => {
|
||||
res.json({
|
||||
name: 'Endurain',
|
||||
version: '1.0.0',
|
||||
status: 'running'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Endurain listening on port ${port}`);
|
||||
console.log(`Data directory: ${process.env.ENDURAIN_DATA_DIR || '/app/data'}`);
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Fedimint - uses official image
|
||||
FROM fedimint/fedimint:0.3.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,58 @@
|
||||
app:
|
||||
id: fedimint
|
||||
name: Fedimint
|
||||
version: 0.3.0
|
||||
description: Federated Bitcoin minting service. Privacy-preserving Bitcoin custody.
|
||||
|
||||
container:
|
||||
image: fedimint/fedimint:0.3.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 20Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 4
|
||||
memory_limit: 4Gi
|
||||
disk_limit: 20Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: fedimint
|
||||
|
||||
ports:
|
||||
- host: 8173
|
||||
container: 8173
|
||||
protocol: tcp # API
|
||||
- host: 8174
|
||||
container: 8174
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/fedimint
|
||||
target: /fedimint
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- FM_BITCOIND_RPC=http://bitcoin-core:8332
|
||||
- FM_BITCOIND_RPC_USER=${BITCOIN_RPC_USER}
|
||||
- FM_BITCOIND_RPC_PASS=${BITCOIN_RPC_PASSWORD}
|
||||
- FM_NETWORK=mainnet
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8174
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: admin
|
||||
sync_required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
# Grafana - uses official image
|
||||
FROM grafana/grafana:10.2.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,49 @@
|
||||
app:
|
||||
id: grafana
|
||||
name: Grafana
|
||||
version: 10.2.0
|
||||
description: Analytics and monitoring platform. Visualize metrics and create dashboards.
|
||||
|
||||
container:
|
||||
image: grafana/grafana:10.2.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 1Gi
|
||||
disk_limit: 5Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: grafana
|
||||
|
||||
ports:
|
||||
- host: 3001
|
||||
container: 3000
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/grafana
|
||||
target: /var/lib/grafana
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
|
||||
- GF_SERVER_ROOT_URL=http://localhost:3001
|
||||
- GF_INSTALL_PLUGINS=
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:3001
|
||||
path: /api/health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -0,0 +1,5 @@
|
||||
# Home Assistant - uses official image
|
||||
FROM homeassistant/home-assistant:2024.1
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,56 @@
|
||||
app:
|
||||
id: home-assistant
|
||||
name: Home Assistant
|
||||
version: 2024.1.0
|
||||
description: Open source home automation platform. Control and monitor your smart home devices.
|
||||
|
||||
container:
|
||||
image: homeassistant/home-assistant:2024.1
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 10Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 10Gi
|
||||
|
||||
security:
|
||||
capabilities: [NET_BIND_SERVICE]
|
||||
readonly_root: false # Home Assistant needs write access
|
||||
network_policy: host # Requires host network for device discovery
|
||||
apparmor_profile: home-assistant
|
||||
|
||||
ports:
|
||||
- host: 8123
|
||||
container: 8123
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/home-assistant
|
||||
target: /config
|
||||
options: [rw]
|
||||
- type: bind
|
||||
source: /var/run/dbus
|
||||
target: /var/run/dbus
|
||||
options: [ro]
|
||||
|
||||
devices:
|
||||
- /dev/ttyUSB0 # Serial devices
|
||||
- /dev/ttyACM0 # USB devices
|
||||
|
||||
environment:
|
||||
- TZ=UTC
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8123
|
||||
path: /api/
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -0,0 +1,5 @@
|
||||
# Lightning Stack - uses official image
|
||||
FROM lightninglabs/lightning-stack:v0.12.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,65 @@
|
||||
app:
|
||||
id: lightning-stack
|
||||
name: Lightning Stack
|
||||
version: 0.12.0
|
||||
description: Complete Lightning Network implementation. Includes LND, CLN, and management tools.
|
||||
|
||||
container:
|
||||
image: lightninglabs/lightning-stack:v0.12.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 50Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 4
|
||||
memory_limit: 4Gi
|
||||
disk_limit: 50Gi
|
||||
|
||||
security:
|
||||
capabilities: [NET_BIND_SERVICE]
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: lightning-stack
|
||||
|
||||
ports:
|
||||
- host: 9737
|
||||
container: 9735
|
||||
protocol: tcp # P2P
|
||||
- host: 10010
|
||||
container: 10009
|
||||
protocol: tcp # gRPC
|
||||
- host: 8087
|
||||
container: 8080
|
||||
protocol: tcp # REST/Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/lightning-stack
|
||||
target: /root/.lightning
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- BITCOIND_HOST=bitcoin-core
|
||||
- BITCOIND_RPCUSER=${BITCOIN_RPC_USER}
|
||||
- BITCOIND_RPCPASS=${BITCOIN_RPC_PASSWORD}
|
||||
- NETWORK=mainnet
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8087
|
||||
path: /v1/getinfo
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: admin
|
||||
sync_required: true
|
||||
|
||||
lightning_integration:
|
||||
channel_management: true
|
||||
payment_routing: true
|
||||
@@ -0,0 +1,5 @@
|
||||
# LND - uses official image
|
||||
FROM lightninglabs/lnd:v0.18.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,5 @@
|
||||
# Mempool - uses official image
|
||||
FROM mempool/mempool:v2.5.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -0,0 +1,56 @@
|
||||
app:
|
||||
id: mempool
|
||||
name: Mempool
|
||||
version: 2.5.0
|
||||
description: Bitcoin mempool and blockchain explorer. Real-time transaction and block visualization.
|
||||
|
||||
container:
|
||||
image: mempool/mempool:v2.5.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 20Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 20Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: mempool
|
||||
|
||||
ports:
|
||||
- host: 4080
|
||||
container: 4080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/mempool
|
||||
target: /data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- MEMPOOL_BACKEND=electrum
|
||||
- MEMPOOL_BITCOIN_HOST=bitcoin-core
|
||||
- MEMPOOL_BITCOIN_PORT=8332
|
||||
- MEMPOOL_BITCOIN_USER=${BITCOIN_RPC_USER}
|
||||
- MEMPOOL_BITCOIN_PASSWORD=${BITCOIN_RPC_PASSWORD}
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:4080
|
||||
path: /api/health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: read-only
|
||||
sync_required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
# Meshtastic - uses official image
|
||||
FROM meshtastic/meshtastic:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -24,8 +24,12 @@ app:
|
||||
apparmor_profile: meshtastic
|
||||
|
||||
ports:
|
||||
- 4403:4403 # HTTP API
|
||||
- 1883:1883 # MQTT (optional)
|
||||
- host: 4403
|
||||
container: 4403
|
||||
protocol: tcp # HTTP API
|
||||
- host: 1883
|
||||
container: 1883
|
||||
protocol: tcp # MQTT (optional)
|
||||
|
||||
devices:
|
||||
- /dev/ttyUSB0 # LoRa radio device (if connected)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
@@ -0,0 +1,37 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV MORPHOS_DATA_DIR=/app/data
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
@@ -0,0 +1,47 @@
|
||||
app:
|
||||
id: morphos-server
|
||||
name: MorphOS Server
|
||||
version: 1.0.0
|
||||
description: MorphOS server platform. Decentralized application server.
|
||||
|
||||
container:
|
||||
image: archipelago/morphos-server:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 5Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: morphos-server
|
||||
|
||||
ports:
|
||||
- host: 8086
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/morphos-server
|
||||
target: /app/data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- MORPHOS_ENV=production
|
||||
- MORPHOS_DATA_DIR=/app/data
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8086
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "morphos-server",
|
||||
"version": "1.0.0",
|
||||
"description": "MorphOS server platform",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'morphos-server', version: '1.0.0' });
|
||||
});
|
||||
|
||||
// API endpoints
|
||||
app.get('/api/info', (req, res) => {
|
||||
res.json({
|
||||
name: 'MorphOS Server',
|
||||
version: '1.0.0',
|
||||
status: 'running'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`MorphOS Server listening on port ${port}`);
|
||||
console.log(`Data directory: ${process.env.MORPHOS_DATA_DIR || '/app/data'}`);
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Nostr RS Relay - uses official image
|
||||
FROM scsibug/nostr-rs-relay:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -24,7 +24,9 @@ app:
|
||||
apparmor_profile: nostr-relay
|
||||
|
||||
ports:
|
||||
- 8080:8080 # HTTP/WebSocket
|
||||
- host: 8081
|
||||
container: 8080
|
||||
protocol: tcp # HTTP/WebSocket
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@@ -40,7 +42,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8081
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
@@ -0,0 +1,40 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache \
|
||||
dbus \
|
||||
avahi \
|
||||
avahi-tools
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080 5353 1900
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
@@ -0,0 +1,38 @@
|
||||
# Archipelago Router
|
||||
|
||||
Mesh routing and local network management for Archipelago.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh router
|
||||
|
||||
# Or manually
|
||||
cd router
|
||||
docker build -t archipelago/router:latest .
|
||||
# or
|
||||
podman build -t archipelago/router:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd router
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **8084**: Web UI (dev: 18084)
|
||||
- **5353**: mDNS/Bonjour (dev: 15353)
|
||||
- **1900**: SSDP (dev: 11900)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 8084:8080 -p 5353:5353/udp -p 1900:1900/udp \
|
||||
-v /tmp/archipelago-dev/router:/app/data \
|
||||
archipelago/router:latest
|
||||
```
|
||||
@@ -7,7 +7,7 @@ app:
|
||||
container:
|
||||
image: archipelago/router:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 500Mi
|
||||
@@ -24,9 +24,15 @@ app:
|
||||
apparmor_profile: router
|
||||
|
||||
ports:
|
||||
- 8080:8080 # Web UI
|
||||
- 5353:5353 # mDNS/Bonjour
|
||||
- 1900:1900 # SSDP
|
||||
- host: 8084
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
- host: 5353
|
||||
container: 5353
|
||||
protocol: udp # mDNS/Bonjour
|
||||
- host: 1900
|
||||
container: 1900
|
||||
protocol: udp # SSDP
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@@ -45,7 +51,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8084
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "archipelago-router",
|
||||
"version": "1.0.0",
|
||||
"description": "Mesh routing and local network management for Archipelago",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"bonjour": "^3.5.0",
|
||||
"network-interfaces": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import express from 'express';
|
||||
import bonjour from 'bonjour';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Initialize Bonjour for mDNS
|
||||
const bonjourInstance = bonjour();
|
||||
|
||||
// Publish Archipelago Router service
|
||||
bonjourInstance.publish({
|
||||
name: 'Archipelago Router',
|
||||
type: 'http',
|
||||
port: port,
|
||||
txt: {
|
||||
version: '1.0.0',
|
||||
mesh: 'enabled',
|
||||
discovery: 'enabled'
|
||||
}
|
||||
});
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'archipelago-router' });
|
||||
});
|
||||
|
||||
// Network topology endpoint
|
||||
app.get('/api/topology', (req, res) => {
|
||||
res.json({
|
||||
nodes: [],
|
||||
links: [],
|
||||
timestamp: Date.now()
|
||||
});
|
||||
});
|
||||
|
||||
// Device discovery endpoint
|
||||
app.get('/api/devices', (req, res) => {
|
||||
res.json({
|
||||
devices: [],
|
||||
count: 0
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Archipelago Router listening on port ${port}`);
|
||||
console.log('mDNS service published');
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('Shutting down...');
|
||||
bonjourInstance.unpublishAll(() => {
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Strfry - uses official image
|
||||
FROM strfry/strfry:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@@ -24,7 +24,9 @@ app:
|
||||
apparmor_profile: nostr-relay
|
||||
|
||||
ports:
|
||||
- 8080:8080 # HTTP/WebSocket
|
||||
- host: 8082
|
||||
container: 8080
|
||||
protocol: tcp # HTTP/WebSocket
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@@ -37,7 +39,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8082
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
@@ -0,0 +1,38 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV DWN_STORAGE_PATH=/app/data
|
||||
ENV DID_METHOD=key
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
@@ -0,0 +1,35 @@
|
||||
# Web5 DWN (Decentralized Web Node)
|
||||
|
||||
Personal data store for Web5. Store and sync your decentralized data across devices.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh web5-dwn
|
||||
|
||||
# Or manually
|
||||
cd web5-dwn
|
||||
docker build -t archipelago/web5-dwn:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd web5-dwn
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **3000**: HTTP API (dev: 13000)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 \
|
||||
-v /tmp/archipelago-dev/web5-dwn:/app/data \
|
||||
-e DWN_STORAGE_PATH=/app/data \
|
||||
archipelago/web5-dwn:latest
|
||||
```
|
||||
@@ -5,9 +5,9 @@ app:
|
||||
description: Personal data store for Web5. Store and sync your decentralized data across devices.
|
||||
|
||||
container:
|
||||
image: tbd/web5-dwn:latest
|
||||
image: archipelago/web5-dwn:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "web5-dwn",
|
||||
"version": "1.0.0",
|
||||
"description": "Decentralized Web Node for Web5",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"@web5/api": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'web5-dwn' });
|
||||
});
|
||||
|
||||
// DWN API endpoints
|
||||
app.post('/dwn', async (req, res) => {
|
||||
// Placeholder for DWN protocol implementation
|
||||
res.json({
|
||||
status: 'ok',
|
||||
message: 'DWN protocol endpoint (placeholder)'
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/dwn', async (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
message: 'DWN query endpoint (placeholder)'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Web5 DWN listening on port ${port}`);
|
||||
console.log(`Storage path: ${process.env.DWN_STORAGE_PATH || '/app/data'}`);
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user