@powerhousedao/academy 5.1.0-dev.9 → 5.1.0-staging.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,384 @@
1
+ # Docker Deployment Guide
2
+
3
+ ## Introduction
4
+
5
+ Powerhouse provides official Docker images for deploying your applications in containerized environments. This guide covers the available Docker images, how to use them with Docker Compose, and the environment variables you can configure.
6
+
7
+ Docker deployment is ideal for:
8
+ - **Production environments** that require consistent, reproducible deployments
9
+ - **Development teams** that want to share a common environment
10
+ - **CI/CD pipelines** that need automated testing and deployment
11
+ - **Cloud platforms** like AWS ECS, Google Cloud Run, or Kubernetes
12
+
13
+ ## Available Docker Images
14
+
15
+ Powerhouse publishes three official Docker images to the GitHub Container Registry (ghcr.io):
16
+
17
+ ### 1. Connect
18
+
19
+ The Connect image provides the Powerhouse web application frontend with an embedded Nginx server.
20
+
21
+ ```
22
+ ghcr.io/powerhouse-inc/powerhouse/connect
23
+ ```
24
+
25
+ **Available tags:**
26
+ - `latest` - Latest stable release
27
+ - `dev` - Development builds
28
+ - `staging` - Staging builds
29
+ - `vX.Y.Z` - Specific version tags (e.g., `v1.0.0`)
30
+
31
+ ### 2. Switchboard
32
+
33
+ The Switchboard image provides the backend API server that handles document synchronization and GraphQL endpoints.
34
+
35
+ ```
36
+ ghcr.io/powerhouse-inc/powerhouse/switchboard
37
+ ```
38
+
39
+ **Available tags:**
40
+ - `latest` - Latest stable release
41
+ - `dev` - Development builds
42
+ - `staging` - Staging builds
43
+ - `vX.Y.Z` - Specific version tags (e.g., `v1.0.0`)
44
+
45
+ ### 3. Academy
46
+
47
+ The Academy image provides the documentation website.
48
+
49
+ ```
50
+ ghcr.io/powerhouse-inc/powerhouse/academy
51
+ ```
52
+
53
+ **Available tags:**
54
+ - `latest` - Latest stable release
55
+ - `dev` - Development builds
56
+ - `staging` - Staging builds
57
+ - `vX.Y.Z` - Specific version tags (e.g., `v1.0.0`)
58
+
59
+ ## Quick Start with Docker Compose
60
+
61
+ The easiest way to run Powerhouse locally is using Docker Compose. Create a `docker-compose.yml` file or use the one provided in the repository:
62
+
63
+ ```yaml
64
+ name: powerhouse
65
+
66
+ services:
67
+ connect:
68
+ image: ghcr.io/powerhouse-inc/powerhouse/connect:dev
69
+ environment:
70
+ - DATABASE_URL=postgres://postgres:postgres@postgres:5432/postgres
71
+ - BASE_PATH=/
72
+ ports:
73
+ - "127.0.0.1:3000:4000"
74
+ networks:
75
+ - powerhouse_network
76
+ depends_on:
77
+ postgres:
78
+ condition: service_healthy
79
+
80
+ switchboard:
81
+ image: ghcr.io/powerhouse-inc/powerhouse/switchboard:dev
82
+ environment:
83
+ - DATABASE_URL=postgres://postgres:postgres@postgres:5432/postgres
84
+ ports:
85
+ - "127.0.0.1:4000:4001"
86
+ networks:
87
+ - powerhouse_network
88
+ depends_on:
89
+ postgres:
90
+ condition: service_healthy
91
+
92
+ postgres:
93
+ image: postgres:16.1
94
+ ports:
95
+ - "127.0.0.1:5444:5432"
96
+ environment:
97
+ - POSTGRES_PASSWORD=postgres
98
+ - POSTGRES_DB=postgres
99
+ - POSTGRES_USER=postgres
100
+ networks:
101
+ - powerhouse_network
102
+ healthcheck:
103
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
104
+ interval: 5s
105
+ timeout: 3s
106
+ retries: 3
107
+
108
+ networks:
109
+ powerhouse_network:
110
+ name: powerhouse_network
111
+ ```
112
+
113
+ ### Running the Stack
114
+
115
+ Start all services:
116
+
117
+ ```bash
118
+ docker compose up -d
119
+ ```
120
+
121
+ View logs:
122
+
123
+ ```bash
124
+ docker compose logs -f
125
+ ```
126
+
127
+ Stop all services:
128
+
129
+ ```bash
130
+ docker compose down
131
+ ```
132
+
133
+ After starting, you can access:
134
+ - **Connect**: http://localhost:3000
135
+ - **Switchboard**: http://localhost:4000
136
+
137
+ ## Environment Variables
138
+
139
+ ### Connect Environment Variables
140
+
141
+ | Variable | Description | Default |
142
+ |----------|-------------|---------|
143
+ | `PORT` | Port the server listens on | `4000` |
144
+ | `PH_CONNECT_BASE_PATH` | Base URL path for the application | `/` |
145
+ | `PH_PACKAGES` | Comma-separated list of packages to install at startup | `""` |
146
+ | `PH_CONNECT_SENTRY_DSN` | Sentry DSN for error tracking | `""` |
147
+ | `PH_CONNECT_SENTRY_ENV` | Sentry environment name | `""` |
148
+ | `DATABASE_URL` | PostgreSQL connection string | Required |
149
+
150
+ #### Feature Flags
151
+
152
+ | Variable | Description | Default |
153
+ |----------|-------------|---------|
154
+ | `PH_CONNECT_DEFAULT_DRIVES_URL` | Default drives URL to load | `""` |
155
+ | `PH_CONNECT_ENABLED_EDITORS` | Enabled editor types (`*` for all) | `"*"` |
156
+ | `PH_CONNECT_DISABLED_EDITORS` | Disabled editor types | `""` |
157
+ | `PH_CONNECT_PUBLIC_DRIVES_ENABLED` | Enable public drives | `"true"` |
158
+ | `PH_CONNECT_CLOUD_DRIVES_ENABLED` | Enable cloud drives | `"true"` |
159
+ | `PH_CONNECT_LOCAL_DRIVES_ENABLED` | Enable local drives | `"true"` |
160
+ | `PH_CONNECT_SEARCH_BAR_ENABLED` | Enable search bar | `"false"` |
161
+ | `PH_CONNECT_DISABLE_ADD_PUBLIC_DRIVES` | Disable adding public drives | `"false"` |
162
+ | `PH_CONNECT_DISABLE_ADD_CLOUD_DRIVES` | Disable adding cloud drives | `"false"` |
163
+ | `PH_CONNECT_DISABLE_ADD_LOCAL_DRIVES` | Disable adding local drives | `"false"` |
164
+ | `PH_CONNECT_DISABLE_DELETE_PUBLIC_DRIVES` | Disable deleting public drives | `"false"` |
165
+ | `PH_CONNECT_DISABLE_DELETE_CLOUD_DRIVES` | Disable deleting cloud drives | `"false"` |
166
+ | `PH_CONNECT_DISABLE_DELETE_LOCAL_DRIVES` | Disable deleting local drives | `"false"` |
167
+ | `PH_CONNECT_HIDE_DOCUMENT_MODEL_SELECTION_SETTINGS` | Hide document model selection | `"true"` |
168
+
169
+ #### Renown Authentication
170
+
171
+ | Variable | Description | Default |
172
+ |----------|-------------|---------|
173
+ | `PH_CONNECT_RENOWN_URL` | Renown authentication service URL | `"https://auth.renown.id"` |
174
+ | `PH_CONNECT_RENOWN_NETWORK_ID` | Renown network identifier | `"eip155"` |
175
+ | `PH_CONNECT_RENOWN_CHAIN_ID` | Renown chain ID | `1` |
176
+
177
+ ### Switchboard Environment Variables
178
+
179
+ #### Core Configuration
180
+
181
+ | Variable | Description | Default |
182
+ |----------|-------------|---------|
183
+ | `PORT` | Port the server listens on | `4001` |
184
+ | `PH_SWITCHBOARD_PORT` | Alias for PORT | `$PORT` |
185
+ | `DATABASE_URL` | PostgreSQL or SQLite connection string | `"dev.db"` |
186
+ | `PH_SWITCHBOARD_DATABASE_URL` | Alias for DATABASE_URL | `"dev.db"` |
187
+ | `BASE_PATH` | Base URL path for the API | `"/"` |
188
+ | `PH_PACKAGES` | Comma-separated list of packages to install at startup | `""` |
189
+
190
+ #### Authentication
191
+
192
+ | Variable | Description | Default |
193
+ |----------|-------------|---------|
194
+ | `AUTH_ENABLED` | Enable authentication | `"false"` |
195
+ | `ADMINS` | Comma-separated list of admin wallet addresses | `""` |
196
+ | `USERS` | Comma-separated list of user wallet addresses | `""` |
197
+ | `GUESTS` | Comma-separated list of guest wallet addresses | `""` |
198
+ | `FREE_ENTRY` | Allow unauthenticated access when auth is enabled | `"false"` |
199
+
200
+ #### Error Tracking & Monitoring
201
+
202
+ | Variable | Description | Default |
203
+ |----------|-------------|---------|
204
+ | `SENTRY_DSN` | Sentry DSN for error tracking | `""` |
205
+ | `SENTRY_ENV` | Sentry environment name (e.g., "production", "staging") | `""` |
206
+ | `PYROSCOPE_SERVER_ADDRESS` | Pyroscope server address for performance profiling | `""` |
207
+
208
+ ## Installing Custom Packages
209
+
210
+ Both Connect and Switchboard support installing custom Powerhouse packages at container startup using the `PH_PACKAGES` environment variable.
211
+
212
+ ```yaml
213
+ services:
214
+ connect:
215
+ image: ghcr.io/powerhouse-inc/powerhouse/connect:dev
216
+ environment:
217
+ - PH_PACKAGES=@powerhousedao/todo-demo-package,@powerhousedao/another-package
218
+ ```
219
+
220
+ Packages are installed using the `ph install` command before the service starts.
221
+
222
+ ## Image Architecture
223
+
224
+ ### Connect Image
225
+
226
+ The Connect image is based on Alpine Linux and includes:
227
+ - Node.js and pnpm
228
+ - Nginx with Brotli compression
229
+ - The `ph-cmd` CLI tool
230
+ - A pre-initialized Powerhouse project
231
+
232
+ At startup, the entrypoint script:
233
+ 1. Installs any packages specified in `PH_PACKAGES`
234
+ 2. Builds the Connect frontend with `ph connect build`
235
+ 3. Configures and starts Nginx to serve the built files
236
+
237
+ ### Switchboard Image
238
+
239
+ The Switchboard image is based on Node.js 22 and includes:
240
+ - pnpm package manager
241
+ - The `ph-cmd` CLI tool
242
+ - Prisma CLI for database migrations
243
+ - A pre-initialized Powerhouse project
244
+
245
+ At startup, the entrypoint script:
246
+ 1. Installs any packages specified in `PH_PACKAGES`
247
+ 2. Runs Prisma database migrations (if using PostgreSQL)
248
+ 3. Starts the Switchboard server with `ph switchboard`
249
+
250
+ ## Production Considerations
251
+
252
+ ### Using Specific Version Tags
253
+
254
+ For production deployments, always use specific version tags instead of `latest` or `dev`:
255
+
256
+ ```yaml
257
+ services:
258
+ connect:
259
+ image: ghcr.io/powerhouse-inc/powerhouse/connect:v1.0.0
260
+ switchboard:
261
+ image: ghcr.io/powerhouse-inc/powerhouse/switchboard:v1.0.0
262
+ ```
263
+
264
+ ### Database Persistence
265
+
266
+ For production, ensure your PostgreSQL data is persisted using volumes:
267
+
268
+ ```yaml
269
+ services:
270
+ postgres:
271
+ image: postgres:16.1
272
+ volumes:
273
+ - postgres_data:/var/lib/postgresql/data
274
+ environment:
275
+ - POSTGRES_PASSWORD=your-secure-password
276
+ - POSTGRES_DB=powerhouse
277
+ - POSTGRES_USER=powerhouse
278
+
279
+ volumes:
280
+ postgres_data:
281
+ ```
282
+
283
+ ### Health Checks
284
+
285
+ The provided docker-compose.yml includes health checks for PostgreSQL. Services wait for the database to be healthy before starting, preventing connection errors during startup.
286
+
287
+ ### Network Security
288
+
289
+ The example configuration binds ports to `127.0.0.1` only:
290
+
291
+ ```yaml
292
+ ports:
293
+ - "127.0.0.1:3000:4000"
294
+ ```
295
+
296
+ This prevents direct external access. In production, use a reverse proxy (like Nginx or Traefik) to:
297
+ - Terminate SSL/TLS
298
+ - Handle load balancing
299
+ - Provide additional security headers
300
+
301
+ ### Environment File
302
+
303
+ For better security, use a `.env` file instead of hardcoding credentials:
304
+
305
+ ```bash
306
+ # .env
307
+ POSTGRES_PASSWORD=your-secure-password
308
+ DATABASE_URL=postgres://powerhouse:your-secure-password@postgres:5432/powerhouse
309
+ ```
310
+
311
+ ```yaml
312
+ services:
313
+ switchboard:
314
+ image: ghcr.io/powerhouse-inc/powerhouse/switchboard:latest
315
+ env_file:
316
+ - .env
317
+ ```
318
+
319
+ ## Troubleshooting
320
+
321
+ ### Container Won't Start
322
+
323
+ Check the logs for errors:
324
+
325
+ ```bash
326
+ docker compose logs connect
327
+ docker compose logs switchboard
328
+ ```
329
+
330
+ ### Database Connection Issues
331
+
332
+ Ensure the database is ready before services start:
333
+
334
+ ```bash
335
+ docker compose logs postgres
336
+ ```
337
+
338
+ Verify the `DATABASE_URL` format:
339
+ ```
340
+ postgres://user:password@host:port/database
341
+ ```
342
+
343
+ ### Package Installation Fails
344
+
345
+ If custom packages fail to install, check:
346
+ 1. Package name is correct
347
+ 2. Network connectivity from container
348
+ 3. Container has access to npm registry
349
+
350
+ ### Permission Issues
351
+
352
+ If you encounter permission issues with volumes:
353
+
354
+ ```bash
355
+ # Fix ownership
356
+ sudo chown -R 1000:1000 ./data
357
+ ```
358
+
359
+ ## Building Custom Images
360
+
361
+ You can extend the official images for custom deployments:
362
+
363
+ ```dockerfile
364
+ FROM ghcr.io/powerhouse-inc/powerhouse/connect:latest
365
+
366
+ # Install additional packages at build time
367
+ RUN ph install @powerhousedao/my-custom-package
368
+
369
+ # Add custom configuration
370
+ COPY my-nginx.conf /etc/nginx/nginx.conf.template
371
+ ```
372
+
373
+ Build and push your custom image:
374
+
375
+ ```bash
376
+ docker build -t my-registry/my-connect:latest .
377
+ docker push my-registry/my-connect:latest
378
+ ```
379
+
380
+ ## Next Steps
381
+
382
+ - Learn about [Environment Configuration](./04-ConfigureEnvironment.md) for more detailed setup options
383
+ - Explore [Publishing Your Project](./02-PublishYourProject.md) to create your own packages
384
+ - Check the [Setup Environment Guide](./03-SetupEnvironment.md) for VM-based deployments
@@ -62,47 +62,6 @@ This schema defines the **data structure** of the document model and the types i
62
62
  <summary>State schema of our ChatRoom</summary>
