indexerDeployment.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. const config = new pulumi.Config()
  15. const DB_PASS = config.require('dbPassword')
  16. const BLOCK_HEIGHT = config.require('blockHeight') || '0'
  17. const WS_PROVIDER_ENDPOINT_URI = config.require('joystreamWsEndpoint')
  18. const DB_USERNAME = 'postgres'
  19. const INDEXER_DATABASE_NAME = 'indexer'
  20. const DB_PORT = '5432'
  21. // Name passed in the constructor will be the endpoint for accessing the service
  22. const serviceName = name
  23. const appLabels = { appClass: 'indexer' }
  24. const indexerDbName = 'indexer-db'
  25. const indexerDb = new PostgresServiceDeployment(
  26. indexerDbName,
  27. {
  28. namespaceName: args.namespaceName,
  29. env: [
  30. { name: 'POSTGRES_USER', value: DB_USERNAME },
  31. { name: 'POSTGRES_PASSWORD', value: DB_PASS },
  32. { name: 'POSTGRES_DB', value: INDEXER_DATABASE_NAME },
  33. { name: 'PGPORT', value: DB_PORT },
  34. ],
  35. storage: args.storage,
  36. },
  37. { parent: this }
  38. )
  39. this.deployment = new k8s.apps.v1.Deployment(
  40. 'indexer',
  41. {
  42. metadata: {
  43. namespace: args.namespaceName,
  44. labels: appLabels,
  45. },
  46. spec: {
  47. replicas: 1,
  48. selector: { matchLabels: appLabels },
  49. template: {
  50. metadata: {
  51. labels: appLabels,
  52. },
  53. spec: {
  54. containers: [
  55. {
  56. name: 'redis',
  57. image: 'redis:6.0-alpine',
  58. ports: [{ containerPort: 6379 }],
  59. },
  60. {
  61. name: 'indexer',
  62. image: 'joystream/hydra-indexer:3.0.0',
  63. env: [
  64. { name: 'DB_HOST', value: indexerDbName },
  65. { name: 'DB_NAME', value: INDEXER_DATABASE_NAME },
  66. { name: 'DB_PASS', value: DB_PASS },
  67. { name: 'DB_USER', value: DB_USERNAME },
  68. { name: 'DB_PORT', value: DB_PORT },
  69. { name: 'INDEXER_WORKERS', value: '5' },
  70. // localhost for redis should work since it is in the same deployment
  71. { name: 'REDIS_URI', value: 'redis://localhost:6379/0' },
  72. { name: 'DEBUG', value: 'index-builder:*' },
  73. { name: 'WS_PROVIDER_ENDPOINT_URI', value: WS_PROVIDER_ENDPOINT_URI },
  74. { name: 'TYPES_JSON', value: 'types.json' },
  75. { name: 'PGUSER', value: DB_USERNAME },
  76. { name: 'BLOCK_HEIGHT', value: BLOCK_HEIGHT },
  77. ],
  78. volumeMounts: [
  79. {
  80. mountPath: '/home/hydra/packages/hydra-indexer/types.json',
  81. name: 'indexer-volume',
  82. subPath: 'fileData',
  83. },
  84. ],
  85. command: ['/bin/sh', '-c'],
  86. args: ['yarn db:bootstrap && yarn start:prod'],
  87. },
  88. {
  89. name: 'hydra-indexer-gateway',
  90. image: 'joystream/hydra-indexer-gateway:3.0.0',
  91. env: [
  92. { name: 'WARTHOG_STARTER_DB_DATABASE', value: INDEXER_DATABASE_NAME },
  93. { name: 'WARTHOG_STARTER_DB_HOST', value: indexerDbName },
  94. { name: 'WARTHOG_STARTER_DB_PASSWORD', value: DB_PASS },
  95. { name: 'WARTHOG_STARTER_DB_PORT', value: DB_PORT },
  96. { name: 'WARTHOG_STARTER_DB_USERNAME', value: DB_USERNAME },
  97. // localhost for redis should work since it is in the same deployment
  98. { name: 'WARTHOG_STARTER_REDIS_URI', value: 'redis://localhost:6379/0' },
  99. { name: 'WARTHOG_APP_PORT', value: '4001' },
  100. { name: 'PORT', value: '4001' },
  101. { name: 'DEBUG', value: '*' },
  102. ],
  103. ports: [{ name: 'hydra-port', containerPort: 4001 }],
  104. },
  105. ],
  106. volumes: [
  107. {
  108. name: 'indexer-volume',
  109. configMap: {
  110. name: args.defsConfig,
  111. },
  112. },
  113. ],
  114. },
  115. },
  116. },
  117. },
  118. { parent: this, dependsOn: indexerDb.service }
  119. )
  120. // Create a Service for the Indexer
  121. this.service = new k8s.core.v1.Service(
  122. serviceName,
  123. {
  124. metadata: {
  125. labels: appLabels,
  126. namespace: args.namespaceName,
  127. name: serviceName,
  128. },
  129. spec: {
  130. ports: [{ name: 'port-1', port: 4000, targetPort: 'hydra-port' }],
  131. selector: appLabels,
  132. },
  133. },
  134. { parent: this }
  135. )
  136. }
  137. }
  138. interface Environment {
  139. name: string
  140. value: string
  141. }
  142. export interface ServiceDeploymentArgs {
  143. namespaceName: pulumi.Output<string>
  144. joystreamAppsImage: pulumi.Output<string>
  145. defsConfig: pulumi.Output<string> | undefined
  146. env?: Environment[]
  147. storage: number
  148. }