@polymorphism-tech/morph-spec 2.2.0 → 2.4.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.
- package/CLAUDE.md +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/CLAUDE.md +150 -442
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
|
@@ -1,437 +1,131 @@
|
|
|
1
|
-
# Container Specialist
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
networks:
|
|
133
|
-
- app-network
|
|
134
|
-
|
|
135
|
-
redis:
|
|
136
|
-
image: redis:7-alpine
|
|
137
|
-
ports:
|
|
138
|
-
- "6379:6379"
|
|
139
|
-
networks:
|
|
140
|
-
- app-network
|
|
141
|
-
|
|
142
|
-
networks:
|
|
143
|
-
app-network:
|
|
144
|
-
driver: bridge
|
|
145
|
-
|
|
146
|
-
volumes:
|
|
147
|
-
sqldata:
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Azure Container Registry (ACR)
|
|
151
|
-
|
|
152
|
-
### Criar ACR via Bicep
|
|
153
|
-
|
|
154
|
-
```bicep
|
|
155
|
-
// modules/acr.bicep
|
|
156
|
-
@description('ACR name')
|
|
157
|
-
param name string
|
|
158
|
-
|
|
159
|
-
@description('Location')
|
|
160
|
-
param location string
|
|
161
|
-
|
|
162
|
-
@description('Tags')
|
|
163
|
-
param tags object = {}
|
|
164
|
-
|
|
165
|
-
@description('SKU')
|
|
166
|
-
@allowed(['Basic', 'Standard', 'Premium'])
|
|
167
|
-
param sku string = 'Basic'
|
|
168
|
-
|
|
169
|
-
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
|
|
170
|
-
name: name
|
|
171
|
-
location: location
|
|
172
|
-
tags: tags
|
|
173
|
-
sku: {
|
|
174
|
-
name: sku
|
|
175
|
-
}
|
|
176
|
-
properties: {
|
|
177
|
-
adminUserEnabled: true
|
|
178
|
-
publicNetworkAccess: 'Enabled'
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
output loginServer string = acr.properties.loginServer
|
|
183
|
-
output name string = acr.name
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Commands ACR
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
# Criar ACR
|
|
190
|
-
az acr create --resource-group rg-myapp --name myappacr --sku Basic
|
|
191
|
-
|
|
192
|
-
# Login
|
|
193
|
-
az acr login --name myappacr
|
|
194
|
-
|
|
195
|
-
# Build e push
|
|
196
|
-
az acr build --registry myappacr --image myapp:v1 .
|
|
197
|
-
|
|
198
|
-
# Listar imagens
|
|
199
|
-
az acr repository list --name myappacr
|
|
200
|
-
|
|
201
|
-
# Listar tags
|
|
202
|
-
az acr repository show-tags --name myappacr --repository myapp
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## Azure Container Apps
|
|
206
|
-
|
|
207
|
-
### Deploy via Bicep
|
|
208
|
-
|
|
209
|
-
```bicep
|
|
210
|
-
// modules/container-app.bicep
|
|
211
|
-
@description('App name')
|
|
212
|
-
param name string
|
|
213
|
-
|
|
214
|
-
@description('Location')
|
|
215
|
-
param location string
|
|
216
|
-
|
|
217
|
-
@description('Tags')
|
|
218
|
-
param tags object = {}
|
|
219
|
-
|
|
220
|
-
@description('Container App Environment ID')
|
|
221
|
-
param environmentId string
|
|
222
|
-
|
|
223
|
-
@description('Container image')
|
|
224
|
-
param containerImage string
|
|
225
|
-
|
|
226
|
-
@description('Registry server')
|
|
227
|
-
param registryServer string
|
|
228
|
-
|
|
229
|
-
@description('Registry username')
|
|
230
|
-
param registryUsername string
|
|
231
|
-
|
|
232
|
-
@description('Registry password')
|
|
233
|
-
@secure()
|
|
234
|
-
param registryPassword string
|
|
235
|
-
|
|
236
|
-
@description('Environment variables')
|
|
237
|
-
param envVars array = []
|
|
238
|
-
|
|
239
|
-
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
|
240
|
-
name: name
|
|
241
|
-
location: location
|
|
242
|
-
tags: tags
|
|
243
|
-
properties: {
|
|
244
|
-
managedEnvironmentId: environmentId
|
|
245
|
-
configuration: {
|
|
246
|
-
ingress: {
|
|
247
|
-
external: true
|
|
248
|
-
targetPort: 8080
|
|
249
|
-
transport: 'http'
|
|
250
|
-
allowInsecure: false
|
|
251
|
-
traffic: [
|
|
252
|
-
{
|
|
253
|
-
latestRevision: true
|
|
254
|
-
weight: 100
|
|
255
|
-
}
|
|
256
|
-
]
|
|
257
|
-
}
|
|
258
|
-
registries: [
|
|
259
|
-
{
|
|
260
|
-
server: registryServer
|
|
261
|
-
username: registryUsername
|
|
262
|
-
passwordSecretRef: 'registry-password'
|
|
263
|
-
}
|
|
264
|
-
]
|
|
265
|
-
secrets: [
|
|
266
|
-
{
|
|
267
|
-
name: 'registry-password'
|
|
268
|
-
value: registryPassword
|
|
269
|
-
}
|
|
270
|
-
]
|
|
271
|
-
}
|
|
272
|
-
template: {
|
|
273
|
-
containers: [
|
|
274
|
-
{
|
|
275
|
-
name: name
|
|
276
|
-
image: containerImage
|
|
277
|
-
resources: {
|
|
278
|
-
cpu: json('0.25')
|
|
279
|
-
memory: '0.5Gi'
|
|
280
|
-
}
|
|
281
|
-
env: envVars
|
|
282
|
-
probes: [
|
|
283
|
-
{
|
|
284
|
-
type: 'Liveness'
|
|
285
|
-
httpGet: {
|
|
286
|
-
path: '/health'
|
|
287
|
-
port: 8080
|
|
288
|
-
}
|
|
289
|
-
initialDelaySeconds: 10
|
|
290
|
-
periodSeconds: 30
|
|
291
|
-
}
|
|
292
|
-
{
|
|
293
|
-
type: 'Readiness'
|
|
294
|
-
httpGet: {
|
|
295
|
-
path: '/health/ready'
|
|
296
|
-
port: 8080
|
|
297
|
-
}
|
|
298
|
-
initialDelaySeconds: 5
|
|
299
|
-
periodSeconds: 10
|
|
300
|
-
}
|
|
301
|
-
]
|
|
302
|
-
}
|
|
303
|
-
]
|
|
304
|
-
scale: {
|
|
305
|
-
minReplicas: 0
|
|
306
|
-
maxReplicas: 5
|
|
307
|
-
rules: [
|
|
308
|
-
{
|
|
309
|
-
name: 'http-scale'
|
|
310
|
-
http: {
|
|
311
|
-
metadata: {
|
|
312
|
-
concurrentRequests: '100'
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
]
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
output url string = 'https://${containerApp.properties.configuration.ingress.fqdn}'
|
|
323
|
-
output name string = containerApp.name
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### Deploy via CLI
|
|
327
|
-
|
|
328
|
-
```bash
|
|
329
|
-
# Criar environment
|
|
330
|
-
az containerapp env create \
|
|
331
|
-
--name myapp-env \
|
|
332
|
-
--resource-group rg-myapp \
|
|
333
|
-
--location brazilsouth
|
|
334
|
-
|
|
335
|
-
# Criar container app
|
|
336
|
-
az containerapp create \
|
|
337
|
-
--name myapp \
|
|
338
|
-
--resource-group rg-myapp \
|
|
339
|
-
--environment myapp-env \
|
|
340
|
-
--image myappacr.azurecr.io/myapp:latest \
|
|
341
|
-
--registry-server myappacr.azurecr.io \
|
|
342
|
-
--registry-username myappacr \
|
|
343
|
-
--registry-password $ACR_PASSWORD \
|
|
344
|
-
--target-port 8080 \
|
|
345
|
-
--ingress external \
|
|
346
|
-
--min-replicas 0 \
|
|
347
|
-
--max-replicas 5 \
|
|
348
|
-
--cpu 0.25 \
|
|
349
|
-
--memory 0.5Gi
|
|
350
|
-
|
|
351
|
-
# Atualizar imagem
|
|
352
|
-
az containerapp update \
|
|
353
|
-
--name myapp \
|
|
354
|
-
--resource-group rg-myapp \
|
|
355
|
-
--image myappacr.azurecr.io/myapp:v2
|
|
356
|
-
|
|
357
|
-
# Ver logs
|
|
358
|
-
az containerapp logs show \
|
|
359
|
-
--name myapp \
|
|
360
|
-
--resource-group rg-myapp \
|
|
361
|
-
--follow
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## Health Checks no ASP.NET
|
|
365
|
-
|
|
366
|
-
```csharp
|
|
367
|
-
// Program.cs
|
|
368
|
-
builder.Services.AddHealthChecks()
|
|
369
|
-
.AddSqlServer(
|
|
370
|
-
connectionString: builder.Configuration.GetConnectionString("Default")!,
|
|
371
|
-
name: "database",
|
|
372
|
-
tags: new[] { "ready" })
|
|
373
|
-
.AddRedis(
|
|
374
|
-
redisConnectionString: builder.Configuration.GetConnectionString("Redis")!,
|
|
375
|
-
name: "redis",
|
|
376
|
-
tags: new[] { "ready" });
|
|
377
|
-
|
|
378
|
-
app.MapHealthChecks("/health", new HealthCheckOptions
|
|
379
|
-
{
|
|
380
|
-
Predicate = _ => true,
|
|
381
|
-
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
app.MapHealthChecks("/health/ready", new HealthCheckOptions
|
|
385
|
-
{
|
|
386
|
-
Predicate = check => check.Tags.Contains("ready")
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
app.MapHealthChecks("/health/live", new HealthCheckOptions
|
|
390
|
-
{
|
|
391
|
-
Predicate = _ => false // Sempre retorna healthy
|
|
392
|
-
});
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
## Otimização de Imagens
|
|
396
|
-
|
|
397
|
-
### Tamanho de Imagens
|
|
398
|
-
|
|
399
|
-
| Base Image | Tamanho |
|
|
400
|
-
|------------|---------|
|
|
401
|
-
| `aspnet:9.0` | ~220MB |
|
|
402
|
-
| `aspnet:9.0-alpine` | ~110MB |
|
|
403
|
-
| `aspnet:9.0-chiseled` | ~80MB |
|
|
404
|
-
|
|
405
|
-
### Chiseled Images (Mais Seguro)
|
|
406
|
-
|
|
407
|
-
```dockerfile
|
|
408
|
-
# Runtime minimal e seguro
|
|
409
|
-
FROM mcr.microsoft.com/dotnet/aspnet:9.0-chiseled AS final
|
|
410
|
-
WORKDIR /app
|
|
411
|
-
COPY --from=publish /app/publish .
|
|
412
|
-
USER $APP_UID
|
|
413
|
-
ENTRYPOINT ["dotnet", "Web.dll"]
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
## Documentação de Referência
|
|
417
|
-
|
|
418
|
-
- [Docker Documentation](https://docs.docker.com/)
|
|
419
|
-
- [Container Apps](https://learn.microsoft.com/en-us/azure/container-apps/)
|
|
420
|
-
- [ACR](https://learn.microsoft.com/en-us/azure/container-registry/)
|
|
421
|
-
- [.NET Container Images](https://learn.microsoft.com/en-us/dotnet/core/docker/)
|
|
422
|
-
|
|
423
|
-
## Checklist de Containerização
|
|
424
|
-
|
|
425
|
-
- [ ] Dockerfile multi-stage
|
|
426
|
-
- [ ] .dockerignore configurado
|
|
427
|
-
- [ ] Non-root user no container
|
|
428
|
-
- [ ] Health checks configurados
|
|
429
|
-
- [ ] Imagem base alpine ou chiseled
|
|
430
|
-
- [ ] Docker Compose para dev
|
|
431
|
-
- [ ] ACR criado e configurado
|
|
432
|
-
- [ ] Container App com scale-to-zero
|
|
433
|
-
- [ ] Probes de liveness e readiness
|
|
434
|
-
|
|
435
|
-
---
|
|
436
|
-
|
|
437
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
1
|
+
# Container Specialist
|
|
2
|
+
|
|
3
|
+
> **Layer:** 2 | **Load:** on-keyword | **Keywords:** docker, container, containerize, container apps, acr, registry, image
|
|
4
|
+
|
|
5
|
+
Especialista em containerização com Docker e deploy para Azure Container Apps.
|
|
6
|
+
|
|
7
|
+
## Dockerfile (.NET Multi-stage)
|
|
8
|
+
|
|
9
|
+
```dockerfile
|
|
10
|
+
FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine AS build
|
|
11
|
+
WORKDIR /src
|
|
12
|
+
COPY ["src/Web/Web.csproj", "src/Web/"]
|
|
13
|
+
COPY ["src/Application/Application.csproj", "src/Application/"]
|
|
14
|
+
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
|
|
15
|
+
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
|
|
16
|
+
RUN dotnet restore "src/Web/Web.csproj"
|
|
17
|
+
COPY . .
|
|
18
|
+
WORKDIR "/src/src/Web"
|
|
19
|
+
RUN dotnet publish "Web.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
|
20
|
+
|
|
21
|
+
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS final
|
|
22
|
+
WORKDIR /app
|
|
23
|
+
RUN addgroup -g 1000 appgroup && adduser -u 1000 -G appgroup -D appuser
|
|
24
|
+
COPY --from=publish /app/publish .
|
|
25
|
+
RUN chown -R appuser:appgroup /app
|
|
26
|
+
USER appuser
|
|
27
|
+
EXPOSE 8080
|
|
28
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
29
|
+
CMD wget --quiet --tries=1 --spider http://localhost:8080/health || exit 1
|
|
30
|
+
ENTRYPOINT ["dotnet", "Web.dll"]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Image Sizes
|
|
34
|
+
| Base Image | Size |
|
|
35
|
+
|------------|------|
|
|
36
|
+
| `aspnet:10.0` | ~220MB |
|
|
37
|
+
| `aspnet:10.0-alpine` | ~110MB |
|
|
38
|
+
| `aspnet:10.0-chiseled` | ~80MB (most secure) |
|
|
39
|
+
|
|
40
|
+
## ACR (Azure Container Registry)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
az acr create -g rg-myapp -n myappacr --sku Basic
|
|
44
|
+
az acr login -n myappacr
|
|
45
|
+
az acr build --registry myappacr --image myapp:v1 .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Container App (Bicep)
|
|
49
|
+
|
|
50
|
+
```bicep
|
|
51
|
+
param name string
|
|
52
|
+
param location string
|
|
53
|
+
param tags object = {}
|
|
54
|
+
param environmentId string
|
|
55
|
+
param containerImage string
|
|
56
|
+
param registryServer string
|
|
57
|
+
param registryUsername string
|
|
58
|
+
@secure() param registryPassword string
|
|
59
|
+
|
|
60
|
+
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
|
61
|
+
name: name
|
|
62
|
+
location: location
|
|
63
|
+
tags: tags
|
|
64
|
+
properties: {
|
|
65
|
+
managedEnvironmentId: environmentId
|
|
66
|
+
configuration: {
|
|
67
|
+
ingress: { external: true, targetPort: 8080, transport: 'http', allowInsecure: false }
|
|
68
|
+
registries: [{ server: registryServer, username: registryUsername, passwordSecretRef: 'reg-pwd' }]
|
|
69
|
+
secrets: [{ name: 'reg-pwd', value: registryPassword }]
|
|
70
|
+
}
|
|
71
|
+
template: {
|
|
72
|
+
containers: [{
|
|
73
|
+
name: name, image: containerImage
|
|
74
|
+
resources: { cpu: json('0.25'), memory: '0.5Gi' }
|
|
75
|
+
probes: [
|
|
76
|
+
{ type: 'Liveness', httpGet: { path: '/health', port: 8080 }, initialDelaySeconds: 10 }
|
|
77
|
+
{ type: 'Readiness', httpGet: { path: '/health/ready', port: 8080 }, initialDelaySeconds: 5 }
|
|
78
|
+
]
|
|
79
|
+
}]
|
|
80
|
+
scale: { minReplicas: 0, maxReplicas: 5
|
|
81
|
+
rules: [{ name: 'http-scale', http: { metadata: { concurrentRequests: '100' } } }]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
output url string = 'https://${containerApp.properties.configuration.ingress.fqdn}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Health Checks (ASP.NET)
|
|
90
|
+
|
|
91
|
+
```csharp
|
|
92
|
+
builder.Services.AddHealthChecks()
|
|
93
|
+
.AddSqlServer(connString, name: "database", tags: new[] { "ready" });
|
|
94
|
+
|
|
95
|
+
app.MapHealthChecks("/health");
|
|
96
|
+
app.MapHealthChecks("/health/ready", new() { Predicate = c => c.Tags.Contains("ready") });
|
|
97
|
+
app.MapHealthChecks("/health/live", new() { Predicate = _ => false }); // Always healthy
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Docker Compose (Dev)
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
services:
|
|
104
|
+
web:
|
|
105
|
+
build: { context: ., dockerfile: Dockerfile }
|
|
106
|
+
ports: ["8080:8080"]
|
|
107
|
+
environment:
|
|
108
|
+
- ConnectionStrings__Default=Server=db;Database=App;User=sa;Password=Pass!;TrustServerCertificate=true
|
|
109
|
+
depends_on: { db: { condition: service_healthy } }
|
|
110
|
+
db:
|
|
111
|
+
image: mcr.microsoft.com/mssql/server:2022-latest
|
|
112
|
+
environment: [ACCEPT_EULA=Y, SA_PASSWORD=YourStrong!Passw0rd]
|
|
113
|
+
ports: ["1433:1433"]
|
|
114
|
+
volumes: [sqldata:/var/opt/mssql]
|
|
115
|
+
volumes:
|
|
116
|
+
sqldata:
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Checklist
|
|
120
|
+
- [ ] Dockerfile multi-stage with alpine/chiseled
|
|
121
|
+
- [ ] .dockerignore configured
|
|
122
|
+
- [ ] Non-root user in container
|
|
123
|
+
- [ ] Health checks (liveness + readiness)
|
|
124
|
+
- [ ] Docker Compose for dev
|
|
125
|
+
- [ ] ACR created and configured
|
|
126
|
+
- [ ] Container App with scale-to-zero
|
|
127
|
+
- [ ] Probes configured
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
*MORPH-SPEC by Polymorphism Tech*
|