63
63
 
64
64
  ```graphql
65
- # The state of our ChatRoom
66
- type ChatRoomState {
67
- id: OID! # Unique identifier for the chat-room
68
- name: String! # Name of the chat-room
69
- description: String # Optional description of the chat-room
70
- createdAt: DateTime! # Timestamp of when the chat-room was created
71
- createdBy: ID! # Agent ID of the user who created the chat-room
72
- messages: [Message!]! # List of messages in the chat-room
73
- }
74
-
75
- # A single message in the chat-room
76
- type Message {
77
- id: OID! # Unique identifier for the message
78
- sender: Sender! # Agent details of the message sender
79
- content: String # Message content
80
- sentAt: DateTime! # Timestamp of when the message was sent
81
- reactions: [Reaction!] # Reactions to the message
82
- }
83
-
84
- # The sender of a message
85
- type Sender {
86
- id: ID! # Unique identifier for the sender
87
- name: String
88
- avatarUrl: URL # Allows us to pull the ENS and/or NFT of the person's profile
89
- }
90
-
91
- # A reaction to a message
92
- type Reaction {
93
- type: ReactionType! # Type of reaction (one of the predefined emoji)
94
- reactedBy: [ID!]! # Agent IDs of users who reacted
95
- }
96
-
97
- # The predefined emoji reactions
98
- enum ReactionType {
99
- THUMBS_UP
100
- THUMBS_DOWN
101
- LAUGH
102
- HEART
103
- CRY
104
- }
105
-
106
65
  type ChatRoomState {
107
66
  id: OID!
108
67
  name: String!
@@ -138,9 +97,15 @@ enum ReactionType {
138
97
  HEART
139
98
  CRY
140
99
  }
100
+ ```
101
+
102
+ </details>
141
103
 
