indexerDeployment.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import * as k8s from '@pulumi/kubernetes'
  2. import * as pulumi from '@pulumi/pulumi'
  3. import { PostgresServiceDeployment } from 'pulumi-common'
  4. /**
  5. * ServiceDeployment is an example abstraction that uses a class to fold together the common pattern of a
  6. * Kubernetes Deployment and its associated Service object.
  7. * This class deploys a db, a migration job and indexer deployment and service
  8. */
  9. export class IndexerServiceDeployment extends pulumi.ComponentResource {
  10. public readonly deployment: k8s.apps.v1.Deployment
  11. public readonly service: k8s.core.v1.Service
  12. constructor(name: string, args: ServiceDeploymentArgs, opts?: pulumi.ComponentResourceOptions) {
  13. super('indexer:service:IndexerServiceDeployment', name, {}, opts)
  14. // Name passed in the constructor will be the endpoint for accessing the service
  15. const serviceName = name
  16. let appLabels = { appClass: 'indexer' }
  17. const indexerDbName = 'indexer-db'
  18. const indexerDb = new PostgresServiceDeployment(
  19. indexerDbName,
  20. {
  21. namespaceName: args.namespaceName,
  22. env: [
  23. { name: 'POSTGRES_USER', value: process.env.DB_USER! },
  24. { name: 'POSTGRES_PASSWORD', value: process.env.DB_PASS! },
  25. { name: 'POSTGRES_DB', value: process.env.INDEXER_DB_NAME! },
  26. ],
  27. storage: args.storage,
  28. },
  29. { parent: this }
  30. )
  31. const indexerMigrationJob = new k8s.batch.v1.Job(
  32. 'indexer-db-migration',
  33. {
  34. metadata: {
  35. namespace: args.namespaceName,
  36. },
  37. spec: {
  38. backoffLimit: 0,
  39. template: {
  40. spec: {
  41. containers: [
  42. {
  43. name: 'db-migration',
  44. image: args.joystreamAppsImage,
  45. imagePullPolicy: 'IfNotPresent',
  46. resources: { requests: { cpu: '100m', memory: '100Mi' } },
  47. env: [
  48. {
  49. name: 'WARTHOG_DB_HOST',
  50. value: indexerDbName,
  51. },
  52. {
  53. name: 'DB_HOST',
  54. value: indexerDbName,
  55. },
  56. { name: 'WARTHOG_DB_DATABASE', value: process.env.INDEXER_DB_NAME! },
  57. { name: 'DB_NAME', value: process.env.INDEXER_DB_NAME! },
  58. { name: 'DB_PASS', value: process.env.DB_PASS! },
  59. ],
  60. command: ['/bin/sh', '-c'],
  61. args: ['yarn workspace query-node-root db:prepare; yarn workspace query-node-root db:migrate'],
  62. },
  63. ],
  64. restartPolicy: 'Never',
  65. },
  66. },
  67. },
  68. },
  69. { parent: this, dependsOn: indexerDb.service }
  70. )
  71. this.deployment = new k8s.apps.v1.Deployment(
  72. 'indexer',
  73. {
  74. metadata: {
  75. namespace: args.namespaceName,
  76. labels: appLabels,
  77. },
  78. spec: {
  79. replicas: 1,
  80. selector: { matchLabels: appLabels },
  81. template: {
  82. metadata: {
  83. labels: appLabels,
  84. },
  85. spec: {
  86. containers: [
  87. {
  88. name: 'redis',
  89. image: 'redis:6.0-alpine',
  90. ports: [{ containerPort: 6379 }],
  91. },
  92. {
  93. name: 'indexer',
  94. image: 'joystream/hydra-indexer:3.0.0',
  95. env: [
  96. { name: 'DB_HOST', value: indexerDbName },
  97. { name: 'DB_NAME', value: process.env.INDEXER_DB_NAME! },
  98. { name: 'DB_PASS', value: process.env.DB_PASS! },
  99. { name: 'DB_USER', value: process.env.DB_USER! },
  100. { name: 'DB_PORT', value: process.env.DB_PORT! },
  101. { name: 'INDEXER_WORKERS', value: '5' },
  102. { name: 'REDIS_URI', value: 'redis://localhost:6379/0' },
  103. { name: 'DEBUG', value: 'index-builder:*' },
  104. { name: 'WS_PROVIDER_ENDPOINT_URI', value: process.env.WS_PROVIDER_ENDPOINT_URI! },
  105. { name: 'TYPES_JSON', value: 'types.json' },
  106. { name: 'PGUSER', value: process.env.DB_USER! },
  107. { name: 'BLOCK_HEIGHT', value: process.env.BLOCK_HEIGHT! },
  108. ],
  109. volumeMounts: [
  110. {
  111. mountPath: '/home/hydra/packages/hydra-indexer/types.json',
  112. name: 'indexer-volume',
  113. subPath: 'fileData',
  114. },
  115. ],
  116. command: ['/bin/sh', '-c'],
  117. args: ['yarn db:bootstrap && yarn start:prod'],
  118. },
  119. {
  120. name: 'hydra-indexer-gateway',
  121. image: 'joystream/hydra-indexer-gateway:3.0.0',
  122. env: [
  123. { name: 'WARTHOG_STARTER_DB_DATABASE', value: process.env.INDEXER_DB_NAME! },
  124. { name: 'WARTHOG_STARTER_DB_HOST', value: indexerDbName },
  125. { name: 'WARTHOG_STARTER_DB_PASSWORD', value: process.env.DB_PASS! },
  126. { name: 'WARTHOG_STARTER_DB_PORT', value: process.env.DB_PORT! },
  127. { name: 'WARTHOG_STARTER_DB_USERNAME', value: process.env.DB_USER! },
  128. { name: 'WARTHOG_STARTER_REDIS_URI', value: 'redis://localhost:6379/0' },
  129. { name: 'WARTHOG_APP_PORT', value: process.env.WARTHOG_APP_PORT! },
  130. { name: 'PORT', value: process.env.WARTHOG_APP_PORT! },
  131. { name: 'DEBUG', value: '*' },
  132. ],
  133. ports: [{ name: 'hydra-port', containerPort: Number(process.env.WARTHOG_APP_PORT!) }],
  134. },
  135. ],
  136. volumes: [
  137. {
  138. name: 'indexer-volume',
  139. configMap: {
  140. name: args.defsConfig,
  141. },
  142. },
  143. ],
  144. },
  145. },
  146. },
  147. },
  148. { parent: this, dependsOn: indexerMigrationJob }
  149. )
  150. // Create a Service for the Indexer
  151. this.service = new k8s.core.v1.Service(
  152. serviceName,
  153. {
  154. metadata: {
  155. labels: appLabels,
  156. namespace: args.namespaceName,
  157. name: serviceName,
  158. },
  159. spec: {
  160. ports: [{ name: 'port-1', port: 4000, targetPort: 'hydra-port' }],
  161. selector: appLabels,
  162. },
  163. },
  164. { parent: this }
  165. )
  166. }
  167. }
  168. interface Environment {
  169. name: string
  170. value: string
  171. }
  172. export interface ServiceDeploymentArgs {
  173. namespaceName: pulumi.Output<string>
  174. joystreamAppsImage: pulumi.Output<string>
  175. defsConfig: pulumi.Output<string> | undefined
  176. env?: Environment[]
  177. storage: Number
  178. }