{
    "componentChunkName": "component---src-pages-blog-post-tsx",
    "path": "/blog/2021-01-19/rabbitmq-docker-tutorial",
    "result": {"data":{"site":{"siteMetadata":{"siteUrl":"https://www.architect.io"}},"allMdx":{"edges":[{"node":{"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Implement RabbitMQ on Docker in 20 Minutes\",\n  \"description\": \"Implement a RabbitMQ message broker with a Node.js Express producer and a Python consumer. Deploy using Docker and Architect.\",\n  \"keywords\": \"rabbitmq docker\",\n  \"slug\": \"rabbitmq-docker-tutorial\",\n  \"date\": \"2021-01-19T00:00:00.000Z\",\n  \"author\": \"Dan Barrett\",\n  \"image\": \"./rabbitmq-docker.png\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Here at Architect, it's no secret that we love portable microservices. And what better way to make\\nyour services portable than by decoupling their interactions?\"), mdx(\"p\", null, \"Today we talk about decoupling your services using a classic communication pattern: the message\\nqueue. In this tutorial, we'll show you how to get our favorite open source message\\nbroker--RabbitMQ--up and running in just 20 minutes. Then we'll use Architect to deploy the stack to\\nboth your local and remote environments.\"), mdx(\"p\", null, \"If you're following along with this tutorial at home, you'll need a few pre-reqs:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://docs.docker.com/get-docker/\"\n  }, \"Docker\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://nodejs.org/en/\"\n  }, \"Node\"), \" >= 8.2.0\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://www.python.org/\"\n  }, \"Python\"), \" >= 3\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://cloud.architect.io/signup\"\n  }, \"Architect\"))), mdx(\"h2\", {\n    \"id\": \"rabbitmq-instance-with-docker\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"RabbitMQ Instance with Docker\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#rabbitmq-instance-with-docker\",\n    \"aria-label\": \"rabbitmq instance with docker permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"First, let's pull the RabbitMQ docker image. We'll use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"3-management\"), \" version, so we get the\\nManagement plugin pre-installed.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"docker pull rabbitmq:3-management\"))), mdx(\"p\", null, \"Now let's stand it up. We\\u2019ll map port \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"15672\"), \" for the management web app and port \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"5672\"), \" for the\\nmessage broker.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"docker run --rm -it -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"15672\"), \":15672 -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"5672\"), \":5672 rabbitmq:3-management\"))), mdx(\"p\", null, \"Assuming that ran successfully, you've got an instance of RabbitMQ running! Bounce over to\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://localhost:15672\"\n  }, \"http://localhost:15672\"), \" to check out the management web app.\"), mdx(\"p\", null, \"Log in using the default username (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guest\"), \") and password (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guest\"), \") and explore the management app a\\nlittle bit. Here you can see an overview of your RabbitMQ instance and the message broker\\u2019s basic\\ncomponents: Connections, Channels, Exchanges, and Queues.\"), mdx(\"h2\", {\n    \"id\": \"send-messages-to-rabbitmq-from-a-producer\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Send Messages to RabbitMQ from a Producer\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#send-messages-to-rabbitmq-from-a-producer\",\n    \"aria-label\": \"send messages to rabbitmq from a producer permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"RabbitMQ is only interesting if we can send messages, so let's create an example publisher to push\\nmessages to RabbitMQ. In a new session (keep RabbitMQ running), we'll use the following directory\\nstructure:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"mkdir\"), \" -p rabbitmq/rabbitmq-producer\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"mkdir\"), \" -p rabbitmq/rabbitmq-consumer\"))), mdx(\"p\", null, \"Our publisher will be a simple Node.js Express web application. Use the Express app generator to\\nbootstrap a simple Express app. We'll use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"amqplib\"), \" Node library, the recommended AMQP client.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbitmq-producer\\nnpx express-generator\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"npm\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"install\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"npm\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"install\"), \" amqplib\"))), mdx(\"p\", null, \"The plan is to add a route that accepts requests to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"POST /message\"), \" with a body that looks something\\nlike this: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"{'message': 'my message'}\"), \". That route will publish each message it receives to our\\nRabbitMQ instance.\"), mdx(\"p\", null, \"First, create a new file called \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"message.js\"), \" next to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \".\"), mdx(\"p\", null, \"Import \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"amqplib\"), \", set the URL to the location of the RabbitMQ instance, and give our queue a name:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"var\"), \" express \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"require\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'express'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"var\"), \" router \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" express\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"Router\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"var\"), \" amqp \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"require\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'amqplib/callback_api'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" url \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'amqp://localhost'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" queue \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'my-queue'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"Next, initialize the connection:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"let\"), \" channel \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"null\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\namqp\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"connect\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"url\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"function\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token parameter\"\n  }, \"err\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" conn\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"if\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"!\"), \"conn\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"throw\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"new\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token class-name\"\n  }, \"Error\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token template-string\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"AMQP connection not available on \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"${\"), \"url\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"}\")), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\")), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), \"\\n  conn\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"createChannel\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"function\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token parameter\"\n  }, \"err\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" ch\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n    channel \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" ch\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"And it's important that we not forget to add an exit handler to close the channel:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"on\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'exit'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token parameter\"\n  }, \"code\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=>\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"close\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  console\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"log\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token template-string\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"Closing\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\")), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"Now for the meat. We'll add a route that receives the message, converts the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body.message\"), \" string\\ninto a Buffer, and sends it to the queue:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"router\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"post\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'/'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"function\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token parameter\"\n  }, \"req\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" res\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" next\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"sendToQueue\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"queue\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"new\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token class-name\"\n  }, \"Buffer\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"from\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"req\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"body\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"message\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n  res\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"render\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'index'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \" response\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \":\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token template-string\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"Successfully sent: \"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"${\"), \"req\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"body\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"message\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"}\")), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\")), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\nmodule\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"exports \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" router\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"Last, we'll need to register our new route in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"app.js\"), \". We'll put it underneath the existing index\\nroute, and we'll nest our routes under \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/message\"), \":\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"var\"), \" messagesRouter \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"require\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'./routes/message'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\\napp\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"use\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'/'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" indexRouter\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\napp\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"use\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'/message'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" messagesRouter\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"We'll also add a simple HTML form to our view to post messages to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/messages\"), \" endpoint. Replace\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" with the following:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"jade\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-jade\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-jade\"\n  }, \"extends layout\\n\\nblock content\\n  h1= 'Example RabbitMQ Producer'\\n\\n  div\\n    form(action='/message',method='post')\\n      div.input\\n          span.label Message:&emsp;\\n          input(type=\\\"text\\\", name=\\\"message\\\")\\n          span.actions &emsp;\\n            input(type=\\\"submit\\\", value=\\\"Send\\\")\\n\\n  div\\n    p= response\"))), mdx(\"p\", null, \"That should do it! See the full Express app\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/architect-team/architect-cli/tree/tutorials/rabbit-mq-1/examples/rabbitmq/rabbit-producer\"\n  }, \"source code here\")), mdx(\"p\", null, \"Now we can run the sample producer app:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"npm start\"))), mdx(\"p\", null, \"And we can visit it here: \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://localhost:3000\"\n  }, \"http://localhost:3000\"), \".\"), mdx(\"p\", null, \"Try sending a message from the browser. It should send a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"POST\"), \" HTTP request to the Express app,\\nwhich will subsequently stick it on the queue. If you navigate to the RabbitMQ management app, you\\nshould see traffic coming through \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://localhost:15672/#/\"\n  }, \"http://localhost:15672\"), \".\"), mdx(\"h2\", {\n    \"id\": \"receive-messages-from-rabbitmq-with-a-consumer\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Receive Messages from RabbitMQ with a Consumer\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#receive-messages-from-rabbitmq-with-a-consumer\",\n    \"aria-label\": \"receive messages from rabbitmq with a consumer permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"Now that we're publishing messages let's see if we can receive them with a consumer application.\"), mdx(\"p\", null, \"We'll use Python for our sample consumer application. This illustrates the flexibility that a\\nmessage queue introduces to our stack. While we wouldn't suggest a multi-language stack just for the\\nhell of it, using AMQP for inter-process communication does give us the polyglot option in a pinch!\"), mdx(\"p\", null, \"In a new session (keep RabbitMQ and the producer running):\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbitmq-consumer\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"touch\"), \" consumer.py\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"touch\"), \" requirements.txt\"))), mdx(\"p\", null, \"We'll use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pika\"), \", a recommended AMQP Python client:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"pip \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"install\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'pika==1.1.0'\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"echo\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'pika == 1.1.0'\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \">\"), \" requirements.txt\"))), mdx(\"p\", null, \"In \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"consumer.py\"), \", first import \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pika\"), \":\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"py\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-py\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-py\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"import\"), \" pika\"))), mdx(\"p\", null, \"And just like we did in the producer app, set the AMQP host and the queue name that our app will\\nlisten on:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"host = 'localhost'\\nqueue = 'my-queue'\"))), mdx(\"p\", null, \"Next, define a method for handling the messages coming off the queue. For the sake of this tutorial,\\nour app will simply log all received messages to stdout:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"py\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-py\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-py\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"def\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"on_message\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"ch\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" method\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" properties\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" body\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \":\"), \"\\n    message \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" body\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"decode\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'UTF-8'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"print\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"message\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\")))), mdx(\"p\", null, \"Let's create a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"main()\"), \" method for the core logic. Here we create the connection and ensure the\\nqueue exists. Last, we pass in the message handler and start consuming.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"py\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-py\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-py\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"def\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"main\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \":\"), \"\\n    connection_params \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" pika\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"ConnectionParameters\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"host\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"host\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n    connection \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" pika\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"BlockingConnection\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"connection_params\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n    channel \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" connection\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n\\n    channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"queue_declare\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"queue\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"queue\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n\\n    channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"basic_consume\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), \"queue\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"queue\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" on_message_callback\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \"on_message\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \",\"), \" auto_ack\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token boolean\"\n  }, \"True\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n\\n    \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"print\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'Subscribed to '\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"+\"), \" queue \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"+\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"', waiting for messages...'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\n    channel\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"start_consuming\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\")))), mdx(\"p\", null, \"Finally, call the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"main()\"), \" method:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"if __name__ == '__main__':\\n    main()\"))), mdx(\"p\", null, \"See the full Python consumer app\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/architect-team/architect-cli/blob/tutorials/rabbit-mq-1/examples/rabbitmq/rabbit-consumer/consumer.py\"\n  }, \"source code here\"), \".\"), mdx(\"p\", null, \"Now run the consumer:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"python consumer.py\"))), mdx(\"p\", null, \"If we navigate back to our \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://localhost:3000\"\n  }, \"producer webapp\"), \", we can publish a message. The\\nbrowser app posts the message to our Node Express server, which publishes the message to RabbitMQ.\\nIf you're watching the logs in our Python command line consumer app, you should see the message come\\nacross. Works like a charm!\"), mdx(\"p\", null, \"Queues are a nifty decoupling mechanism. We've got a Node app and a Python app seamlessly\\ncommunicating! Even better- neither one depends on the uptime of the other. Try killing the consumer\\napplication and then publish a message from the producer. Now restart the Python consumer. You\\nshould see the message come through! No traffic was lost while the consumer was down.\"), mdx(\"h2\", {\n    \"id\": \"deploy-rabbitmq-with-docker\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Deploy RabbitMQ with Docker\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#deploy-rabbitmq-with-docker\",\n    \"aria-label\": \"deploy rabbitmq with docker permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"We already have three components in our stack: the web app producer, the message broker, and the\\ncommand line consumer. How are we going to deploy this stack into a remote or production\\nenvironment?\"), mdx(\"p\", null, \"First, let's make these applications a little bit more portable using docker. The RabbitMQ container\\nis already Dockerized, so we'll create Dockerfiles for both the Express server and the Python\\nconsumer.\"), mdx(\"p\", null, \"First, the producer Dockerfile:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbit-producer\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"touch\"), \" Dockerfile\"))), mdx(\"p\", null, \"Add the following contents:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"FROM node:14\\n\\nWORKDIR /usr/src/app\\n\\n## copying package.json and npm install before copying directory saves time w/ caching\\nCOPY package*.json ./\\n\\nRUN npm install\\n\\nCOPY . .\\n\\nEXPOSE 3000\\n\\nCMD [ \\\"npm\\\", \\\"start\\\" ]\"))), mdx(\"p\", null, \"Adding a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".dockerignore\"), \" file next to the producer \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Dockerfile\"), \" will save us some build time here\\ntoo:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"node_modules\\nnpm-debug.log\"))), mdx(\"p\", null, \"Next, add the consumer Dockerfile:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbit-consumer\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token function\"\n  }, \"touch\"), \" Dockerfile\"))), mdx(\"p\", null, \"Add the following:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"FROM python:3\\n\\nWORKDIR /usr/src/app\\n\\nCOPY requirements.txt ./\\nRUN pip install --no-cache-dir -r requirements.txt\\n\\nCOPY . .\\n\\nCMD [ \\\"python\\\", \\\"-u\\\", \\\"consumer.py\\\" ]\"))), mdx(\"p\", null, \"Let's fire them all up locally. First, in one session, we'll run RabbitMQ:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"docker run --rm -it -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"15672\"), \":15672 -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"5672\"), \":5672 rabbitmq:3-management\"))), mdx(\"p\", null, \"Next, open up another session and run the producer. We'll map port 3000, so we can access our\\nExpress app.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbit-producer\\ndocker docker build -t rabbit-producer \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \".\"), \"\\ndocker run -it --rm -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"3000\"), \":3000 rabbit-producer\"))), mdx(\"p\", null, \"Uh oh... that crashed. Looks like we got an error:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"Error: AMQP connection not available on amqp://localhost\"))), mdx(\"p\", null, \"This makes sense: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"localhost\"), \" no longer resolves to RabbitMQ now that we're running the producer\\ninside a docker container. The RabbitMQ instance is running in a different container! We might make\\nthis work by changing the URL to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"host.docker.internal\"), \", but this is just as brittle: now we can't\\nrun the producer without docker. Further, once we try to deploy this remotely, we'll need to change\\nthis again.\"), mdx(\"p\", null, \"This sounds like a good candidate for an environment variable! So let's factor it out. While we're\\nat it, let's do the same for the queue name since this is liable to change across environments as\\nwell.\"), mdx(\"p\", null, \"In our Node.js producer \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"message.js\"), \", we'll change the url and queue:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"js\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-js\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" url \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token template-string\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token string\"\n  }, \"amqp://\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"${\"), \"process\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token constant\"\n  }, \"AMQP_HOST\"), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token interpolation-punctuation punctuation\"\n  }, \"}\")), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"token template-punctuation string\"\n  }, \"`\")), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token keyword\"\n  }, \"const\"), \" queue \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" process\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"env\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"QUEUE_NAME\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \";\")))), mdx(\"p\", null, \"Likewise, in our Python \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"consumer.py\"), \", we'll do the same (you'll need to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"import os\"), \" at the top of\\nthe file).\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"python\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-python\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-python\"\n  }, \"host \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" os\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"environ\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"get\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'AMQP_HOST'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\"), \"\\nqueue \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), \" os\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"environ\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \".\"), \"get\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"(\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'QUEUE_NAME'\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \")\")))), mdx(\"p\", null, \"Be sure the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"rabbitmq\"), \" docker container is still running in another shell. Now, in a new shell, we\\nshould be able to run the producer and pass in the environment variables:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbit-producer\\ndocker build -t rabbit-producer \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \".\"), \"\\ndocker run -it --rm -p \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token number\"\n  }, \"3000\"), \":3000 -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"QUEUE_NAME\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'my-queue'\"), \" -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"AMQP_HOST\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'host.docker.internal'\"), \" rabbit-producer\"))), mdx(\"p\", null, \"Keep the producer running and open up a new shell. Then run the consumer:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"bash\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-bash\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \"cd\"), \" rabbitmq/rabbit-consumer\\ndocker build -t rabbit-consumer \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token builtin class-name\"\n  }, \".\"), \"\\ndocker run -it --rm -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"QUEUE_NAME\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'my-queue'\"), \" -e \", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token assign-left variable\"\n  }, \"AMQP_HOST\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"'host.docker.internal'\"), \" rabbit-consumer\"))), mdx(\"p\", null, \"Now, if you navigate to \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://localhost:3000\"\n  }, \"http://localhost:3000\"), \", you should be able to\\npublish a message and watch that messages flow!\"), mdx(\"h2\", {\n    \"id\": \"deploy-rabbitmq-with-docker-and-architect\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Deploy RabbitMQ with Docker and Architect\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#deploy-rabbitmq-with-docker-and-architect\",\n    \"aria-label\": \"deploy rabbitmq with docker and architect permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"By Dockerizing our services, we've taken a great step toward a more portable application.\"), mdx(\"p\", null, \"But deploying these services remotely still requires several steps with manual configuration. While\\nDocker makes individual services more portable,\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.architect.io/blog/the-feature-docker-forgot#make-apps-portable-with-network-awareness\"\n  }, \"it doesn't quite do the same for the full stack.\"), \"\\nDocker Compose gets us some of the way there for local development, but an important principle of\\nportable application development is that we operate our services the same way, regardless of the\\nenvironment! A developer shouldn't have to change the way they deploy services between local and\\nremote environments. \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cloud.architect.io/signup\"\n  }, \"Architect\"), \" solves that.\"), mdx(\"p\", null, \"Using Architect to make a fully deployable stack is easy:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Mark up your services with a YML file\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Deploy\")), mdx(\"p\", null, \"If you haven't signed up for Architect yet, \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cloud.architect.io/signup\"\n  }, \"do it now\"), \"! It's\\nfast, free, and we'll blow you away with our deploy process!\"), mdx(\"p\", null, \"Download the Architect CLI and log in to Architect Cloud:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"npm install -g @architect-io/cli\\narchitect login\"))), mdx(\"p\", null, \"To get started, we\\u2019ve composed an example\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/architect-team/architect-cli/blob/tutorials/rabbit-mq-2/examples/rabbitmq/architect.yml\"\n  }, \"architect.yml\"), \"\\nfor this rabbitmq stack. You can copy it to your directory with:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"cd rabbitmq\\ncurl https://raw.githubusercontent.com/architect-team/architect-cli/tutorials/rabbit-mq-2/examples/rabbitmq/architect.yml > architect.yml\"))), mdx(\"p\", null, \"When you registered with Architect Cloud, you were prompted to create an account. Change the top\\nline of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"architect.yml\"), \" to match your new account name:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"name: <your-account-name>/rabbitmq\"))), mdx(\"p\", null, \"Now, deploying the example RabbitMQ stack on your local environment becomes as easy as:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"architect link architect.yml\\narchitect dev <your-account-name>/rabbitmq:latest -p QUEUE_NAME=my-queue -i app:app mgmt:mgmt\"))), mdx(\"p\", null, \"Then navigate to \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://app.localhost\"\n  }, \"app.localhost\"), \" to see your running producer or\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"http://mgmt.localhost\"\n  }, \"mgmt.localhost\"), \" to see the RabbitMQ management webapp.\"), mdx(\"p\", null, \"To deploy the same app to a remote staging or production environment, first register it with\\nArchitect Cloud:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"architect register architect.yml -t latest\"))), mdx(\"p\", null, \"Then deploy with a similar command:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"architect deploy <your-account-name>/rabbitmq:latest -a <your-account-name> -e example-environment -p QUEUE_NAME=my-queue -i app:app mgmt:mgmt\"))), mdx(\"p\", null, \"Architect Cloud will generate a deployment diff and prompt you to review it. Press \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Y\"), \" to continue\\nand deploy. Architect is now deploying your RabbitMQ stack--producer, consumer, and broker--to a\\nremote Kubernetes cluster.\"), mdx(\"p\", null, \"You can watch the deployment unfold here:\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cloud.architect.io/%3Cyour-account-name%3E/environments/example-environment/\"\n  }, \"https://cloud.architect.io/\", \"<\", \"your-account-name\", \">\", \"/environments/example-environment/\")), mdx(\"p\", null, \"While you\\u2019re waiting for that deployment to complete, you can also explore deploying this stack to\\nyour infrastructure by registering your AWS account or Kubernetes Cluster with Architect:\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cloud.architect.io/%3Cyour-account-name%3E/platforms/new\"\n  }, \"https://cloud.architect.io/\", \"<\", \"your-account-name\", \">\", \"/platforms/new\"), \".\"), mdx(\"p\", null, \"Once the deployment completes, you should be able to see the message consumer and broker running\\nlive:\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"https://app.example-environment.<your-account-name>.arc.domains/\")), mdx(\"p\", null, \"Likewise, your RabbitMQ management interface:\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"https://mgmt.example-environment.<your-account-name>.arc.domains/\")), mdx(\"small\", null, \"_Note: it takes a few minutes for new SSL certificates to propagate, so domains may appear to be insecure initially. Rest assured, they will propagate._\"), mdx(\"p\", null, \"Finally, to clean up this environment and break down your deployed services, use:\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"text\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"className\": \"language-text\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"architect destroy -a <your-account-name> -e example-environment\"))), mdx(\"h2\", {\n    \"id\": \"learn-more-about-architect-and-modern-deployment-practices\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, \"Learn More About Architect and Modern Deployment Practices\", mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#learn-more-about-architect-and-modern-deployment-practices\",\n    \"aria-label\": \"learn more about architect and modern deployment practices permalink\",\n    \"className\": \"anchor after\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  })))), mdx(\"p\", null, \"We hope you enjoyed following along!\"), mdx(\"p\", null, \"Check out our \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.architect.io/blog\"\n  }, \"other tutorials and blog series\"), \".\"), mdx(\"p\", null, \"If you'd like to play around with Architect some more,\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.architect.io/docs\"\n  }, \"check out our Docs\"), \".\"), mdx(\"p\", null, \"And don't be afraid to reach out to the team with any questions or comments! You can find us on\\nTwitter \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://twitter.com/architect_team\"\n  }, \"@architect_team\"), \".\"));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"Here at Architect, it's no secret that we love portable microservices. And what better way to make\nyour services portable than by decoupling their interactions? Today we talk about decoupling your…","tableOfContents":{"items":[{"url":"#rabbitmq-instance-with-docker","title":"RabbitMQ Instance with Docker"},{"url":"#send-messages-to-rabbitmq-from-a-producer","title":"Send Messages to RabbitMQ from a Producer"},{"url":"#receive-messages-from-rabbitmq-with-a-consumer","title":"Receive Messages from RabbitMQ with a Consumer"},{"url":"#deploy-rabbitmq-with-docker","title":"Deploy RabbitMQ with Docker"},{"url":"#deploy-rabbitmq-with-docker-and-architect","title":"Deploy RabbitMQ with Docker and Architect"},{"url":"#learn-more-about-architect-and-modern-deployment-practices","title":"Learn More About Architect and Modern Deployment Practices"}]},"frontmatter":{"title":"Implement RabbitMQ on Docker in 20 Minutes","description":"Implement a RabbitMQ message broker with a Node.js Express producer and a Python consumer. Deploy using Docker and Architect.","author":"Dan Barrett","date":"2021-01-19","image":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","images":{"fallback":{"src":"/static/e87efca12e336ce71c528a9e356e927f/7a23e/rabbitmq-docker.png","srcSet":"/static/e87efca12e336ce71c528a9e356e927f/4ca58/rabbitmq-docker.png 250w,\n/static/e87efca12e336ce71c528a9e356e927f/0251a/rabbitmq-docker.png 500w,\n/static/e87efca12e336ce71c528a9e356e927f/7a23e/rabbitmq-docker.png 1000w,\n/static/e87efca12e336ce71c528a9e356e927f/fca1d/rabbitmq-docker.png 2000w","sizes":"(min-width: 1000px) 1000px, 100vw"},"sources":[{"srcSet":"/static/e87efca12e336ce71c528a9e356e927f/002ed/rabbitmq-docker.webp 250w,\n/static/e87efca12e336ce71c528a9e356e927f/15bdf/rabbitmq-docker.webp 500w,\n/static/e87efca12e336ce71c528a9e356e927f/27c85/rabbitmq-docker.webp 1000w,\n/static/e87efca12e336ce71c528a9e356e927f/0dc98/rabbitmq-docker.webp 2000w","type":"image/webp","sizes":"(min-width: 1000px) 1000px, 100vw"}]},"width":1000,"height":563}}}}},"next":null,"previous":null}]}},"pageContext":{"slug":"rabbitmq-docker-tutorial"}},
    "staticQueryHashes": ["764694655"]}