142
- # messages
104
+ <details>
105
+ <summary>Messages Module: Operations for ChatRoom Messages</summary>
143
106
 
107
+ ```graphql
108
+ # Add a new message to the chat-room
144
109
  input AddMessageInput {
145
110
  messageId: OID!
146
111
  sender: SenderInput!
@@ -148,77 +113,34 @@ input AddMessageInput {
148
113
  sentAt: DateTime!
149
114
  }
150
115
 
116
+ # Sender information for a message
151
117
  input SenderInput {
152
118
  id: ID!
153
119
  name: String
154
120
  avatarUrl: URL
155
121
  }
156
122
 
123
+ # Add an emoji reaction to a message
157
124
  input AddEmojiReactionInput {
158
125
  messageId: OID!
159
126
  reactedBy: ID!
160
127
  type: ReactionType!
161
128
  }
162
129
 
130
+ # Remove an emoji reaction from a message
163
131
  input RemoveEmojiReactionInput {
164
132
  messageId: OID!
165
133
  senderId: ID!
166
134
  type: ReactionType!
167
135
  }
168
-
169
- # settings
170
-
171
- input EditChatNameInput {
172
- name: String
173
- }
174
-
175
- input EditChatDescriptionInput {
176
- description: String
177
- }
178
136
  ```
