@k2works/claude-code-booster 6.2.0 → 6.3.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.
Files changed (618) hide show
  1. package/lib/assets/.claude/skills/practicing-getting-start-tdd/SKILL.md +3 -7
  2. package/lib/assets/docs/article/index.md +16 -41
  3. package/lib/assets/docs/index.md +1 -1
  4. package/lib/assets/mkdocs.yml +0 -6
  5. package/package.json +1 -1
  6. package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +0 -484
  7. package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +0 -528
  8. package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +0 -546
  9. package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +0 -309
  10. package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +0 -329
  11. package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +0 -507
  12. package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +0 -307
  13. package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +0 -300
  14. package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +0 -345
  15. package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +0 -312
  16. package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +0 -295
  17. package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +0 -331
  18. package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +0 -328
  19. package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +0 -374
  20. package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +0 -165
  21. package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +0 -187
  22. package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +0 -321
  23. package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +0 -296
  24. package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +0 -295
  25. package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +0 -283
  26. package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +0 -303
  27. package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +0 -346
  28. package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +0 -388
  29. package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +0 -282
  30. package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +0 -389
  31. package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +0 -393
  32. package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +0 -359
  33. package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +0 -361
  34. package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +0 -392
  35. package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +0 -538
  36. package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +0 -404
  37. package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +0 -408
  38. package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +0 -494
  39. package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +0 -575
  40. package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +0 -576
  41. package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +0 -484
  42. package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +0 -471
  43. package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +0 -334
  44. package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +0 -410
  45. package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +0 -459
  46. package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +0 -484
  47. package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +0 -748
  48. package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +0 -576
  49. package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +0 -527
  50. package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +0 -541
  51. package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +0 -241
  52. package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +0 -392
  53. package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +0 -383
  54. package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +0 -384
  55. package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +0 -204
  56. package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +0 -277
  57. package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +0 -303
  58. package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +0 -173
  59. package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +0 -177
  60. package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +0 -263
  61. package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +0 -278
  62. package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +0 -157
  63. package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +0 -185
  64. package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +0 -613
  65. package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +0 -738
  66. package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +0 -300
  67. package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +0 -429
  68. package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +0 -328
  69. package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +0 -475
  70. package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +0 -532
  71. package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +0 -296
  72. package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +0 -349
  73. package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +0 -404
  74. package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +0 -248
  75. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +0 -393
  76. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +0 -461
  77. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +0 -504
  78. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +0 -425
  79. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +0 -391
  80. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +0 -696
  81. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +0 -451
  82. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +0 -488
  83. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +0 -488
  84. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +0 -436
  85. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +0 -437
  86. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +0 -348
  87. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +0 -318
  88. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +0 -605
  89. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +0 -364
  90. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +0 -359
  91. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +0 -423
  92. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +0 -376
  93. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +0 -412
  94. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +0 -300
  95. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +0 -333
  96. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +0 -341
  97. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +0 -274
  98. package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +0 -307
  99. package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +0 -313
  100. package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +0 -371
  101. package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +0 -266
  102. package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +0 -263
  103. package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +0 -292
  104. package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +0 -404
  105. package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +0 -328
  106. package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +0 -391
  107. package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +0 -296
  108. package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +0 -312
  109. package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +0 -335
  110. package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +0 -341
  111. package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +0 -388
  112. package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +0 -186
  113. package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +0 -228
  114. package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +0 -253
  115. package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +0 -372
  116. package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +0 -447
  117. package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +0 -334
  118. package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +0 -412
  119. package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +0 -478
  120. package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +0 -174
  121. package/lib/assets/docs/article/functional-desgin-ppp/index.md +0 -90
  122. package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +0 -459
  123. package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +0 -472
  124. package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +0 -434
  125. package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +0 -282
  126. package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +0 -256
  127. package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +0 -850
  128. package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +0 -393
  129. package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +0 -392
  130. package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +0 -348
  131. package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +0 -340
  132. package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +0 -365
  133. package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +0 -388
  134. package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +0 -370
  135. package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +0 -401
  136. package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +0 -309
  137. package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +0 -306
  138. package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +0 -313
  139. package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +0 -324
  140. package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +0 -320
  141. package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +0 -313
  142. package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +0 -345
  143. package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +0 -358
  144. package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +0 -243
  145. package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +0 -337
  146. package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +0 -357
  147. package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +0 -366
  148. package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +0 -373
  149. package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +0 -524
  150. package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +0 -566
  151. package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +0 -372
  152. package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +0 -336
  153. package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +0 -526
  154. package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +0 -450
  155. package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +0 -416
  156. package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +0 -388
  157. package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +0 -407
  158. package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +0 -485
  159. package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +0 -400
  160. package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +0 -351
  161. package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +0 -333
  162. package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +0 -739
  163. package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +0 -633
  164. package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +0 -521
  165. package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +0 -442
  166. package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +0 -697
  167. package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +0 -243
  168. package/lib/assets/docs/article/getting-start-docker-kubernetes/01-container-and-docker-basics.md +0 -341
  169. package/lib/assets/docs/article/getting-start-docker-kubernetes/02-container-deployment.md +0 -785
  170. package/lib/assets/docs/article/getting-start-docker-kubernetes/03-practical-container-build-deploy.md +0 -466
  171. package/lib/assets/docs/article/getting-start-docker-kubernetes/04-multi-container-application.md +0 -878
  172. package/lib/assets/docs/article/getting-start-docker-kubernetes/05-kubernetes-introduction.md +0 -585
  173. package/lib/assets/docs/article/getting-start-docker-kubernetes/06-kubernetes-deploy-cluster.md +0 -620
  174. package/lib/assets/docs/article/getting-start-docker-kubernetes/07-kubernetes-advanced.md +0 -621
  175. package/lib/assets/docs/article/getting-start-docker-kubernetes/08-kubernetes-packaging.md +0 -518
  176. package/lib/assets/docs/article/getting-start-docker-kubernetes/09-container-operations.md +0 -546
  177. package/lib/assets/docs/article/getting-start-docker-kubernetes/10-optimal-container-image.md +0 -640
  178. package/lib/assets/docs/article/getting-start-docker-kubernetes/11-continuous-delivery.md +0 -607
  179. package/lib/assets/docs/article/getting-start-docker-kubernetes/12-container-use-cases.md +0 -463
  180. package/lib/assets/docs/article/getting-start-docker-kubernetes/13-case-monolith-compose-vs-kustomize.md +0 -346
  181. package/lib/assets/docs/article/getting-start-docker-kubernetes/14-case-event-driven-kustomize-vs-helm.md +0 -324
  182. package/lib/assets/docs/article/getting-start-docker-kubernetes/15-case-escqrs-axon-kustomize-vs-helm.md +0 -297
  183. package/lib/assets/docs/article/getting-start-docker-kubernetes/16-case-escqrs-kafka-kustomize-vs-helm.md +0 -256
  184. package/lib/assets/docs/article/getting-start-docker-kubernetes/17-case-comparison-summary.md +0 -141
  185. package/lib/assets/docs/article/getting-start-docker-kubernetes/18-case-load-testing.md +0 -303
  186. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-a-dev-tools-setup.md +0 -274
  187. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-b-orchestration-environments.md +0 -530
  188. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-c-tips.md +0 -519
  189. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-01-comic.png +0 -0
  190. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-02-comic.png +0 -0
  191. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-03-comic.png +0 -0
  192. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-04-comic.png +0 -0
  193. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-05-comic.png +0 -0
  194. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-06-comic.png +0 -0
  195. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-07-comic.png +0 -0
  196. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-08-comic.png +0 -0
  197. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-09-comic.png +0 -0
  198. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-10-comic.png +0 -0
  199. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-11-comic.png +0 -0
  200. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-12-comic.png +0 -0
  201. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/overview-comic.png +0 -0
  202. package/lib/assets/docs/article/getting-start-docker-kubernetes/index.md +0 -82
  203. package/lib/assets/docs/article/getting-start-docker-kubernetes/outline.md +0 -220
  204. package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +0 -175
  205. package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +0 -171
  206. package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +0 -144
  207. package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +0 -97
  208. package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +0 -308
  209. package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +0 -250
  210. package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +0 -140
  211. package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +0 -139
  212. package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +0 -136
  213. package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +0 -123
  214. package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +0 -147
  215. package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +0 -170
  216. package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +0 -65
  217. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +0 -241
  218. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +0 -253
  219. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +0 -211
  220. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +0 -101
  221. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +0 -265
  222. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +0 -204
  223. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +0 -223
  224. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +0 -258
  225. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +0 -183
  226. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +0 -175
  227. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +0 -201
  228. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +0 -220
  229. package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +0 -83
  230. package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +0 -96
  231. package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +0 -104
  232. package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +0 -118
  233. package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +0 -105
  234. package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +0 -97
  235. package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +0 -80
  236. package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +0 -119
  237. package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +0 -117
  238. package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +0 -113
  239. package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +0 -187
  240. package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +0 -151
  241. package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +0 -154
  242. package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +0 -35
  243. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +0 -211
  244. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +0 -255
  245. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +0 -227
  246. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +0 -188
  247. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +0 -276
  248. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +0 -199
  249. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +0 -170
  250. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +0 -184
  251. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +0 -231
  252. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +0 -198
  253. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +0 -221
  254. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +0 -224
  255. package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +0 -71
  256. package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +0 -222
  257. package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +0 -311
  258. package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +0 -348
  259. package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +0 -121
  260. package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +0 -281
  261. package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +0 -242
  262. package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +0 -402
  263. package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +0 -430
  264. package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +0 -408
  265. package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +0 -234
  266. package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +0 -304
  267. package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +0 -419
  268. package/lib/assets/docs/article/getting-start-tdd/go/index.md +0 -83
  269. package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +0 -288
  270. package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +0 -346
  271. package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +0 -266
  272. package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +0 -191
  273. package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +0 -322
  274. package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +0 -318
  275. package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +0 -421
  276. package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +0 -399
  277. package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +0 -470
  278. package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +0 -443
  279. package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +0 -401
  280. package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +0 -640
  281. package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +0 -49
  282. package/lib/assets/docs/article/getting-start-tdd/index.md +0 -93
  283. package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +0 -384
  284. package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +0 -358
  285. package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +0 -454
  286. package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +0 -418
  287. package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +0 -339
  288. package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +0 -299
  289. package/lib/assets/docs/article/getting-start-tdd/integration/index.md +0 -69
  290. package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +0 -243
  291. package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +0 -270
  292. package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +0 -194
  293. package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +0 -124
  294. package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +0 -391
  295. package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +0 -281
  296. package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +0 -635
  297. package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +0 -402
  298. package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +0 -319
  299. package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +0 -197
  300. package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +0 -176
  301. package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +0 -214
  302. package/lib/assets/docs/article/getting-start-tdd/java/index.md +0 -61
  303. package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +0 -253
  304. package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +0 -271
  305. package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +0 -178
  306. package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +0 -121
  307. package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +0 -323
  308. package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +0 -244
  309. package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +0 -336
  310. package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +0 -331
  311. package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +0 -294
  312. package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +0 -208
  313. package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +0 -216
  314. package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +0 -304
  315. package/lib/assets/docs/article/getting-start-tdd/node/index.md +0 -56
  316. package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +0 -268
  317. package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +0 -209
  318. package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +0 -257
  319. package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +0 -150
  320. package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +0 -419
  321. package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +0 -330
  322. package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +0 -380
  323. package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +0 -461
  324. package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +0 -468
  325. package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +0 -190
  326. package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +0 -274
  327. package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +0 -316
  328. package/lib/assets/docs/article/getting-start-tdd/php/index.md +0 -84
  329. package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +0 -210
  330. package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +0 -256
  331. package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +0 -208
  332. package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +0 -96
  333. package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +0 -283
  334. package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +0 -199
  335. package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +0 -217
  336. package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +0 -181
  337. package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +0 -139
  338. package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +0 -131
  339. package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +0 -125
  340. package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +0 -135
  341. package/lib/assets/docs/article/getting-start-tdd/python/index.md +0 -55
  342. package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +0 -240
  343. package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +0 -247
  344. package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +0 -237
  345. package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +0 -121
  346. package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +0 -296
  347. package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +0 -257
  348. package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +0 -288
  349. package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +0 -338
  350. package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +0 -205
  351. package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +0 -184
  352. package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +0 -246
  353. package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +0 -407
  354. package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +0 -83
  355. package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +0 -220
  356. package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +0 -273
  357. package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +0 -242
  358. package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +0 -101
  359. package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +0 -221
  360. package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +0 -173
  361. package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +0 -151
  362. package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +0 -154
  363. package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +0 -119
  364. package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +0 -103
  365. package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +0 -114
  366. package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +0 -121
  367. package/lib/assets/docs/article/getting-start-tdd/rust/index.md +0 -83
  368. package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +0 -120
  369. package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +0 -116
  370. package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +0 -108
  371. package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +0 -132
  372. package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +0 -205
  373. package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +0 -195
  374. package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +0 -148
  375. package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +0 -115
  376. package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +0 -84
  377. package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +0 -113
  378. package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +0 -103
  379. package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +0 -101
  380. package/lib/assets/docs/article/getting-start-tdd/scala/index.md +0 -65
  381. package/lib/assets/docs/article/grokking-concurrency/all/index.md +0 -403
  382. package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +0 -563
  383. package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +0 -478
  384. package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +0 -529
  385. package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +0 -429
  386. package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +0 -519
  387. package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +0 -444
  388. package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +0 -474
  389. package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +0 -386
  390. package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +0 -106
  391. package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +0 -107
  392. package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +0 -100
  393. package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +0 -121
  394. package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +0 -122
  395. package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +0 -117
  396. package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +0 -88
  397. package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +0 -99
  398. package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +0 -119
  399. package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +0 -91
  400. package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +0 -96
  401. package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +0 -122
  402. package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +0 -100
  403. package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +0 -111
  404. package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +0 -98
  405. package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +0 -60
  406. package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +0 -83
  407. package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +0 -91
  408. package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +0 -55
  409. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +0 -79
  410. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +0 -102
  411. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +0 -93
  412. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +0 -109
  413. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +0 -103
  414. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +0 -92
  415. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +0 -120
  416. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +0 -106
  417. package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +0 -238
  418. package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +0 -95
  419. package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +0 -95
  420. package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +0 -90
  421. package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +0 -105
  422. package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +0 -98
  423. package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +0 -94
  424. package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +0 -110
  425. package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +0 -117
  426. package/lib/assets/docs/article/grokking-concurrency/index.md +0 -66
  427. package/lib/assets/docs/article/grokking-concurrency/java/index.md +0 -92
  428. package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +0 -307
  429. package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +0 -333
  430. package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +0 -220
  431. package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +0 -212
  432. package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +0 -111
  433. package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +0 -68
  434. package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +0 -100
  435. package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +0 -100
  436. package/lib/assets/docs/article/grokking-concurrency/python/index.md +0 -303
  437. package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +0 -238
  438. package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +0 -417
  439. package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +0 -226
  440. package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +0 -298
  441. package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +0 -314
  442. package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +0 -296
  443. package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +0 -313
  444. package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +0 -359
  445. package/lib/assets/docs/article/grokking-concurrency/rust/index.md +0 -260
  446. package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +0 -107
  447. package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +0 -119
  448. package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +0 -125
  449. package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +0 -174
  450. package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +0 -157
  451. package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +0 -93
  452. package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +0 -132
  453. package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +0 -154
  454. package/lib/assets/docs/article/grokking-concurrency/scala/index.md +0 -59
  455. package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +0 -77
  456. package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +0 -111
  457. package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +0 -92
  458. package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +0 -109
  459. package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +0 -118
  460. package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +0 -82
  461. package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +0 -130
  462. package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +0 -128
  463. package/lib/assets/docs/article/grokkingfp/all/index.md +0 -368
  464. package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +0 -539
  465. package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +0 -932
  466. package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +0 -1137
  467. package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +0 -1113
  468. package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +0 -1035
  469. package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +0 -794
  470. package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +0 -880
  471. package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +0 -981
  472. package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +0 -935
  473. package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +0 -879
  474. package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +0 -724
  475. package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +0 -635
  476. package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +0 -721
  477. package/lib/assets/docs/article/grokkingfp/clojure/index.md +0 -276
  478. package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +0 -676
  479. package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +0 -652
  480. package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +0 -629
  481. package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +0 -706
  482. package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +0 -760
  483. package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +0 -730
  484. package/lib/assets/docs/article/grokkingfp/csharp/index.md +0 -246
  485. package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +0 -820
  486. package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +0 -980
  487. package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +0 -990
  488. package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +0 -958
  489. package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +0 -956
  490. package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +0 -748
  491. package/lib/assets/docs/article/grokkingfp/elixir/index.md +0 -203
  492. package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +0 -721
  493. package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +0 -847
  494. package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +0 -994
  495. package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +0 -983
  496. package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +0 -1295
  497. package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +0 -1058
  498. package/lib/assets/docs/article/grokkingfp/fsharp/index.md +0 -210
  499. package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +0 -723
  500. package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +0 -970
  501. package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +0 -981
  502. package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +0 -841
  503. package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +0 -920
  504. package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +0 -931
  505. package/lib/assets/docs/article/grokkingfp/haskell/index.md +0 -234
  506. package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +0 -600
  507. package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +0 -875
  508. package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +0 -924
  509. package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +0 -887
  510. package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +0 -854
  511. package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +0 -853
  512. package/lib/assets/docs/article/grokkingfp/index.md +0 -143
  513. package/lib/assets/docs/article/grokkingfp/java/index.md +0 -211
  514. package/lib/assets/docs/article/grokkingfp/java/part-1.md +0 -657
  515. package/lib/assets/docs/article/grokkingfp/java/part-2.md +0 -684
  516. package/lib/assets/docs/article/grokkingfp/java/part-3.md +0 -681
  517. package/lib/assets/docs/article/grokkingfp/java/part-4.md +0 -780
  518. package/lib/assets/docs/article/grokkingfp/java/part-5.md +0 -968
  519. package/lib/assets/docs/article/grokkingfp/java/part-6.md +0 -1337
  520. package/lib/assets/docs/article/grokkingfp/python/index.md +0 -258
  521. package/lib/assets/docs/article/grokkingfp/python/part-1.md +0 -452
  522. package/lib/assets/docs/article/grokkingfp/python/part-2.md +0 -967
  523. package/lib/assets/docs/article/grokkingfp/python/part-3.md +0 -1013
  524. package/lib/assets/docs/article/grokkingfp/python/part-4.md +0 -774
  525. package/lib/assets/docs/article/grokkingfp/python/part-5.md +0 -756
  526. package/lib/assets/docs/article/grokkingfp/python/part-6.md +0 -870
  527. package/lib/assets/docs/article/grokkingfp/ruby/index.md +0 -330
  528. package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +0 -764
  529. package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +0 -947
  530. package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +0 -955
  531. package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +0 -930
  532. package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +0 -917
  533. package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +0 -1421
  534. package/lib/assets/docs/article/grokkingfp/rust/index.md +0 -242
  535. package/lib/assets/docs/article/grokkingfp/rust/part-1.md +0 -643
  536. package/lib/assets/docs/article/grokkingfp/rust/part-2.md +0 -1069
  537. package/lib/assets/docs/article/grokkingfp/rust/part-3.md +0 -1003
  538. package/lib/assets/docs/article/grokkingfp/rust/part-4.md +0 -582
  539. package/lib/assets/docs/article/grokkingfp/rust/part-5.md +0 -714
  540. package/lib/assets/docs/article/grokkingfp/rust/part-6.md +0 -517
  541. package/lib/assets/docs/article/grokkingfp/scala/index.md +0 -171
  542. package/lib/assets/docs/article/grokkingfp/scala/part-1.md +0 -552
  543. package/lib/assets/docs/article/grokkingfp/scala/part-2.md +0 -955
  544. package/lib/assets/docs/article/grokkingfp/scala/part-3.md +0 -928
  545. package/lib/assets/docs/article/grokkingfp/scala/part-4.md +0 -751
  546. package/lib/assets/docs/article/grokkingfp/scala/part-5.md +0 -731
  547. package/lib/assets/docs/article/grokkingfp/scala/part-6.md +0 -876
  548. package/lib/assets/docs/article/grokkingfp/typescript/index.md +0 -273
  549. package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +0 -570
  550. package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +0 -1138
  551. package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +0 -851
  552. package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +0 -1096
  553. package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +0 -726
  554. package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +0 -991
  555. package/lib/assets/docs/article/practical-database-design/index.md +0 -121
  556. package/lib/assets/docs/article/practical-database-design/part1/chapter01.md +0 -297
  557. package/lib/assets/docs/article/practical-database-design/part1/chapter02.md +0 -527
  558. package/lib/assets/docs/article/practical-database-design/part1/chapter03.md +0 -566
  559. package/lib/assets/docs/article/practical-database-design/part2/chapter04.md +0 -933
  560. package/lib/assets/docs/article/practical-database-design/part2/chapter05.md +0 -1636
  561. package/lib/assets/docs/article/practical-database-design/part2/chapter06.md +0 -2725
  562. package/lib/assets/docs/article/practical-database-design/part2/chapter07.md +0 -2091
  563. package/lib/assets/docs/article/practical-database-design/part2/chapter08.md +0 -2114
  564. package/lib/assets/docs/article/practical-database-design/part2/chapter09.md +0 -2040
  565. package/lib/assets/docs/article/practical-database-design/part2/chapter10.md +0 -1396
  566. package/lib/assets/docs/article/practical-database-design/part2/chapter11.md +0 -1686
  567. package/lib/assets/docs/article/practical-database-design/part2/chapter12.md +0 -1426
  568. package/lib/assets/docs/article/practical-database-design/part2/chapter13.md +0 -1443
  569. package/lib/assets/docs/article/practical-database-design/part3/chapter14.md +0 -676
  570. package/lib/assets/docs/article/practical-database-design/part3/chapter15.md +0 -1634
  571. package/lib/assets/docs/article/practical-database-design/part3/chapter16.md +0 -1924
  572. package/lib/assets/docs/article/practical-database-design/part3/chapter17.md +0 -1717
  573. package/lib/assets/docs/article/practical-database-design/part3/chapter18.md +0 -2104
  574. package/lib/assets/docs/article/practical-database-design/part3/chapter19.md +0 -1132
  575. package/lib/assets/docs/article/practical-database-design/part3/chapter20.md +0 -1040
  576. package/lib/assets/docs/article/practical-database-design/part3/chapter21.md +0 -1391
  577. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter14-orm.md +0 -1000
  578. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter15-orm.md +0 -1309
  579. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter16-orm.md +0 -1175
  580. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter17-orm.md +0 -1593
  581. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter18-orm.md +0 -1192
  582. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter19-orm.md +0 -1025
  583. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter20-orm.md +0 -1762
  584. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter21-orm.md +0 -1456
  585. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter22-orm.md +0 -1887
  586. package/lib/assets/docs/article/practical-database-design/part4/chapter22.md +0 -974
  587. package/lib/assets/docs/article/practical-database-design/part4/chapter23.md +0 -2078
  588. package/lib/assets/docs/article/practical-database-design/part4/chapter24.md +0 -2448
  589. package/lib/assets/docs/article/practical-database-design/part4/chapter25.md +0 -3670
  590. package/lib/assets/docs/article/practical-database-design/part4/chapter26.md +0 -2925
  591. package/lib/assets/docs/article/practical-database-design/part4/chapter27.md +0 -3114
  592. package/lib/assets/docs/article/practical-database-design/part4/chapter28.md +0 -2706
  593. package/lib/assets/docs/article/practical-database-design/part4/chapter29.md +0 -2552
  594. package/lib/assets/docs/article/practical-database-design/part4/chapter30.md +0 -2188
  595. package/lib/assets/docs/article/practical-database-design/part4/chapter31.md +0 -1200
  596. package/lib/assets/docs/article/practical-database-design/part4/chapter32.md +0 -2109
  597. package/lib/assets/docs/article/practical-database-design/part5/chapter33.md +0 -1041
  598. package/lib/assets/docs/article/practical-database-design/part5/chapter34.md +0 -1618
  599. package/lib/assets/docs/article/practical-database-design/part5/chapter35.md +0 -1462
  600. package/lib/assets/docs/article/practical-database-design/part5/chapter36.md +0 -1301
  601. package/lib/assets/docs/article/practical-database-design/part5/chapter37.md +0 -1479
  602. package/lib/assets/docs/article/practical-database-design/part5/chapter38.md +0 -1707
  603. package/lib/assets/docs/article/practical-database-design/part5/chapter39.md +0 -2343
  604. package/lib/assets/docs/article/practical-database-design/study/study2-1.md +0 -1702
  605. package/lib/assets/docs/article/practical-database-design/study/study2-2.md +0 -1356
  606. package/lib/assets/docs/article/practical-database-design/study/study2-3.md +0 -2053
  607. package/lib/assets/docs/article/practical-database-design/study/study2-4.md +0 -2238
  608. package/lib/assets/docs/article/practical-database-design/study/study2-5.md +0 -2427
  609. package/lib/assets/docs/article/practical-database-design/study/study3-1.md +0 -2214
  610. package/lib/assets/docs/article/practical-database-design/study/study3-2.md +0 -2230
  611. package/lib/assets/docs/article/practical-database-design/study/study3-3.md +0 -2262
  612. package/lib/assets/docs/article/practical-database-design/study/study3-4.md +0 -2115
  613. package/lib/assets/docs/article/practical-database-design/study/study3-5.md +0 -2516
  614. package/lib/assets/docs/article/practical-database-design/study/study4-1.md +0 -2596
  615. package/lib/assets/docs/article/practical-database-design/study/study4-2.md +0 -2084
  616. package/lib/assets/docs/article/practical-database-design/study/study4-3.md +0 -1814
  617. package/lib/assets/docs/article/practical-database-design/study/study4-4.md +0 -1904
  618. package/lib/assets/docs/article/practical-database-design/study/study4-5.md +0 -2887
