Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
# Ignore temp directory and temp files at repository root
/temp*
!/temp/.gitkeep
# node
node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log
package-lock.json

# env
.env
.env.local
.env.*.local
.env.backup
.env.example

# python
__pycache__/
*.py[cod]
.venv/
venv/

# OS / IDE
.DS_Store
.vscode/
.idea/

# logs
*.log
logs/
Comment thread
coderabbitai[bot] marked this conversation as resolved.
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,30 @@ Create the runtime and register your nodes:

Get Exosphere running locally in under 2 minutes:

### 1. Set up environment variables

```bash
# Copy the example environment file
cp .env.example .env

# Generate secure secrets (REQUIRED!)
# For STATE_MANAGER_SECRET and EXOSPHERE_API_KEY:
openssl rand -base64 32

# For SECRETS_ENCRYPTION_KEY (must be a valid Fernet key):
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

# Edit .env and add your generated secrets
nano .env
```

> **🔒 Security Note**: Never commit `.env` file or use default secrets in production! See [SECURITY_SETUP.md](SECURITY_SETUP.md) for detailed security configuration.

### 2. Start the services

```bash
# Option 1: With cloud MongoDB (recommended)
echo "MONGO_URI=your-mongodb-connection-string" > .env
# Ensure MONGO_URI is set in your .env file
curl -O https://raw.githubusercontent.com/exospherehost/exospherehost/main/docker-compose/docker-compose.yml
docker compose up -d

Expand All @@ -248,14 +269,15 @@ docker compose -f docker-compose-with-mongodb.yml up -d

**Environment Configuration:**
- Docker Compose automatically loads `.env` files from the working directory
- Create your `.env` file in the same directory as your docker-compose file
- All secrets must be configured before starting services
- Use `.env.example` as a template - never commit `.env` to version control

Access your services:

- **Dashboard**: `http://localhost:3000`
- **API**: `http://localhost:8000`

> **📝 Note**: This configuration is for **development and testing only**. For production deployments, environment variable customization, and advanced configuration options, please read the complete **[Docker Compose Setup Guide](https://docs.exosphere.host/docker-compose-setup)**.
> **📝 Note**: This configuration requires proper environment setup. For production deployments, environment variable customization, and advanced configuration options, please read the complete **[Docker Compose Setup Guide](https://docs.exosphere.host/docker-compose-setup)** and **[Security Setup Guide](SECURITY_SETUP.md)**.

## 📚 Documentation & Resources

Expand Down
54 changes: 54 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
services:
exosphere-state-manager:
build:
context: ./state-manager
dockerfile: Dockerfile
image: exosphere-state-manager:local
container_name: exosphere-state-manager
restart: unless-stopped
environment:
- MONGO_URI=${MONGO_URI:?MONGO_URI must be set}
- STATE_MANAGER_SECRET=${STATE_MANAGER_SECRET:?STATE_MANAGER_SECRET must be set}
- MONGO_DATABASE_NAME=${MONGO_DATABASE_NAME:-exosphere}
- SECRETS_ENCRYPTION_KEY=${SECRETS_ENCRYPTION_KEY:?SECRETS_ENCRYPTION_KEY must be set}
- TTL_DAYS=${TTL_DAYS:-30}
ports:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- "8000:8000"
networks:
- exosphere-network
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s

exosphere-dashboard:
image: ghcr.io/exospherehost/exosphere-dashboard:${EXOSPHERE_TAG:-latest}
pull_policy: always
container_name: exosphere-dashboard
restart: unless-stopped
environment:
# Server-side secure configuration (NOT exposed to browser)
- EXOSPHERE_STATE_MANAGER_URI=${EXOSPHERE_STATE_MANAGER_URI:-http://exosphere-state-manager:8000}
- EXOSPHERE_API_KEY=${EXOSPHERE_API_KEY:?EXOSPHERE_API_KEY must be set}
# Client-side configuration (exposed to browser)
- NEXT_PUBLIC_DEFAULT_NAMESPACE=${NEXT_PUBLIC_DEFAULT_NAMESPACE:-default}
depends_on:
exosphere-state-manager:
condition: service_healthy
ports:
- "3000:3000"
networks:
- exosphere-network
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s

Comment thread
coderabbitai[bot] marked this conversation as resolved.
networks:
exosphere-network:
driver: bridge
attachable: true
162 changes: 162 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"mongodb": "^7.0.0"
}
}
4 changes: 3 additions & 1 deletion state-manager/app/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Settings(BaseModel):
secrets_encryption_key: str = Field(..., description="Key for encrypting secrets")
trigger_workers: int = Field(default=1, description="Number of workers to run the trigger cron")
trigger_retention_hours: int = Field(default=720, description="Number of hours to retain completed/failed triggers before cleanup")
ttl_days: int = Field(default=30, description="TTL in days for TTL indexes")

@classmethod
def from_env(cls) -> "Settings":
Expand All @@ -23,7 +24,8 @@ def from_env(cls) -> "Settings":
state_manager_secret=os.getenv("STATE_MANAGER_SECRET"), # type: ignore
secrets_encryption_key=os.getenv("SECRETS_ENCRYPTION_KEY"), # type: ignore
trigger_workers=int(os.getenv("TRIGGER_WORKERS", 1)), # type: ignore
trigger_retention_hours=int(os.getenv("TRIGGER_RETENTION_HOURS", 720)) # type: ignore
trigger_retention_hours=int(os.getenv("TRIGGER_RETENTION_HOURS", 720)), # type: ignore
ttl_days=int(os.getenv("TTL_DAYS", 30)) # type: ignore
)


Expand Down
Loading