179
137
 
180
138
  </details>
181
139
 
182
140
  <details>
183
- <summary>Messages Module: Operations schema of our ChatRoom Messages</summary>
141
+ <summary>Settings Module: Operations for ChatRoom Settings</summary>
184
142
 
185
143
  ```graphql
186
- # Add a new message to the chat-room
187
- input AddMessageInput {
188
- messageId: OID! # ID of the message being added
189
- sender: SenderInput! # Sender information
190
- content: String! # Content of the message
191
- sentAt: DateTime! # Timestamp when the message was sent
192
- }
193
-
194
- # Sender information for a message
195
- input SenderInput {
196
- id: ID! # Unique identifier for the sender
197
- name: String
198
- avatarUrl: URL # Avatar URL for the sender
199
- }
200
-
201
- # Add an emoji reaction to a message
202
- input AddEmojiReactionInput {
203
- messageId: OID! # ID of the message to react to
204
- reactedBy: ID! # ID of the user adding the reaction
205
- type: ReactionType! # Type of the reaction (emoji)
206
- }
207
-
208
- # Remove an emoji reaction from a message
209
- input RemoveEmojiReactionInput {
210
- messageId: OID! # ID of the message to remove reaction from
211
- senderId: ID! # ID of the user removing the reaction
212
- type: ReactionType! # Type of the reaction (emoji)
213
- }
214
-
215
-
216
- </details>
217
-
218
-
219
- <details>
220
- <summary>Settings Module: Operations schema of our ChatRoom Settings</summary>
221
-
222
144
  # Edit the chat-room name
223
145
  input EditChatNameInput {
224
146
  name: String
@@ -260,11 +182,11 @@ To define the document model, you need to open the document model editor in Conn
260
182
  }
261
183
  ```
