{"id":20816804,"url":"https://github.com/khofesh/ticketing-rabbitmq","last_synced_at":"2026-04-20T18:31:39.111Z","repository":{"id":45454797,"uuid":"431754776","full_name":"khofesh/ticketing-rabbitmq","owner":"khofesh","description":"the code from https://www.udemy.com/course/microservices-with-node-js-and-react/ edited","archived":false,"fork":false,"pushed_at":"2021-12-30T09:20:05.000Z","size":830,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-15T18:41:04.037Z","etag":null,"topics":["kubernetes","rabbitmq"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khofesh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-11-25T07:37:41.000Z","updated_at":"2022-03-30T07:40:42.000Z","dependencies_parsed_at":"2022-09-19T01:00:50.833Z","dependency_job_id":null,"html_url":"https://github.com/khofesh/ticketing-rabbitmq","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/khofesh/ticketing-rabbitmq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khofesh%2Fticketing-rabbitmq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khofesh%2Fticketing-rabbitmq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khofesh%2Fticketing-rabbitmq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khofesh%2Fticketing-rabbitmq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khofesh","download_url":"https://codeload.github.com/khofesh/ticketing-rabbitmq/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khofesh%2Fticketing-rabbitmq/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32059733,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kubernetes","rabbitmq"],"created_at":"2024-11-17T21:37:09.740Z","updated_at":"2026-04-20T18:31:39.095Z","avatar_url":"https://github.com/khofesh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## TODO\n\n1. tests\n2. all mongo sessions connect to mongodb://auth-mongo-srv:27017/session\n\n## minikube\n\n```sh\nminikube start\nskaffold config set --global local-cluster true\neval $(minikube -p minikube docker-env)\n```\n\n### IP\n\n```shell\nminikube ip\n```\n\n## krew\n\nhttps://krew.sigs.k8s.io/docs/user-guide/setup/install/\n\ndownload and install krew\n\n```sh\n(\n  set -x; cd \"$(mktemp -d)\" \u0026\u0026\n  OS=\"$(uname | tr '[:upper:]' '[:lower:]')\" \u0026\u0026\n  ARCH=\"$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\\(arm\\)\\(64\\)\\?.*/\\1\\2/' -e 's/aarch64$/arm64/')\" \u0026\u0026\n  KREW=\"krew-${OS}_${ARCH}\" \u0026\u0026\n  curl -fsSLO \"https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz\" \u0026\u0026\n  tar zxvf \"${KREW}.tar.gz\" \u0026\u0026\n  ./\"${KREW}\" install krew\n)\n```\n\nappend the following line to `$HOME/.profile`\n\n```sh\nexport PATH=\"${KREW_ROOT:-$HOME/.krew}/bin:$PATH\"\n```\n\ncheck installation\n\n```sh\n[fahmad@ryzen ticketing]$  kubectl krew\nkrew is the kubectl plugin manager.\nYou can invoke krew through kubectl: \"kubectl krew [command]...\"\n\nUsage:\n  kubectl krew [command]\n\n...\n```\n\n## install rabbitmq cluster operator\n\n```sh\nkubectl apply -f \"https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml\"\n```\n\n## install kubectl-rabbitmq plugin\n\nhttps://www.rabbitmq.com/kubernetes/operator/install-operator.html\n\n```sh\n[fahmad@ryzen ticketing]$ kubectl krew install rabbitmq\nUpdated the local copy of plugin index.\nInstalling plugin: rabbitmq\nInstalled plugin: rabbitmq\n\\\n | Use this plugin:\n | \tkubectl rabbitmq\n | Documentation:\n | \thttps://github.com/rabbitmq/cluster-operator\n | Caveats:\n | \\\n |  | This plugin requires the RabbitMQ cluster operator to be installed.\n |  | To install the RabbitMQ cluster operator run `kubectl rabbitmq install-cluster-operator`.\n |  |\n |  | `tail` subcommand requires the `tail` plugin. You can install it with `kubectl krew install tail`.\n | /\n/\nWARNING: You installed plugin \"rabbitmq\" from the krew-index plugin repository.\n   These plugins are not audited for security by the Krew maintainers.\n   Run them at your own risk.\n\n```\n\n## rabbitmq\n\nhttps://www.rabbitmq.com/production-checklist.html\n\nhttps://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler#autoscaling_profiles\n\nhttps://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-can-i-check-what-is-going-on-in-ca-\n\nhttps://github.com/rabbitmq/cluster-operator/blob/main/docs/examples/resource-limits/rabbitmq.yaml\n\nhttps://www.rabbitmq.com/kubernetes/operator/kubectl-plugin.html\n\n### Clients Libraries and Developer Tools\n\nhttps://www.rabbitmq.com/devtools.html\n\namqp 1.0\n\n- https://github.com/amqp/rhea\n\n### yaml config\n\nhttps://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/\n\n```yaml title=\"rabbitmq.yml\"\napiVersion: rabbitmq.com/v1beta1\nkind: RabbitmqCluster\nmetadata:\n  name: rabbit\nspec:\n  replicas: 1\n  resources:\n    requests:\n      cpu: 500m\n      memory: 1Gi\n    limits:\n      cpu: 800m\n      memory: 1Gi\n```\n\napply the config\n\n```sh\nkubectl apply -f infra/rabbit/rabbitmq.yml\n```\n\ncheck\n\n```sh\nfahmad@ryzen ticketing-rabbitmq]$  kubectl get pods\nNAME              READY   STATUS    RESTARTS   AGE\nrabbit-server-0   1/1     Running   0          15m\n[fahmad@ryzen ticketing-rabbitmq]$  kubectl get services\nNAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE\nkubernetes     ClusterIP   10.96.0.1       \u003cnone\u003e        443/TCP                        37d\nrabbit         ClusterIP   10.110.18.122   \u003cnone\u003e        5672/TCP,15672/TCP,15692/TCP   15m\nrabbit-nodes   ClusterIP   None            \u003cnone\u003e        4369/TCP,25672/TCP             15m\n\n```\n\nport forwarding\n\n```sh\nkubectl port-forward rabbit-server-0 5672:5672\n```\n\nget default username and password\n\n```sh\nusername=\"$(kubectl get secret rabbit-default-user -o jsonpath='{.data.username}' | base64 --decode)\"\necho $username\n\npassword=\"$(kubectl get secret rabbit-default-user -o jsonpath='{.data.password}' | base64 --decode)\"\necho $password\n```\n\n### notes\n\nIn order to make sure a message is never lost, RabbitMQ supports [message acknowledgments](https://www.rabbitmq.com/confirms.html). An ack(nowledgement) is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it.\n\n## test\n\n### work queues\n\nDistributing tasks among workers\n\n```sh\nts-node src/worker.js\n```\n\n```sh\nts-node src/worker.js\n```\n\n```sh\nsh new-task.sh\n```\n\n### publish/subscribe\n\nSending messages to many consumers at once\n\n```sh\nts-node src/receive_logs.js \u003e logs_from_rabbit.log\n```\n\n```sh\nts-node src/receive_logs.js\n```\n\n```sh\nsh emit-log.sh\n```\n\n### routing\n\nReceiving messages selectively\n\n```sh\nts-node src/receive_log_direct.ts warning error \u003e logs_from_rabbit.log\n```\n\n```sh\nts-node src/receive_log_direct.ts info warning error\n```\n\n```sh\nts-node src/emit_log_direct.ts error \"Run. Run. \"\n```\n\n### topic\n\nReceiving messages based on a pattern (topics)\n\nAlthough using the direct exchange improved our system, it still has limitations - it can't do routing based on multiple criteria.\n\n```sh\nts-node src/receive_log_topic.ts '#'\n```\n\n```sh\nts-node src/receive_log_topic.ts \"kern.*\"\n```\n\n```sh\nts-node src/receive_log_topic.ts '*.critical'\n```\n\n```sh\nts-node src/receive_log_topic.ts \"kern.*\"\n```\n\n```sh\ns-node src/emit_log_topic.ts 'kern.critical' 'a critical kernel error'\n```\n\n### rpc\n\n```sh\nts-node src/rpc_server.ts\n [x] Awaiting RPC requests\n [.] fib(30)\n [.] fib(30)\n```\n\n```sh\nts-node src/rpc_client.ts 30\n [x] Requesting fib(30)\n [.] Got 832040\n```\n\n## rabbit on app\n\n```sh\nkubectl create secret generic rabbit-user --from-literal RABBIT_USER=thepassword\nsecret/rabbit-user created\n\nkubectl create secret generic rabbit-password --from-literal RABBIT_PASSWORD=thepassword\nsecret/rabbit-password created\n```\n\ninside `tickets.depl.yaml` add the following right before `- name: JWT_KEY`\n\n```yaml\n- name: RABBIT_USER\n  valueFrom:\n    secretKeyRef:\n      name: rabbit-user\n      key: RABBIT_USER\n- name: RABBIT_PASSWORD\n  valueFrom:\n    secretKeyRef:\n      name: rabbit-password\n      key: RABBIT_PASSWORD\n- name: RABBIT_URL\n  value: \"rabbit\"\n```\n\n### test\n\n```sh\nskaffold dev\n```\n\nport-forward\n\n```sh\nkubectl port-forward rabbit-server-0 5672:5672\n```\n\nchange dir to rabbit-test then run\n\n```sh\nts-node src/emit_direct_new.ts\n```\n\nhit endpoint `https://ticketing.dev/api/tickets` with method `POST` and json body :\n\n```json\n{\n  \"title\": \"concert\",\n  \"price\": 500\n}\n```\n\nresult\n\n```sh\n[fahmad@ryzen rabbit-test] $ ts-node src/receive_direct-new.ts\n [*] Waiting for logs. To exit press CTRL+C\n [x] tickets: '{\"id\":\"61a098920d5a50f6ddcfc4dd\",\"title\":\"concert\",\"price\":500,\"userId\":\"61a097c301126ea70bb547d4\"}'\n [x] tickets: '{\"id\":\"61a09c082f66716e91dde5fb\",\"title\":\"concert\",\"price\":500,\"userId\":\"61a09bfeadd1ec605b55f19b\"}'\n```\n\n## errors\n\n```shell\nError: Channel closed by server: 406 (PRECONDITION-FAILED) with message \"PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more\"\n```\n\n## optimistic concurrency control in mongoose\n\nhttps://stackoverflow.com/a/69047822\n\nhttps://mongoosejs.com/docs/guide.html#optimisticConcurrency\n\n```typescript\nconst orderSchema = new mongoose.Schema(\n  {\n    userId: {\n      type: String,\n      required: true,\n    },\n    status: {\n      type: String,\n      required: true,\n      enum: Object.values(OrderStatus),\n      default: OrderStatus.Created,\n    },\n    expiresAt: {\n      type: mongoose.Schema.Types.Date,\n    },\n    ticket: {\n      type: mongoose.Schema.Types.ObjectId,\n      ref: \"Ticket\",\n    },\n  },\n  {\n    toJSON: {\n      transform(doc, ret) {\n        ret.id = ret._id;\n        delete ret._id;\n      },\n    },\n    optimisticConcurrency: true,\n  }\n);\n```\n\n## Stripe\n\n1. sign up\n2. get secret key\n\n```shell\nkubectl create secret generic stripe-secret --from-literal STRIPE_KEY=sfsdfsdfsdf\n\n```\n\ncheck it out\n\n```shell\nkubectl get secrets\n```\n\n### charge\n\nhttps://stripe.com/docs/api/charges/create\n\n### references\n\nhttps://stripe.com/docs/payments/quickstart\n\nhttps://stripe.com/docs/testing\n\nhttps://stripe.com/docs/api/checkout/sessions/object\n\n## npm update\n\nhttps://github.com/npm/cli/issues/708#issuecomment-965430893\n\n## github actions\n\nhttps://docs.github.com/en/actions/quickstart\n\n## nestjs microservices\n\n### rabbitmq\n\nhttps://github.com/golevelup/nestjs/tree/master/packages/rabbitmq\n\n### sample\n\nhttps://github.com/nestjs/nest/tree/master/sample/03-microservices\n\n## ErrImagePull, ErrImageNeverPull and ImagePullBackoff Errors\n\n```shell\nkubectl delete -f infra/k8s/\n```\n\n```yml\nspec:\n  containers:\n    - name: posts\n      image: khofesh/posts:0.0.1\n      imagePullPolicy: Never\n```\n\n```shell\n[fahmad@ryzen blog]$  pwd\n/media/xfsfast/study/udemy-microservices/blog\n\neval $(minikube -p minikube docker-env)\n\ndocker build -t khofesh/posts:0.0.1 -f posts/Dockerfile ./posts\n```\n\n```shell\nkubectl apply -f infra/k8s/\n```\n\n## common kubectl commands\n\n```sh\nkubectl exec -it posts -- sh\n```\n\n`kubectl exec -it posts sh` is deprecated\n\n## access nodePort services\n\n```sh\n[fahmad@ryzen blog]$ kubectl describe service posts-srv\nName:                     posts-srv\nNamespace:                default\nLabels:                   \u003cnone\u003e\nAnnotations:              \u003cnone\u003e\nSelector:                 app=posts\nType:                     NodePort\nIP Family Policy:         SingleStack\nIP Families:              IPv4\nIP:                       10.96.97.204\nIPs:                      10.96.97.204\nPort:                     posts  4000/TCP\nTargetPort:               4000/TCP\nNodePort:                 posts  32442/TCP\nEndpoints:                172.17.0.4:4000\nSession Affinity:         None\nExternal Traffic Policy:  Cluster\nEvents:                   \u003cnone\u003e\n\n```\n\n```shell\n[fahmad@ryzen blog]$  minikube ip\n192.168.49.2\n```\n\nthen, open `http://192.168.49.2:32442/posts` in browser\n\n## skaffold\n\ninstall\n\n```sh\n# For Linux x86_64 (amd64)\ncurl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 \u0026\u0026 \\\nsudo install skaffold /usr/local/bin/\n```\n\nhttps://skaffold.dev/docs/quickstart/\n\n```sh\nminikube start --profile custom\nskaffold config set --global local-cluster true\neval $(minikube -p minikube docker-env)\n```\n\n## ingress nginx\n\nhttps://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/\n\n## nextjs dockerfile\n\nhttps://nextjs.org/docs/deployment\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhofesh%2Fticketing-rabbitmq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhofesh%2Fticketing-rabbitmq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhofesh%2Fticketing-rabbitmq/lists"}