axiom-coding-agent-setup 1.0.0 → 1.0.2
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.
- package/.agents/skills/ai-integration/SKILL.md +314 -0
- package/.agents/skills/deployment-patterns/SKILL.md +408 -0
- package/.agents/skills/fastapi-templates/SKILL.md +540 -0
- package/.agents/skills/git-commit/SKILL.md +124 -0
- package/.agents/skills/mcp-builder/SKILL.md +292 -0
- package/.agents/skills/n8n-patterns/SKILL.md +272 -0
- package/.agents/templates/ai-engineering-python.md +508 -0
- package/.agents/templates/fullstack-ai-nextjs.md +632 -0
- package/AGENTS.md +5 -3
- package/README.md +20 -6
- package/bin/cli.js +21 -9
- package/package.json +2 -2
- package/skills-lock.json +15 -0
- /package/{.axiom → .agents}/engineering.md +0 -0
- /package/{.axiom → .agents}/stack.md +0 -0
- /package/{.axiom → .agents}/workflow.md +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-integration
|
|
3
|
+
description: Patterns and best practices for integrating AI/LLM capabilities into applications. Use when implementing chat, RAG, agents, or other AI features.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AI Integration Patterns Guide
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This skill covers patterns for integrating Large Language Models (LLMs) into applications effectively and safely.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## When to Use This Skill
|
|
15
|
+
|
|
16
|
+
- Building chat interfaces
|
|
17
|
+
- Implementing RAG (Retrieval-Augmented Generation)
|
|
18
|
+
- Creating AI agents
|
|
19
|
+
- Adding AI-powered features to existing apps
|
|
20
|
+
- Choosing between different AI approaches
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Core Patterns
|
|
25
|
+
|
|
26
|
+
### 1. Chat Interface
|
|
27
|
+
|
|
28
|
+
**Basic Streaming Chat**
|
|
29
|
+
```typescript
|
|
30
|
+
// Server-side (API route)
|
|
31
|
+
import { streamText } from 'ai';
|
|
32
|
+
import { openai } from '@/lib/ai/providers';
|
|
33
|
+
|
|
34
|
+
export async function POST(req: Request) {
|
|
35
|
+
const { messages } = await req.json();
|
|
36
|
+
|
|
37
|
+
const result = streamText({
|
|
38
|
+
model: openai('gpt-4'),
|
|
39
|
+
messages,
|
|
40
|
+
system: "You are a helpful assistant.",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return result.toDataStreamResponse();
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// Client-side (React)
|
|
49
|
+
import { useChat } from 'ai/react';
|
|
50
|
+
|
|
51
|
+
function ChatComponent() {
|
|
52
|
+
const { messages, input, handleInputChange, handleSubmit } = useChat();
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<form onSubmit={handleSubmit}>
|
|
56
|
+
{messages.map(m => (
|
|
57
|
+
<div key={m.id}>{m.content}</div>
|
|
58
|
+
))}
|
|
59
|
+
<input
|
|
60
|
+
value={input}
|
|
61
|
+
onChange={handleInputChange}
|
|
62
|
+
placeholder="Type a message..."
|
|
63
|
+
/>
|
|
64
|
+
</form>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. RAG (Retrieval-Augmented Generation)
|
|
70
|
+
|
|
71
|
+
**Basic RAG Flow**
|
|
72
|
+
```
|
|
73
|
+
User Query → Embed Query → Vector Search → Retrieve Context →
|
|
74
|
+
Augment Prompt → Generate Response → Return with Sources
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Implementation Pattern**
|
|
78
|
+
```typescript
|
|
79
|
+
async function generateWithRAG(query: string) {
|
|
80
|
+
// 1. Generate embedding for query
|
|
81
|
+
const embedding = await generateEmbedding(query);
|
|
82
|
+
|
|
83
|
+
// 2. Search vector database
|
|
84
|
+
const relevantDocs = await vectorDB.query({
|
|
85
|
+
embedding,
|
|
86
|
+
topK: 5,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// 3. Build augmented prompt
|
|
90
|
+
const context = relevantDocs.map(d => d.content).join('\n\n');
|
|
91
|
+
const prompt = `Context:\n${context}\n\nQuestion: ${query}`;
|
|
92
|
+
|
|
93
|
+
// 4. Generate response
|
|
94
|
+
const response = await llm.generate(prompt);
|
|
95
|
+
|
|
96
|
+
// 5. Return with source citations
|
|
97
|
+
return {
|
|
98
|
+
answer: response,
|
|
99
|
+
sources: relevantDocs.map(d => ({
|
|
100
|
+
title: d.title,
|
|
101
|
+
url: d.url,
|
|
102
|
+
})),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 3. Tool Use / Function Calling
|
|
108
|
+
|
|
109
|
+
**Defining Tools**
|
|
110
|
+
```typescript
|
|
111
|
+
import { tool } from 'ai';
|
|
112
|
+
import { z } from 'zod';
|
|
113
|
+
|
|
114
|
+
const searchDocuments = tool({
|
|
115
|
+
description: "Search the knowledge base for relevant information",
|
|
116
|
+
parameters: z.object({
|
|
117
|
+
query: z.string().describe("The search query"),
|
|
118
|
+
}),
|
|
119
|
+
execute: async ({ query }) => {
|
|
120
|
+
// Implementation
|
|
121
|
+
return await searchKnowledgeBase(query);
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const calculateMortgage = tool({
|
|
126
|
+
description: "Calculate monthly mortgage payment",
|
|
127
|
+
parameters: z.object({
|
|
128
|
+
principal: z.number().describe("Loan amount"),
|
|
129
|
+
rate: z.number().describe("Annual interest rate (decimal)"),
|
|
130
|
+
years: z.number().describe("Loan term in years"),
|
|
131
|
+
}),
|
|
132
|
+
execute: async ({ principal, rate, years }) => {
|
|
133
|
+
const monthlyRate = rate / 12;
|
|
134
|
+
const numPayments = years * 12;
|
|
135
|
+
const payment =
|
|
136
|
+
(principal * monthlyRate * Math.pow(1 + monthlyRate, numPayments)) /
|
|
137
|
+
(Math.pow(1 + monthlyRate, numPayments) - 1);
|
|
138
|
+
return { monthlyPayment: payment.toFixed(2) };
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Using Tools**
|
|
144
|
+
```typescript
|
|
145
|
+
const result = await generateText({
|
|
146
|
+
model: openai('gpt-4'),
|
|
147
|
+
tools: { searchDocuments, calculateMortgage },
|
|
148
|
+
prompt: userMessage,
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 4. Multi-Step Agents
|
|
153
|
+
|
|
154
|
+
**Simple Agent Loop**
|
|
155
|
+
```typescript
|
|
156
|
+
async function runAgent(userInput: string, maxSteps = 5) {
|
|
157
|
+
const messages: Message[] = [
|
|
158
|
+
{ role: 'system', content: 'You are a helpful agent...' },
|
|
159
|
+
{ role: 'user', content: userInput },
|
|
160
|
+
];
|
|
161
|
+
|
|
162
|
+
for (let i = 0; i < maxSteps; i++) {
|
|
163
|
+
const response = await llm.generate({
|
|
164
|
+
messages,
|
|
165
|
+
tools: availableTools,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
if (response.finishReason === 'stop') {
|
|
169
|
+
return response.content;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (response.toolCalls) {
|
|
173
|
+
// Execute tool calls
|
|
174
|
+
for (const call of response.toolCalls) {
|
|
175
|
+
const result = await executeTool(call);
|
|
176
|
+
messages.push({
|
|
177
|
+
role: 'tool',
|
|
178
|
+
tool_call_id: call.id,
|
|
179
|
+
content: JSON.stringify(result),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return "Maximum steps reached";
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Best Practices
|
|
192
|
+
|
|
193
|
+
### 1. Prompt Engineering
|
|
194
|
+
|
|
195
|
+
**System Prompts**
|
|
196
|
+
- Be specific about the assistant's role
|
|
197
|
+
- Include constraints and boundaries
|
|
198
|
+
- Provide output format examples
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
You are a customer support agent for TechCorp.
|
|
202
|
+
- Be friendly but professional
|
|
203
|
+
- If you don't know something, say so
|
|
204
|
+
- Always verify account details before making changes
|
|
205
|
+
- Format responses in markdown
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Few-Shot Prompting**
|
|
209
|
+
Include examples for complex tasks:
|
|
210
|
+
```
|
|
211
|
+
Classify the sentiment of the following text.
|
|
212
|
+
|
|
213
|
+
Examples:
|
|
214
|
+
Text: "I love this product!"
|
|
215
|
+
Sentiment: Positive
|
|
216
|
+
|
|
217
|
+
Text: "Terrible experience, never again"
|
|
218
|
+
Sentiment: Negative
|
|
219
|
+
|
|
220
|
+
Text: {{user_input}}
|
|
221
|
+
Sentiment:
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 2. Context Management
|
|
225
|
+
|
|
226
|
+
**Token Budgets**
|
|
227
|
+
- Track token usage
|
|
228
|
+
- Implement context window management
|
|
229
|
+
- Summarize long conversations when needed
|
|
230
|
+
|
|
231
|
+
**Relevant Context Selection**
|
|
232
|
+
- Don't dump entire documents into context
|
|
233
|
+
- Use semantic search to find relevant chunks
|
|
234
|
+
- Prioritize recent and relevant information
|
|
235
|
+
|
|
236
|
+
### 3. Error Handling
|
|
237
|
+
|
|
238
|
+
**Common Errors**
|
|
239
|
+
- Rate limits: Implement exponential backoff
|
|
240
|
+
- Timeout: Break requests into smaller chunks
|
|
241
|
+
- Content policy: Handle refusals gracefully
|
|
242
|
+
- JSON parsing: Use structured output when possible
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
try {
|
|
246
|
+
const response = await llm.generate(prompt);
|
|
247
|
+
return response;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error.code === 'rate_limit_exceeded') {
|
|
250
|
+
await sleep(1000);
|
|
251
|
+
return retry(prompt);
|
|
252
|
+
}
|
|
253
|
+
if (error.code === 'content_policy_violation') {
|
|
254
|
+
return { error: 'I cannot respond to that request' };
|
|
255
|
+
}
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### 4. Safety & Guardrails
|
|
261
|
+
|
|
262
|
+
**Input Validation**
|
|
263
|
+
- Sanitize user inputs
|
|
264
|
+
- Limit input length
|
|
265
|
+
- Validate against injection attacks
|
|
266
|
+
|
|
267
|
+
**Output Filtering**
|
|
268
|
+
- Check for PII in outputs
|
|
269
|
+
- Filter inappropriate content
|
|
270
|
+
- Add human review for sensitive actions
|
|
271
|
+
|
|
272
|
+
**Cost Controls**
|
|
273
|
+
- Set token limits per request
|
|
274
|
+
- Cache common responses
|
|
275
|
+
- Monitor usage and set budgets
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Provider Selection Guide
|
|
280
|
+
|
|
281
|
+
| Use Case | Recommended Provider | Model |
|
|
282
|
+
|----------|---------------------|-------|
|
|
283
|
+
| General chat | OpenAI / Anthropic | GPT-4 / Claude Sonnet |
|
|
284
|
+
| Reasoning tasks | OpenAI / Anthropic | o3 / Claude Opus |
|
|
285
|
+
| Long context | Google | Gemini 2.5 Pro |
|
|
286
|
+
| Cost-sensitive | OpenAI | GPT-4o-mini |
|
|
287
|
+
| Code generation | Anthropic | Claude Sonnet |
|
|
288
|
+
| Multimodal | OpenAI / Google | GPT-4o / Gemini |
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Evaluation
|
|
293
|
+
|
|
294
|
+
**Test Your AI Integration**
|
|
295
|
+
|
|
296
|
+
1. **Create test cases** with expected outputs
|
|
297
|
+
2. **Test edge cases** (empty input, very long input, special characters)
|
|
298
|
+
3. **Measure latency** and cost per request
|
|
299
|
+
4. **Monitor error rates** and failure modes
|
|
300
|
+
|
|
301
|
+
**Example Evaluation Questions**
|
|
302
|
+
- Can the system handle ambiguous queries?
|
|
303
|
+
- Does it refuse inappropriate requests?
|
|
304
|
+
- Are sources correctly cited in RAG?
|
|
305
|
+
- Does it maintain context across multiple turns?
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Resources
|
|
310
|
+
|
|
311
|
+
- **Vercel AI SDK**: https://sdk.vercel.ai/docs
|
|
312
|
+
- **OpenAI API**: https://platform.openai.com/docs
|
|
313
|
+
- **Anthropic API**: https://docs.anthropic.com/
|
|
314
|
+
- **LangChain**: https://python.langchain.com/ / https://js.langchain.com/
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deployment-patterns
|
|
3
|
+
description: Deployment patterns and best practices for various platforms. Use when setting up deployment pipelines, choosing infrastructure, or configuring CI/CD.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deployment Patterns Guide
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This skill covers deployment patterns for different types of applications across various platforms.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## When to Use This Skill
|
|
15
|
+
|
|
16
|
+
- Setting up deployment for a new project
|
|
17
|
+
- Choosing between deployment platforms
|
|
18
|
+
- Configuring CI/CD pipelines
|
|
19
|
+
- Migrating between hosting providers
|
|
20
|
+
- Setting up staging/production environments
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Platform Selection Guide
|
|
25
|
+
|
|
26
|
+
### Vercel
|
|
27
|
+
**Best for:** Next.js, React, static sites
|
|
28
|
+
|
|
29
|
+
**Pros:**
|
|
30
|
+
- Zero-config for Next.js
|
|
31
|
+
- Automatic preview deployments
|
|
32
|
+
- Edge functions
|
|
33
|
+
- Built-in analytics
|
|
34
|
+
|
|
35
|
+
**When to use:**
|
|
36
|
+
- Frontend applications
|
|
37
|
+
- Full-stack Next.js apps
|
|
38
|
+
- JAMstack sites
|
|
39
|
+
|
|
40
|
+
**Configuration:**
|
|
41
|
+
```json
|
|
42
|
+
// vercel.json
|
|
43
|
+
{
|
|
44
|
+
"buildCommand": "npm run build",
|
|
45
|
+
"outputDirectory": ".next",
|
|
46
|
+
"framework": "nextjs",
|
|
47
|
+
"rewrites": [
|
|
48
|
+
{ "source": "/api/(.*)", "destination": "/api/$1" }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Railway / Render / Fly.io
|
|
54
|
+
**Best for:** Full-stack apps, APIs, databases
|
|
55
|
+
|
|
56
|
+
**Pros:**
|
|
57
|
+
- Easy environment variable management
|
|
58
|
+
- Automatic HTTPS
|
|
59
|
+
- Native Docker support
|
|
60
|
+
- Good for Node.js/Python/Go
|
|
61
|
+
|
|
62
|
+
**When to use:**
|
|
63
|
+
- Backend APIs
|
|
64
|
+
- Full-stack apps with persistent storage
|
|
65
|
+
- Applications needing databases
|
|
66
|
+
|
|
67
|
+
### AWS (ECS, Lambda, EC2)
|
|
68
|
+
**Best for:** Enterprise, complex infrastructure
|
|
69
|
+
|
|
70
|
+
**Pros:**
|
|
71
|
+
- Full control
|
|
72
|
+
- Scalable
|
|
73
|
+
- Extensive service ecosystem
|
|
74
|
+
|
|
75
|
+
**When to use:**
|
|
76
|
+
- Production enterprise apps
|
|
77
|
+
- Complex microservices
|
|
78
|
+
- When you need specific AWS services
|
|
79
|
+
|
|
80
|
+
**Lambda Example:**
|
|
81
|
+
```yaml
|
|
82
|
+
# serverless.yml
|
|
83
|
+
service: my-api
|
|
84
|
+
|
|
85
|
+
provider:
|
|
86
|
+
name: aws
|
|
87
|
+
runtime: nodejs20.x
|
|
88
|
+
region: us-east-1
|
|
89
|
+
|
|
90
|
+
functions:
|
|
91
|
+
api:
|
|
92
|
+
handler: dist/index.handler
|
|
93
|
+
events:
|
|
94
|
+
- httpApi: '*'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Docker + VPS (DigitalOcean, Hetzner, etc.)
|
|
98
|
+
**Best for:** Cost-conscious, full control
|
|
99
|
+
|
|
100
|
+
**Pros:**
|
|
101
|
+
- Cheapest for steady traffic
|
|
102
|
+
- Full control over server
|
|
103
|
+
- No vendor lock-in
|
|
104
|
+
|
|
105
|
+
**When to use:**
|
|
106
|
+
- Side projects
|
|
107
|
+
- Predictable traffic
|
|
108
|
+
- Learning/DevOps practice
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## CI/CD Patterns
|
|
113
|
+
|
|
114
|
+
### GitHub Actions
|
|
115
|
+
|
|
116
|
+
**Basic Setup**
|
|
117
|
+
```yaml
|
|
118
|
+
# .github/workflows/deploy.yml
|
|
119
|
+
name: Deploy
|
|
120
|
+
|
|
121
|
+
on:
|
|
122
|
+
push:
|
|
123
|
+
branches: [main]
|
|
124
|
+
pull_request:
|
|
125
|
+
branches: [main]
|
|
126
|
+
|
|
127
|
+
jobs:
|
|
128
|
+
test:
|
|
129
|
+
runs-on: ubuntu-latest
|
|
130
|
+
steps:
|
|
131
|
+
- uses: actions/checkout@v4
|
|
132
|
+
- uses: actions/setup-node@v4
|
|
133
|
+
with:
|
|
134
|
+
node-version: '20'
|
|
135
|
+
cache: 'npm'
|
|
136
|
+
- run: npm ci
|
|
137
|
+
- run: npm run lint
|
|
138
|
+
- run: npm run test
|
|
139
|
+
- run: npm run build
|
|
140
|
+
|
|
141
|
+
deploy:
|
|
142
|
+
needs: test
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
if: github.ref == 'refs/heads/main'
|
|
145
|
+
steps:
|
|
146
|
+
- uses: actions/checkout@v4
|
|
147
|
+
- name: Deploy to Vercel
|
|
148
|
+
uses: vercel/action-deploy@v1
|
|
149
|
+
with:
|
|
150
|
+
vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Matrix Testing**
|
|
154
|
+
```yaml
|
|
155
|
+
strategy:
|
|
156
|
+
matrix:
|
|
157
|
+
node-version: [18, 20, 21]
|
|
158
|
+
os: [ubuntu-latest, windows-latest]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Environment Strategy
|
|
162
|
+
|
|
163
|
+
**Typical Setup**
|
|
164
|
+
```
|
|
165
|
+
Development → Staging → Production
|
|
166
|
+
↓ ↓ ↓
|
|
167
|
+
Local Preview Live
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Branch-Based**
|
|
171
|
+
```
|
|
172
|
+
feature/* → Deploy to Preview/Staging
|
|
173
|
+
main → Deploy to Production
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Database Deployment
|
|
179
|
+
|
|
180
|
+
### PostgreSQL Options
|
|
181
|
+
|
|
182
|
+
| Platform | Type | Best For |
|
|
183
|
+
|----------|------|----------|
|
|
184
|
+
| **Neon** | Serverless | Auto-scaling, scale-to-zero |
|
|
185
|
+
| **Supabase** | Managed | Full backend-as-a-service |
|
|
186
|
+
| **Railway** | Managed | Simple setup, good pricing |
|
|
187
|
+
| **AWS RDS** | Managed | Enterprise, compliance needs |
|
|
188
|
+
| **Self-hosted** | VPS | Cost control, full access |
|
|
189
|
+
|
|
190
|
+
### Migration Strategy
|
|
191
|
+
|
|
192
|
+
**Prisma (Node.js)**
|
|
193
|
+
```bash
|
|
194
|
+
# Generate migration
|
|
195
|
+
npx prisma migrate dev --name add_user_table
|
|
196
|
+
|
|
197
|
+
# Deploy migration
|
|
198
|
+
npx prisma migrate deploy
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Alembic (Python)**
|
|
202
|
+
```bash
|
|
203
|
+
# Generate migration
|
|
204
|
+
alembic revision --autogenerate -m "Add user table"
|
|
205
|
+
|
|
206
|
+
# Run migration
|
|
207
|
+
alembic upgrade head
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Environment Configuration
|
|
213
|
+
|
|
214
|
+
### Environment Variables
|
|
215
|
+
|
|
216
|
+
**Required Variables**
|
|
217
|
+
```bash
|
|
218
|
+
# App
|
|
219
|
+
NODE_ENV=production
|
|
220
|
+
PORT=3000
|
|
221
|
+
|
|
222
|
+
# Database
|
|
223
|
+
DATABASE_URL=postgresql://...
|
|
224
|
+
|
|
225
|
+
# Auth
|
|
226
|
+
JWT_SECRET=...
|
|
227
|
+
NEXTAUTH_SECRET=...
|
|
228
|
+
|
|
229
|
+
# APIs
|
|
230
|
+
OPENAI_API_KEY=...
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Configuration Pattern**
|
|
234
|
+
```typescript
|
|
235
|
+
// config.ts
|
|
236
|
+
const config = {
|
|
237
|
+
development: {
|
|
238
|
+
apiUrl: 'http://localhost:3000',
|
|
239
|
+
debug: true,
|
|
240
|
+
},
|
|
241
|
+
production: {
|
|
242
|
+
apiUrl: process.env.API_URL,
|
|
243
|
+
debug: false,
|
|
244
|
+
},
|
|
245
|
+
}[process.env.NODE_ENV || 'development'];
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Docker Deployment
|
|
251
|
+
|
|
252
|
+
### Dockerfile Patterns
|
|
253
|
+
|
|
254
|
+
**Node.js**
|
|
255
|
+
```dockerfile
|
|
256
|
+
# Build stage
|
|
257
|
+
FROM node:20-alpine AS builder
|
|
258
|
+
WORKDIR /app
|
|
259
|
+
COPY package*.json ./
|
|
260
|
+
RUN npm ci
|
|
261
|
+
COPY . .
|
|
262
|
+
RUN npm run build
|
|
263
|
+
|
|
264
|
+
# Production stage
|
|
265
|
+
FROM node:20-alpine
|
|
266
|
+
WORKDIR /app
|
|
267
|
+
COPY --from=builder /app/dist ./dist
|
|
268
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
269
|
+
COPY package*.json ./
|
|
270
|
+
EXPOSE 3000
|
|
271
|
+
CMD ["node", "dist/index.js"]
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Python**
|
|
275
|
+
```dockerfile
|
|
276
|
+
FROM python:3.11-slim
|
|
277
|
+
|
|
278
|
+
WORKDIR /app
|
|
279
|
+
|
|
280
|
+
# Install uv
|
|
281
|
+
RUN pip install uv
|
|
282
|
+
|
|
283
|
+
# Copy and install dependencies
|
|
284
|
+
COPY pyproject.toml ./
|
|
285
|
+
RUN uv pip install --system -e "."
|
|
286
|
+
|
|
287
|
+
# Copy source
|
|
288
|
+
COPY src/ ./src/
|
|
289
|
+
|
|
290
|
+
EXPOSE 8000
|
|
291
|
+
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Docker Compose
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
# docker-compose.yml
|
|
298
|
+
version: '3.8'
|
|
299
|
+
|
|
300
|
+
services:
|
|
301
|
+
app:
|
|
302
|
+
build: .
|
|
303
|
+
ports:
|
|
304
|
+
- "3000:3000"
|
|
305
|
+
environment:
|
|
306
|
+
- NODE_ENV=production
|
|
307
|
+
- DATABASE_URL=postgresql://postgres:password@db:5432/myapp
|
|
308
|
+
depends_on:
|
|
309
|
+
- db
|
|
310
|
+
|
|
311
|
+
db:
|
|
312
|
+
image: postgres:15-alpine
|
|
313
|
+
environment:
|
|
314
|
+
- POSTGRES_USER=postgres
|
|
315
|
+
- POSTGRES_PASSWORD=password
|
|
316
|
+
- POSTGRES_DB=myapp
|
|
317
|
+
volumes:
|
|
318
|
+
- postgres_data:/var/lib/postgresql/data
|
|
319
|
+
|
|
320
|
+
volumes:
|
|
321
|
+
postgres_data:
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Health Checks & Monitoring
|
|
327
|
+
|
|
328
|
+
### Health Check Endpoint
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// Simple health check
|
|
332
|
+
app.get('/health', (req, res) => {
|
|
333
|
+
res.json({
|
|
334
|
+
status: 'ok',
|
|
335
|
+
timestamp: new Date().toISOString(),
|
|
336
|
+
version: process.env.npm_package_version
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// With dependencies check
|
|
341
|
+
app.get('/health', async (req, res) => {
|
|
342
|
+
const checks = {
|
|
343
|
+
database: await checkDatabase(),
|
|
344
|
+
cache: await checkCache(),
|
|
345
|
+
externalApi: await checkExternalApi(),
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const healthy = Object.values(checks).every(c => c.status === 'ok');
|
|
349
|
+
|
|
350
|
+
res.status(healthy ? 200 : 503).json({
|
|
351
|
+
status: healthy ? 'ok' : 'error',
|
|
352
|
+
checks,
|
|
353
|
+
timestamp: new Date().toISOString(),
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Monitoring Tools
|
|
359
|
+
|
|
360
|
+
| Tool | Purpose | Cost |
|
|
361
|
+
|------|---------|------|
|
|
362
|
+
| **Sentry** | Error tracking | Free tier |
|
|
363
|
+
| **Datadog** | Full observability | Paid |
|
|
364
|
+
| **Grafana Cloud** | Metrics/dashboards | Free tier |
|
|
365
|
+
| **UptimeRobot** | Uptime monitoring | Free tier |
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Security Checklist
|
|
370
|
+
|
|
371
|
+
- [ ] HTTPS enforced
|
|
372
|
+
- [ ] Secrets in environment variables (never in code)
|
|
373
|
+
- [ ] Database credentials rotated regularly
|
|
374
|
+
- [ ] CORS properly configured
|
|
375
|
+
- [ ] Rate limiting implemented
|
|
376
|
+
- [ ] Input validation on all endpoints
|
|
377
|
+
- [ ] Dependencies kept up to date
|
|
378
|
+
- [ ] Security headers set (HSTS, CSP, etc.)
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Troubleshooting
|
|
383
|
+
|
|
384
|
+
### Common Issues
|
|
385
|
+
|
|
386
|
+
**Build fails**
|
|
387
|
+
- Check Node.js/Python version matches
|
|
388
|
+
- Clear cache and reinstall dependencies
|
|
389
|
+
- Check for missing environment variables
|
|
390
|
+
|
|
391
|
+
**Deployment succeeds but app crashes**
|
|
392
|
+
- Check logs: `vercel logs` / `railway logs` / `docker logs`
|
|
393
|
+
- Verify environment variables are set
|
|
394
|
+
- Check database connectivity
|
|
395
|
+
|
|
396
|
+
**Slow cold starts**
|
|
397
|
+
- Use smaller dependencies
|
|
398
|
+
- Implement connection pooling
|
|
399
|
+
- Use edge functions where appropriate
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Resources
|
|
404
|
+
|
|
405
|
+
- **Vercel Docs**: https://vercel.com/docs
|
|
406
|
+
- **Railway Docs**: https://docs.railway.app/
|
|
407
|
+
- **Docker Docs**: https://docs.docker.com/
|
|
408
|
+
- **GitHub Actions**: https://docs.github.com/en/actions
|