262
184
 
263
- 5. Below the editor, find the input field `Add module`. Create and name a module for organizing your input operations. Name the module `general_operations`. Press enter.
185
+ 5. Below the editor, find the input field `Add module`. Create the first module for message-related operations. Name the module `messages`. Press enter.
264
186
 
265
187
  6. Now there is a new field, called `Add operation`. Here you will add each input operation to the module, one by one.
266
188
 
267
- 7. Inside the `Add operation` field, type `ADD_MESSAGE` and press enter. A small editor will appear underneath with an empty input type that you need to fill. Copy the `AddMessageInput` and `SenderInput` from the **Operations Schema** section and paste them in the editor:
189
+ 7. Inside the `Add operation` field, type `ADD_MESSAGE` and press enter. A small editor will appear underneath with an empty input type that you need to fill. Copy the `AddMessageInput` and `SenderInput` from the **Messages Module** section and paste them in the editor:
268
190
 
269
191
  ```graphql
270
192
  input AddMessageInput {
@@ -281,11 +203,15 @@ To define the document model, you need to open the document model editor in Conn
281
203
  }
282
204
  ```
283
205
 
284
- 8. Repeat step 7 for the other input operations: `ADD_EMOJI_REACTION`, `REMOVE_EMOJI_REACTION`, `EDIT_CHAT_NAME`, and `EDIT_CHAT_DESCRIPTION`. Note that you only need to add the operation name (e.g., `ADD_EMOJI_REACTION`) without the `Input` suffix—it will be generated automatically.
206
+ 8. Add the remaining message operations to the `messages` module: `ADD_EMOJI_REACTION` and `REMOVE_EMOJI_REACTION`. Note that you only need to add the operation name (e.g., `ADD_EMOJI_REACTION`) without the `Input` suffix—it will be generated automatically.
207
+
208
+ 9. Add reducer exceptions to the `ADD_MESSAGE` operation for validation: `MessageContentCannotBeEmpty` and `MessageNotFound`. These will be used later to validate messages.
209
+
210
+ 10. Create a second module called `settings` for the chat room configuration operations.
285
211
 