@@ -1,640 +0,0 @@
1
- ---
2
- type: Article
3
- title: "第 10 章 最適なコンテナイメージ作成と運用"
4
- description: "前章までで、コンテナ化したアプリケーションを Kubernetes 上で動かし、パッケージングして配布するところまでを学びました。"
5
- tags: [article, getting-start-docker-kubernetes]
6
- status: stable
7
- generated: { by: human:kakimomokuri, at: 2026-06-26T00:29:42Z }
8
- ---
9
-
10
- # 第 10 章 最適なコンテナイメージ作成と運用
11
-
12
- ![最適なコンテナイメージ作成を説明する 4 コマ漫画](images/chapter-10-comic.png)
13
-
14
- *小さなベース、Multi-stage build、非 root 実行、脆弱性スキャンで安全で扱いやすいイメージを作ります。*
15
-
16
- ## はじめに
17
-
18
- 前章までで、コンテナ化したアプリケーションを Kubernetes 上で動かし、パッケージングして配布するところまでを学びました。アプリケーションが「動く」ようになったら、次に向き合うべきは「どう運用するか」です。
19
-
20
- 開発の初期段階では、とにかく動くコンテナイメージを素早く作ることが優先されます。しかし、そのイメージを本番環境で長期間運用しはじめると、別の側面が重要になってきます。イメージが大きすぎてデプロイに時間がかかる、古いライブラリに脆弱性が見つかる、root 権限で動いていてセキュリティ上のリスクがある、といった問題です。
21
-
22
- この章では、開発時の「とりあえず動く」イメージを、運用に耐える「最適な」イメージへと洗練させていく過程を学びます。題材には、Go 製の小さな Web サーバである `echo` と `image-bootstrap` の 2 つのサンプルリポジトリ、そして書籍旧版のサンプルコード(`gihyo-docker-kuberbetes/ch10`)を使います。実際の Dockerfile を段階的に引用しながら、軽量化・セキュア化・CI による自動化を見ていきます。
23
-
24
- ### 目次
25
-
26
- 1. [運用に最適なコンテナイメージとは](#101-運用に最適なコンテナイメージとは)
27
- 2. [軽量なベースイメージ](#102-軽量なベースイメージ)
28
- 3. [軽量なコンテナイメージを作る](#103-軽量なコンテナイメージを作る)
29
- 4. [Multi-stage builds](#104-multi-stage-builds)
30
- 5. [BuildKit](#105-buildkit)
31
- 6. [セキュアなコンテナイメージの利用と作成](#106-セキュアなコンテナイメージの利用と作成)
32
- 7. [CI ツールでコンテナイメージをビルドする](#107-ci-ツールでコンテナイメージをビルドする)
33
-
34
- ---
35
-
36
- ## 10.1 運用に最適なコンテナイメージとは
37
-
38
- 「最適なコンテナイメージ」とは何でしょうか。コンテナの世界では、漠然と「良いイメージ」を語るのではなく、評価できる基準を持つことが大切です。本章では、最適なイメージを次の 4 つの基準で捉えます。
39
-
40
- ### 小さい(サイズ)
41
-
42
- イメージが小さいほど、レジストリへの push、レジストリからの pull、ノードへの展開がすべて速くなります。Kubernetes のように多数のノードへ同じイメージを配布する環境では、サイズの差がデプロイ全体の所要時間に直結します。ディスクやネットワーク帯域の節約にもなります。
43
-
44
- ### 速い(ビルド・起動)
45
-
46
- ビルドが速いと開発のフィードバックループが短くなります。レイヤキャッシュを活かし、変わらない部分を再ビルドしない工夫が効きます。また、余計なプロセスやシェルを含まない小さなイメージは起動も速く、スケールアウト時の応答性を高めます。
47
-
48
- ### 安全(セキュリティ)
49
-
50
- イメージに含まれるパッケージが少ないほど、攻撃対象領域(アタックサーフェス)は小さくなります。シェルやパッケージマネージャを含まないイメージは、侵入されても攻撃者が次の手を打ちにくくなります。さらに、root ではなく非 root ユーザで実行する、脆弱性スキャンで既知の CVE を検知する、といった対策が求められます。
51
-
52
- ### 再現性(リプロデューシビリティ)
53
-
54
- 「いつビルドしても同じ結果になる」ことは運用上きわめて重要です。ベースイメージのタグを `latest` ではなく固定する、ビルド手順をコード(Dockerfile)として管理する、CI で自動ビルドして人手のばらつきを排除する、といった取り組みが再現性を支えます。
55
-
56
- これらの基準は、本連載で繰り返し参照している「よいソフトウェアとは変更を楽に安全にできて役に立つソフトウェアである」という考え方とも一致します。小さく安全で再現性のあるイメージは、変更を楽に安全に届けるための土台です。
57
-
58
- ```plantuml
59
- @startmindmap
60
- title 最適なコンテナイメージの 4 基準
61
-
62
- * 最適なイメージ
63
- ** 小さい
64
- *** push / pull が速い
65
- *** ディスク・帯域の節約
66
- ** 速い
67
- *** ビルドキャッシュ活用
68
- *** 起動が速い
69
- ** 安全
70
- *** 攻撃対象領域が小さい
71
- *** 非 root 実行
72
- *** 脆弱性スキャン
73
- ** 再現性
74
- *** タグ固定
75
- *** Dockerfile で管理
76
- *** CI で自動化
77
- @endmindmap
78
- ```
79
-
80
- 以降の節では、この 4 基準を 1 つずつ具体的な手法に落とし込んでいきます。
81
-
82
- ---
83
-
84
- ## 10.2 軽量なベースイメージ
85
-
86
- イメージのサイズを決める最大の要因は、ベースイメージの選択です。同じアプリケーションでも、ベースに何を選ぶかでサイズは大きく変わります。
87
-
88
- ### 汎用 OS イメージは大きい
89
-
90
- 旧版サンプル `gihyo-docker-kuberbetes/ch10/ch10_1_1/Dockerfile` は、汎用的な Ubuntu をベースに各種ツールをインストールする例です。
91
-
92
- ```dockerfile
93
- FROM ubuntu:16.04
94
-
95
- RUN apt -y update
96
- RUN apt -y install net-tools \
97
- iproute2 \
98
- inetutils-ping \
99
- iproute2 \
100
- tcpdump \
101
- mycli \
102
- redis-tools
103
- ```
104
-
105
- このようなイメージはデバッグ用途には便利ですが、フルセットの OS をベースにしているため数百 MB に達します。アプリケーション本体だけを動かしたい運用用イメージには大きすぎます。
106
-
107
- ### 軽量ベースイメージの選択肢
108
-
109
- 運用向けには、より小さなベースイメージを選びます。代表的な選択肢を整理します。
110
-
111
- | ベース | 特徴 | シェル / パッケージマネージャ | 主な用途 |
112
- |--------|------|------------------------------|----------|
113
- | `alpine` | musl libc ベースで数 MB | あり(`apk`) | 汎用・軽量 |
114
- | `*-slim`(debian-slim 等) | 通常版から不要物を削った版 | あり(`apt`) | glibc が必要なとき |
115
- | `distroless` | OS パッケージを含まず実行に必要な最小限のみ | なし | 静的バイナリの実行 |
116
- | `scratch` | 完全な空 | なし | 完全静的バイナリ |
117
-
118
- ### Alpine Linux
119
-
120
- `alpine` は数 MB と非常に小さく、`apk` パッケージマネージャを備えています。旧版サンプル `gihyo-docker-kuberbetes/ch10/ch10_2_1/Dockerfile` は Alpine 上に `jq` を導入する例です。
121
-
122
- ```dockerfile
123
- FROM alpine:3.7
124
-
125
- RUN apk add --no-cache --virtual=build-deps wget && \
126
- wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && \
127
- mv jq-linux64 /usr/local/bin/jq && \
128
- chmod +x /usr/local/bin/jq && \
129
- apk del build-deps
130
-
131
- ENTRYPOINT ["/usr/local/bin/jq", "-C"]
132
- CMD [""]
133
- ```
134
-
135
- ここでのポイントは、ダウンロードにだけ必要な `wget` を `--virtual=build-deps` という仮想パッケージグループとしてまとめ、用が済んだら `apk del build-deps` で削除している点です。これにより、ビルドにのみ必要なツールを最終イメージに残しません。`--no-cache` は `apk` のキャッシュを残さないオプションで、これもサイズ削減に効きます。
136
-
137
- ### distroless
138
-
139
- `distroless` は Google が提供するベースイメージ群で、アプリケーションの実行に必要な共有ライブラリと CA 証明書などだけを含み、シェルもパッケージマネージャも含みません。Go のような静的にコンパイルできる言語と相性がよく、本章後半で `echo` と `image-bootstrap` の最終イメージに採用します。シェルがないため、侵入されても攻撃者ができることが極端に限られます。
140
-
141
- ベースイメージの選択は、「実行に本当に必要なものは何か」を問い直す作業でもあります。デバッグツールが欲しくなるのは分かりますが、運用イメージにはそれを含めず、必要なら別のデバッグ用イメージ(後述)を使い分けるのが定石です。
142
-
143
- ---
144
-
145
- ## 10.3 軽量なコンテナイメージを作る
146
-
147
- ベースイメージを軽くしたら、次は Dockerfile の書き方そのものでサイズとビルド時間を削っていきます。Docker イメージはレイヤの積み重ねでできており、各命令(`RUN` `COPY` など)が 1 レイヤを生みます。レイヤをどう構成するかがサイズに直結します。
148
-
149
- ### RUN をまとめてレイヤを減らす
150
-
151
- 10.2 で引用した `ch10_2_1/Dockerfile` をもう一度見てください。`wget` のインストール・ダウンロード・配置・不要パッケージの削除を、`&&` でつないで 1 つの `RUN` にまとめています。
152
-
153
- ```dockerfile
154
- RUN apk add --no-cache --virtual=build-deps wget && \
155
- wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && \
156
- mv jq-linux64 /usr/local/bin/jq && \
157
- chmod +x /usr/local/bin/jq && \
158
- apk del build-deps
159
- ```
160
-
161
- これを別々の `RUN` に分けてしまうと問題が起きます。Docker のレイヤは追記方式なので、あるレイヤで作ったファイルを後のレイヤで削除しても、前のレイヤにはファイルが残ったままになり、イメージサイズは減りません。`apk del build-deps` を `apk add` と同じ `RUN` 内で実行しているのは、この性質を踏まえてのことです。一連の「導入してから片付ける」処理は 1 つの `RUN` にまとめるのが鉄則です。
162
-
163
- 逆に、`ch10_1_1/Dockerfile` のように `RUN apt -y update` と `RUN apt -y install ...` を分けると、`apt` のインデックスキャッシュが中間レイヤに残りやすく、サイズ面でも不利になります。
164
-
165
- ### 不要ファイルを削除する
166
-
167
- `apk` の `--no-cache`、`apt` での `rm -rf /var/lib/apt/lists/*` のように、パッケージマネージャが残すキャッシュやインデックスは明示的に削除します。ビルドにのみ必要なツール(コンパイラ、`wget` など)も、最終イメージには残さないようにします。これらをすべて同一 `RUN` 内で完結させるのがポイントです。
168
-
169
- ### .dockerignore でビルドコンテキストを絞る
170
-
171
- `docker build` は、カレントディレクトリ(ビルドコンテキスト)一式を Docker デーモンへ送ります。`.git` やローカルのビルド成果物、ログなどが含まれていると、転送に時間がかかるうえ、`COPY . .` で不要なファイルをイメージに取り込んでしまう恐れがあります。
172
-
173
- `.dockerignore` ファイルを用意して、コンテキストから除外する対象を指定します。次は典型的な例です。
174
-
175
- ```bash
176
- # .dockerignore の例
177
- .git
178
- *.md
179
- bin/
180
- node_modules/
181
- *.log
182
- ```
183
-
184
- これにより、ビルドが速くなり、機密情報や巨大ファイルの混入も防げます。`image-bootstrap` リポジトリにも `.gitignore` が用意されており、ビルド成果物などをバージョン管理から外す方針が取られています。同様の発想で `.dockerignore` を整えるとよいでしょう。
185
-
186
- ### レイヤキャッシュを活かす
187
-
188
- Docker は各レイヤをキャッシュし、命令と入力が変わらなければ再利用します。変更頻度の低いものを Dockerfile の上の方に、変更頻度の高いもの(アプリのソースなど)を下の方に置くと、キャッシュが効きやすくなります。たとえば依存関係の定義ファイルを先に `COPY` して依存だけ先に解決し、その後でソース全体を `COPY` する、という順序が定番です。
189
-
190
- ### COPY したスクリプトを使う例
191
-
192
- `ch10_2_2/Dockerfile` は `ch10_2_1` を発展させ、ローカルのシェルスクリプトをイメージに取り込んでエントリポイントにする例です。
193
-
194
- ```dockerfile
195
- FROM alpine:3.7
196
-
197
- RUN apk add --no-cache --virtual=build-deps wget && \
198
- wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && \
199
- mv jq-linux64 /usr/local/bin/jq && \
200
- chmod +x /usr/local/bin/jq && \
201
- apk del build-deps
202
-
203
- COPY show-attr.sh /usr/local/bin/
204
-
205
- ENTRYPOINT ["sh", "/usr/local/bin/show-attr.sh"]
206
- CMD [""]
207
- ```
208
-
209
- 取り込まれる `show-attr.sh`(`gihyo-docker-kuberbetes/ch10/ch10_2_2/show-attr.sh`)は、引数で渡された属性名を JSON から `jq` で取り出す小さなスクリプトです。
210
-
211
- ```bash
212
- #!/bin/bash
213
-
214
- ATTR=$1
215
- if [ "$ATTR" = "" ]; then
216
- echo "required attribute name argument" 1>&2
217
- exit 1
218
- fi
219
-
220
- echo '{
221
- "id": 100,
222
- "username": "gihyo",
223
- "comment": "I like Alpine Linux"
224
- }' | jq -r ".$ATTR"
225
- ```
226
-
227
- アプリケーション本体(ここでは `jq` とスクリプト)だけを最小のベースに載せる、という構成が見て取れます。とはいえ、Alpine にはまだシェルが含まれています。アプリがシェルすら必要としないなら、次節の Multi-stage builds と distroless でさらに削ぎ落とせます。
228
-
229
- ---
230
-
231
- ## 10.4 Multi-stage builds
232
-
233
- ここまでの工夫を一気に進めるのが Multi-stage builds(マルチステージビルド)です。1 つの Dockerfile の中に複数の `FROM`(ステージ)を書き、ビルド用ステージで成果物を作り、その成果物だけを最終ステージへコピーします。ビルドに必要なコンパイラや依存物は最終イメージに一切残りません。
234
-
235
- ### ビルドツールを含んだ素朴なイメージ
236
-
237
- まず、`echo` リポジトリの素朴版 `apps/echo/Dockerfile` を見ます。
238
-
239
- ```dockerfile
240
- FROM golang:1.21.6
241
-
242
- LABEL org.opencontainers.image.source=https://github.com/gihyodocker/echo
243
-
244
- WORKDIR /go/src/github.com/gihyodocker/echo
245
- COPY main.go .
246
- RUN go mod init
247
-
248
- CMD ["go", "run", "main.go"]
249
- ```
250
-
251
- これは `golang:1.21.6` をそのまま実行イメージにしています。`go run` でソースからその場でビルドして起動するため、最終イメージに Go ツールチェーン一式(コンパイラ、標準ライブラリのソースなど)が丸ごと含まれます。`golang` の公式イメージは数百 MB 規模で、実行に不要なものばかりです。手軽ですが運用には重すぎます。
252
-
253
- ### Multi-stage で成果物だけを残す
254
-
255
- これを最適化したのが `apps/echo/Dockerfile.slim` です。
256
-
257
- ```dockerfile
258
- FROM --platform=$TARGETPLATFORM golang:1.21.6 AS build
259
- ARG TARGETARCH
260
-
261
- WORKDIR /go/src/github.com/gihyodocker/echo
262
- COPY . .
263
-
264
- RUN GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -o bin/echo main.go
265
-
266
- FROM gcr.io/distroless/base-debian11:latest
267
- LABEL org.opencontainers.image.source=https://github.com/gihyodocker/echo
268
-
269
- COPY --from=build /go/src/github.com/gihyodocker/echo/bin/echo /usr/local/bin/
270
-
271
- CMD ["echo"]
272
- ```
273
-
274
- この Dockerfile は 2 つのステージに分かれています。
275
-
276
- 1. **build ステージ**(`FROM golang:1.21.6 AS build`): Go のツールチェーンを使って `go build` を実行し、実行可能バイナリ `bin/echo` を生成します。`CGO_ENABLED=0` を指定して C 依存を切り、静的にリンクされた単一バイナリを作るのがポイントです。これにより、distroless のような最小ベースでも動かせます。
277
- 2. **最終ステージ**(`FROM gcr.io/distroless/base-debian11:latest`): distroless ベースに、`COPY --from=build` で build ステージのバイナリ `echo` だけを取り込みます。Go ツールチェーンもソースも入りません。
278
-
279
- ### サイズ差を理解する
280
-
281
- 両者の違いは、最終イメージに何が入るかです。
282
-
283
- | Dockerfile | ベース | 最終イメージに含まれるもの | 傾向 |
284
- |------------|--------|---------------------------|------|
285
- | `apps/echo/Dockerfile` | `golang:1.21.6` | Go ツールチェーン + ソース + `go run` | 非常に大きい(数百 MB 規模) |
286
- | `apps/echo/Dockerfile.slim` | `distroless/base-debian11` | 静的バイナリ `echo` のみ | 非常に小さい |
287
-
288
- > 注: 正確なサイズは Go のバージョンや環境で変わるため、実際の値は `docker images` で確認してください。一般に、Go ツールチェーンを含むイメージは数百 MB に達するのに対し、distroless にバイナリだけを載せたイメージは桁違いに小さくなります。
289
-
290
- ```plantuml
291
- @startuml
292
- title Multi-stage builds(apps/echo/Dockerfile.slim)
293
-
294
- rectangle "build ステージ\n(golang:1.21.6)" as B {
295
- card "COPY . ." as src
296
- card "go build -o bin/echo" as build
297
- }
298
-
299
- rectangle "最終ステージ\n(distroless/base-debian11)" as F {
300
- card "echo バイナリのみ" as bin
301
- }
302
-
303
- src --> build
304
- build --> bin : COPY --from=build\n(成果物のみ)
305
- @enduml
306
- ```
307
-
308
- Multi-stage builds は、「ビルドに必要なもの」と「実行に必要なもの」を分離する、シンプルで強力な発想です。10.1 で挙げた「小さい」「速い」「安全」の 3 基準を一度に満たせます。
309
-
310
- ---
311
-
312
- ## 10.5 BuildKit
313
-
314
- Multi-stage builds をはじめとする近代的なビルド機能を支えているのが BuildKit です。BuildKit は Docker の次世代ビルドエンジンで、並列ビルド、効率的なキャッシュ、マルチプラットフォームビルドなどに対応します。
315
-
316
- ### BuildKit を有効にする
317
-
318
- 環境変数 `DOCKER_BUILDKIT=1` を付けると、従来の `docker build` でも BuildKit が使われます。
319
-
320
- ```bash
321
- DOCKER_BUILDKIT=1 docker build -t echo:slim -f Dockerfile.slim .
322
- ```
323
-
324
- より高機能なフロントエンドが `docker buildx` です。マルチプラットフォームビルドやキャッシュのインポート/エクスポートを扱えます。
325
-
326
- ```bash
327
- # buildx 用のビルダーを用意して有効化(例)
328
- docker buildx create --use
329
-
330
- # マルチプラットフォーム向けにビルドして push(例)
331
- docker buildx build \
332
- --platform linux/amd64,linux/arm64 \
333
- -f Dockerfile.slim \
334
- -t ghcr.io/gihyodocker/echo:slim \
335
- --push .
336
- ```
337
-
338
- ### マルチプラットフォームビルド
339
-
340
- `apps/echo/Dockerfile.slim` と `apps/image-bootstrap/Dockerfile` には、マルチプラットフォーム対応のための仕掛けが入っています。再掲します。
341
-
342
- ```dockerfile
343
- FROM --platform=$TARGETPLATFORM golang:1.21.6 AS build
344
- ARG TARGETARCH
345
-
346
- WORKDIR /go/src/github.com/gihyodocker/echo
347
- COPY . .
348
-
349
- RUN GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -o bin/echo main.go
350
- ```
351
-
352
- ここで使われている `$TARGETPLATFORM` や `$TARGETARCH` は、BuildKit がビルド時に自動で渡してくれる変数です。
353
-
354
- - `$TARGETPLATFORM`: ビルド対象のプラットフォーム(例: `linux/amd64`、`linux/arm64`)
355
- - `$TARGETARCH`: 対象アーキテクチャ(例: `amd64`、`arm64`)
356
-
357
- `GOARCH=${TARGETARCH}` を指定することで、Go のクロスコンパイル機能を使い、対象アーキテクチャ向けのバイナリを生成しています。これにより、1 度の `buildx` 実行で amd64 と arm64 の両方のイメージを作れます。Intel/AMD のサーバと Apple Silicon や ARM サーバが混在する現代では、この対応がほぼ必須になっています。
358
-
359
- `apps/image-bootstrap/Dockerfile` の build ステージでは `--platform=$BUILDPLATFORM` を使っています。これは「ビルドを実行しているマシンのネイティブプラットフォーム」を指し、ビルドホスト上でクロスコンパイルする(エミュレーションを避けて高速化する)狙いがあります。`$BUILDPLATFORM` でビルドし、`GOARCH` で出力先アーキテクチャを切り替えるのが、Go におけるマルチプラットフォームビルドの定石です。
360
-
361
- ### キャッシュの活用
362
-
363
- BuildKit はレイヤキャッシュをレジストリにエクスポート/インポートできます。CI のように毎回まっさらな環境でビルドする場合でも、前回のキャッシュを取り込んでビルドを高速化できます。実例は 10.7 の CI で見ます。
364
-
365
- また、`RUN` 命令にキャッシュマウントを指定すると、パッケージのダウンロードキャッシュやコンパイルキャッシュをレイヤに残さずに再利用できます。これも BuildKit ならではの機能です。
366
-
367
- ```dockerfile
368
- # キャッシュマウントの例(Go モジュールのダウンロードキャッシュを再利用)
369
- RUN --mount=type=cache,target=/go/pkg/mod \
370
- GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -o bin/echo main.go
371
- ```
372
-
373
- > 注: 上記はキャッシュマウントの一般的な書き方の例です。サンプルリポジトリの Dockerfile では使われていませんが、ビルド時間が問題になる場合の選択肢として覚えておくと役立ちます。
374
-
375
- ---
376
-
377
- ## 10.6 セキュアなコンテナイメージの利用と作成
378
-
379
- イメージを小さくすると、攻撃対象領域が減るという意味でセキュリティ面でも有利になります。しかし、それだけでは不十分です。この節では、非 root 実行と脆弱性スキャンという 2 つの柱を、`image-bootstrap` リポジトリのサンプルで具体的に見ます。
380
-
381
- ### 非 root ユーザで実行する(最小権限の原則)
382
-
383
- コンテナはデフォルトで root として実行されます。万が一コンテナが乗っ取られた場合、root だとホストへの影響範囲が広がりかねません。最小権限の原則に従い、アプリは必要最小限の権限を持つ非 root ユーザで動かすべきです。
384
-
385
- `apps/image-bootstrap/Dockerfile` は、distroless の nonroot バリアントと `USER` 指定を組み合わせて、非 root 実行を実現しています。
386
-
387
- ```dockerfile
388
- FROM --platform=$BUILDPLATFORM golang:1.21.6 AS build
389
- ARG TARGETARCH
390
-
391
- WORKDIR /go/src/github.com/gihyodocker/image-bootstrap
392
- COPY . .
393
-
394
- RUN GOARCH=${TARGETARCH} go build -o bin/server main.go
395
-
396
- FROM gcr.io/distroless/base-debian11:nonroot
397
- LABEL org.opencontainers.image.source=https://github.com/gihyodocker/image-bootstrap
398
-
399
- COPY --from=build --chown=nonroot:nonroot /go/src/github.com/gihyodocker/image-bootstrap/bin/server /usr/local/bin/
400
-
401
- USER nonroot
402
-
403
- CMD ["server"]
404
- ```
405
-
406
- セキュリティ上の要点は 3 つです。
407
-
408
- 1. **`distroless/base-debian11:nonroot`**: distroless の `nonroot` タグは、あらかじめ `nonroot` ユーザが用意されたバリアントです。シェルもパッケージマネージャも含まないため、侵入されても攻撃者が打てる手は限られます。
409
- 2. **`COPY --chown=nonroot:nonroot`**: build ステージから成果物をコピーする際に、所有者を `nonroot` ユーザに設定します。これにより、`nonroot` ユーザがバイナリを実行できるようになります。
410
- 3. **`USER nonroot`**: 以降のプロセスを `nonroot` ユーザとして実行するよう宣言します。コンテナ起動時の `server` プロセスは root ではなく `nonroot` で動きます。
411
-
412
- なお、このサンプルが動かす `apps/image-bootstrap/main.go` は、ポート 8080 で待ち受ける小さな HTTP サーバです。1024 番未満の特権ポートを使わないため、非 root ユーザでも問題なく待ち受けできます。非 root 実行を前提にするなら、こうした設計(特権ポートを避ける)も合わせて意識します。
413
-
414
- ### 脆弱性管理(Trivy によるスキャン)
415
-
416
- イメージに含まれるパッケージには、後から脆弱性(CVE)が見つかることがあります。そこで、イメージやソースを定期的にスキャンして既知の脆弱性を検知する仕組みが必要です。`image-bootstrap` では Trivy を使っています。
417
-
418
- Trivy の設定ファイル `apps/image-bootstrap/trivy.yaml` は次の通りです。
419
-
420
- ```yaml
421
- scan:
422
- scanners:
423
- - vuln
424
- - config
425
- - secret
426
- ```
427
-
428
- 3 種類のスキャナを有効にしています。
429
-
430
- - **`vuln`**: OS パッケージや言語ライブラリの既知の脆弱性(CVE)を検出します。
431
- - **`config`**: Dockerfile や Kubernetes マニフェストなどの設定ミス(IaC の誤り)を検出します。たとえば root 実行のままになっていないか、といったチェックです。
432
- - **`secret`**: ソースやイメージにハードコードされた認証情報やトークン(シークレット)の混入を検出します。
433
-
434
- この 1 つの設定で、「脆弱なライブラリ」「危険な設定」「秘密情報の漏洩」という 3 つの観点を一度にカバーできます。スキャンは CI に組み込んで自動化するのが理想で、その実例は次節で見ます。
435
-
436
- ### セキュアなイメージの考え方
437
-
438
- セキュアなイメージ作りは、特別な魔法ではなく、地道な原則の積み重ねです。
439
-
440
- - 含めるものを最小限にする(distroless / 軽量ベース)
441
- - 最小権限で動かす(非 root、特権ポートを避ける)
442
- - 既知の脆弱性を継続的に監視する(Trivy 等のスキャンを自動化)
443
- - ベースイメージを定期的に更新し、タグは固定して再現性を保つ
444
-
445
- これらは 10.1 の「安全」「再現性」の基準を具体化したものです。一度設定して終わりではなく、CI に組み込んで継続的に回すことが肝心です。
446
-
447
- ---
448
-
449
- ## 10.7 CI ツールでコンテナイメージをビルドする
450
-
451
- イメージの軽量化・セキュア化を手作業で毎回行うのは現実的ではありません。Dockerfile に書いた工夫を確実に・再現性をもって適用するには、CI(継続的インテグレーション)でビルドを自動化します。ここでは GitHub Actions を使い、`echo` と `image-bootstrap` の 2 つのワークフローを見ます。
452
-
453
- ### echo: 複数バリアントを buildx でビルドして push する
454
-
455
- `apps/echo/.github/workflows/push-image.yml` は、main ブランチへの push と `v*` タグの付与をトリガに、複数のイメージバリアントをビルドして GitHub Container Registry(ghcr.io)へ push します。
456
-
457
- ```yaml
458
- name: Push the container image
459
-
460
- on:
461
- push:
462
- branches:
463
- - main
464
- tags:
465
- - 'v*'
466
-
467
- env:
468
- CONTAINER_REGISTRY: ghcr.io
469
-
470
- jobs:
471
- push_image:
472
- runs-on: ubuntu-latest
473
- permissions:
474
- contents: read
475
- packages: write
476
- steps:
477
- - uses: actions/checkout@v4
478
- with:
479
- fetch-depth: 0
480
- - name: Calculate the version
481
- run: echo "IMAGE_VERSION=$(git describe --tags --always)" >> $GITHUB_ENV
482
- - uses: docker/setup-qemu-action@v3
483
- - uses: docker/setup-buildx-action@v3
484
- - uses: docker/login-action@v3
485
- with:
486
- registry: ghcr.io
487
- username: ${{ github.actor }}
488
- password: ${{ secrets.GITHUB_TOKEN }}
489
- - name: Build and push plain image
490
- uses: docker/build-push-action@v5
491
- with:
492
- context: .
493
- push: true
494
- platforms: linux/amd64,linux/arm64
495
- tags: ${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:${{ env.IMAGE_VERSION }}
496
- - name: Build and push slim image
497
- uses: docker/build-push-action@v5
498
- with:
499
- context: .
500
- file: Dockerfile.slim
501
- push: true
502
- platforms: linux/amd64,linux/arm64
503
- tags: ${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:${{ env.IMAGE_VERSION }}-slim
504
- - name: Build and push debug image
505
- uses: docker/build-push-action@v5
506
- with:
507
- context: .
508
- file: Dockerfile.debug
509
- push: true
510
- platforms: linux/amd64,linux/arm64
511
- tags: ${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:${{ env.IMAGE_VERSION }}-debug
512
- ```
513
-
514
- このワークフローの流れを追ってみます。
515
-
516
- 1. **トリガと権限**: `on.push` で main ブランチと `v*` タグを対象にし、`permissions` で `packages: write`(レジストリへの書き込み)を最小限だけ許可します。権限も最小権限の原則に従います。
517
- 2. **バージョン算出**: `git describe --tags --always` で Git のタグやコミットからバージョン文字列を作り、`IMAGE_VERSION` に格納します。これをイメージタグに使うことで、どのコミットから作られたイメージかが追跡でき、再現性が高まります。
518
- 3. **buildx の準備**: `setup-qemu-action` でエミュレーションを、`setup-buildx-action` で BuildKit ベースのビルダーを用意します。これでマルチプラットフォームビルドが可能になります。
519
- 4. **レジストリへのログイン**: `login-action` で `GITHUB_TOKEN` を使い ghcr.io にログインします。
520
- 5. **3 種のイメージをビルド・push**: `docker/build-push-action` を 3 回呼び、`platforms: linux/amd64,linux/arm64` で 2 アーキテクチャ分を一度に作ります。
521
-
522
- - plain(`Dockerfile`): タグ `:バージョン`
523
- - slim(`Dockerfile.slim`): タグ `:バージョン-slim`
524
- - debug(`Dockerfile.debug`): タグ `:バージョン-debug`
525
-
526
- slim が運用用の最小イメージ、debug は distroless の `debug` バリアント(シェルを含む)を使った調査用イメージで、用途に応じて使い分けられるようになっています。10.2 で「デバッグツールは別イメージに分ける」と述べた方針が、ここで実装されています。
527
-
528
- ### image-bootstrap: ビルド前に Trivy スキャンとキャッシュを組み込む
529
-
530
- `apps/image-bootstrap/.github/workflows/push-image.yml` は、`echo` のワークフローに「脆弱性スキャン」と「ビルドキャッシュ」を加えた、よりセキュアで効率的な構成です。
531
-
532
- ```yaml
533
- name: Push the container image
534
-
535
- on:
536
- push:
537
- branches:
538
- - main
539
- tags:
540
- - 'v*'
541
-
542
- env:
543
- CONTAINER_REGISTRY: ghcr.io
544
-
545
- jobs:
546
- push_image:
547
- runs-on: ubuntu-latest
548
- permissions:
549
- contents: read
550
- packages: write
551
- steps:
552
- - uses: actions/checkout@v4
553
- with:
554
- fetch-depth: 0
555
- - name: Calculate the version
556
- run: echo "IMAGE_VERSION=$(git describe --tags --always)" >> $GITHUB_ENV
557
- - uses: docker/setup-qemu-action@v3
558
- - uses: docker/setup-buildx-action@v3
559
- - uses: docker/login-action@v3
560
- with:
561
- registry: ghcr.io
562
- username: ${{ github.actor }}
563
- password: ${{ secrets.GITHUB_TOKEN }}
564
- - name: Run Trivy vulnerability scanner in fs mode
565
- uses: aquasecurity/trivy-action@0.16.0
566
- with:
567
- scan-type: 'fs'
568
- scan-ref: '.'
569
- trivy-config: trivy.yaml
570
- - name: Build and push plain image
571
- uses: docker/build-push-action@v5
572
- with:
573
- context: .
574
- push: true
575
- platforms: linux/amd64,linux/arm64
576
- tags: ${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:${{ env.IMAGE_VERSION }}
577
- cache-to: type=registry,ref=${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:cache,mode=max
578
- cache-from: type=registry,ref=${{ env.CONTAINER_REGISTRY }}/${{ github.repository }}:cache
579
- ```
580
-
581
- `echo` のワークフローとの違いは 2 点です。
582
-
583
- 1. **Trivy スキャンをビルド前に実行**: `aquasecurity/trivy-action` を `scan-type: 'fs'`(ファイルシステムモード)で実行し、`trivy-config: trivy.yaml` で 10.6 の設定(`vuln` / `config` / `secret`)を読み込みます。ビルドより前にスキャンを置くことで、脆弱性や設定ミス、シークレットの混入を検知した段階で、危険なイメージを push する前に止められます。
584
- 2. **レジストリキャッシュの活用**: `cache-to` と `cache-from` で、ビルドキャッシュを ghcr.io の `:cache` タグにエクスポート/インポートします。`mode=max` は中間レイヤも含めてキャッシュする設定です。CI 実行ごとに環境がまっさらでも、前回のキャッシュを取り込んでビルドを高速化できます。10.5 で触れた BuildKit のキャッシュ機能を、CI で実用化した形です。
585
-
586
- ```plantuml
587
- @startuml
588
- title CI でのセキュアなイメージビルド(image-bootstrap)
589
-
590
- start
591
- :push(main / v* タグ);
592
- :checkout;
593
- :バージョン算出\n(git describe);
594
- :buildx 準備\n(qemu + buildx);
595
- :ghcr.io ログイン;
596
- :Trivy スキャン\n(vuln / config / secret);
597
- if (脆弱性・設定ミス・\nシークレットを検知?) then (はい)
598
- :ビルド中止;
599
- stop
600
- else (いいえ)
601
- endif
602
- :buildx でビルド\n(amd64 / arm64);
603
- :レジストリキャッシュ\n利用 (cache-from/to);
604
- :ghcr.io へ push;
605
- stop
606
- @enduml
607
- ```
608
-
609
- ### CI が支える 4 基準
610
-
611
- この 2 つのワークフローは、10.1 で挙げた最適なイメージの 4 基準をすべて自動で満たします。
612
-
613
- - **小さい**: Multi-stage builds + distroless の Dockerfile をそのままビルド
614
- - **速い**: buildx の並列ビルドとレジストリキャッシュ
615
- - **安全**: Trivy スキャン、最小権限の `permissions`、非 root イメージ
616
- - **再現性**: `git describe` 由来のバージョンタグ、コードとして管理されたワークフロー
617
-
618
- 人手を介さずこれらを毎回確実に適用できることが、CI 自動化の最大の価値です。
619
-
620
- ---
621
-
622
- ## まとめ
623
-
624
- この章では、開発時の「とりあえず動く」コンテナイメージを、運用に耐える「最適な」イメージへ磨き上げる手法を、実際の Dockerfile と CI ワークフローを通して学びました。
625
-
626
- - **10.1** 最適なイメージの 4 基準(小さい・速い・安全・再現性)を定義しました。漠然と良し悪しを語るのではなく、評価できる軸を持つことが出発点です。
627
- - **10.2 / 10.3** ベースイメージの選択(Ubuntu → Alpine → distroless)と、`RUN` のまとめ・不要ファイル削除・`.dockerignore`・レイヤキャッシュという軽量化の基本を、`gihyo-docker-kuberbetes/ch10` の Dockerfile で段階的に確認しました。
628
- - **10.4** Multi-stage builds により、`apps/echo/Dockerfile`(Go ツールチェーン込み)から `apps/echo/Dockerfile.slim`(distroless に静的バイナリのみ)へと、ビルド環境と実行環境を分離してサイズを大幅に削減しました。
629
- - **10.5** BuildKit と `docker buildx`、`$TARGETPLATFORM` / `$TARGETARCH` を使ったマルチプラットフォームビルドとキャッシュ活用を見ました。
630
- - **10.6** `apps/image-bootstrap/Dockerfile` の distroless nonroot・`USER nonroot`・`--chown` による非 root 実行と、`trivy.yaml` による脆弱性/設定/シークレットスキャンで、最小権限と脆弱性管理を実現しました。
631
- - **10.7** GitHub Actions で buildx ビルド → ghcr.io への push を自動化し、Trivy スキャンとレジストリキャッシュを組み込むことで、4 基準を毎回確実に満たす仕組みを構築しました。
632
-
633
- 最適なイメージ作りは、一度設定して終わりではありません。ベースイメージの更新、新たに見つかる脆弱性への対応、ビルドの改善を、CI を通じて継続的に回し続けることが、「変更を楽に安全にできて役に立つソフトウェア」を運用し続ける鍵になります。
634
-
635
- 次章では、こうして作った最適なイメージを実際の環境へ届ける、継続的デリバリ(CD)の世界へ進みます。
636
-
637
- ---
638
-
639
- - 前の章: [第 9 章 コンテナの運用](09-container-operations.md)
640
- - 次の章: [第 11 章 コンテナにおける継続的デリバリー](11-continuous-delivery.md)