286
- 9. Add reducer exceptions to the `ADD_MESSAGE` operation for validation: `MessageContentCannotBeEmpty` and `MessageContentExceedsTheMaximumLength`. These will be used later to validate messages.
212
+ 11. Add the settings operations to the `settings` module: `EDIT_CHAT_NAME` and `EDIT_CHAT_DESCRIPTION`.
287
213
 
288
- 10. Once you have added all the input operations, click the `Export` button at the top right of the editor to save the document model specification to your local machine. Save the file in the root of your Powerhouse project.
214
+ 12. Once you have added all the input operations, click the `Export` button at the top right of the editor to save the document model specification to your local machine. Save the file in the root of your Powerhouse project.
289
215
 
290
216
  Check the screenshot below to verify the complete implementation:
291
217
 
@@ -302,13 +228,24 @@ document-models/chat-room/
302
228
  │ ├── creators.ts # Action creator functions
303
229
  │ ├── types.ts # TypeScript type definitions
304
230
  │ ├── reducer.ts
305
- └── general-operations/
306
- └── operations.ts # Operation type definitions
231
+ ├── messages/ # Messages module
232
+ │ ├── actions.ts
233
+ │ │ ├── creators.ts
234
+ │ │ ├── error.ts # Error classes for validation
235
+ │ │ └── operations.ts
236
+ │ └── settings/ # Settings module
237
+ │ ├── actions.ts
238
+ │ ├── creators.ts
239
+ │ ├── error.ts
240
+ │ └── operations.ts
307
241
  ├── src/ # Your custom implementation
308
242
  │ ├── reducers/
309
- │ │ └── general-operations.ts # Reducer functions (to implement next)
243
+ │ │ ├── messages.ts # Message operation reducers
244
+ │ │ └── settings.ts # Settings operation reducers
310
245
  │ └── tests/
311
- └── general-operations.test.ts # Test file scaffolding
246
+ ├── document-model.test.ts # Document model tests
247
+ │ ├── messages.test.ts # Messages operation tests
248
+ │ └── settings.test.ts # Settings operation tests
312
249
  ├── chat-room.json # Document model specification
313
250
  └── schema.graphql # GraphQL schema
314
251
  ```