{"componentChunkName":"component---node-modules-gatsby-theme-medium-to-own-blog-src-templates-blog-post-js","path":"/a-serverless-alternative-to-wordpress/","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://javame.netlify.app","githubUrl":"https://github.com/aterreno/blog"}},"mdx":{"fields":{"slug":"/a-serverless-alternative-to-wordpress/"},"excerpt":"In all my career I always had to battle with a  WordPress  installation, first it was my personal blog then it was the public facing website…","timeToRead":2,"frontmatter":{"title":"A Serverless alternative to WordPress","description":"In all my career I always had to battle with a WordPress installation, first it was my personal blog then it was the public facing website…","categories":[],"date":"June 13, 2018","canonical_link":"https://javame.netlify.app//a-serverless-alternative-to-wordpress-b55c628c71e2"},"body":"function _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\": \"A Serverless alternative to WordPress\",\n  \"description\": \"In all my career I always had to battle with a WordPress installation, first it was my personal blog then it was the public facing website…\",\n  \"date\": \"2018-06-13T12:07:50.287Z\",\n  \"categories\": [],\n  \"published\": true,\n  \"canonical_link\": \"https://javame.netlify.app//a-serverless-alternative-to-wordpress-b55c628c71e2\",\n  \"redirect_from\": [\"/a-serverless-alternative-to-wordpress-b55c628c71e2\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"In all my career I always had to battle with a \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://wordpress.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"WordPress\"), \" installation, first it was my personal blog then it was the public facing website of companies I worked for.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"It\\u2019s not in the scope of this post to elicit the flaws and fragility of the WordPress platform, but my main drivers as CTO of \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.thelabrador.co.uk/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Labrador\"), \" were:\"), mdx(\"h4\", {\n    \"id\": \"aligned-tech-stack\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h4\"\n  }, {\n    \"href\": \"#aligned-tech-stack\",\n    \"aria-label\": \"aligned tech stack permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\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\", _extends({\n    parentName: \"svg\"\n  }, {\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  })))), \"Aligned Tech\\xA0Stack\"), mdx(\"p\", null, \"Everything at Labrador is done in \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://nodejs.org/en/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Node.JS\"), \" and \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://reactjs.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"React.JS\"), \" not only, we leverage as much as possible Cloud (\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://aws.amazon.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"AWS\"), \"), FaaS (\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://aws.amazon.com/lambda/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Lambdas\"), \"): WordPress was far from this model and nobody in the tech team had PHP or WordPress administration skills, and, to be quite frank, nobody wanted to gain those skills.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Aligned and uniform Process\", mdx(\"br\", {\n    parentName: \"strong\"\n  })), \"Sure, there are ways to do continuous delivery and integration with WordPress, but again we didn\\u2019t want to invest into this, we wanted to use our favourite tooling and model also to promote changes for the public facing website: a local dev environment, a non-production environment, a production environment, a continuous delivery pipeline powered by our \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://concourse-ci.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"ConcourseCI\"), \" server.\"), mdx(\"h4\", {\n    \"id\": \"more-power-and-easier-integration-with-other-components\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h4\"\n  }, {\n    \"href\": \"#more-power-and-easier-integration-with-other-components\",\n    \"aria-label\": \"more power and easier integration with other components permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\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\", _extends({\n    parentName: \"svg\"\n  }, {\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  })))), \"More power and easier integration with other components\"), mdx(\"p\", null, \"The User Journey was broken down in two: you\\u2019ll be in a slow, server side rendered page on WordPress and then taken into a sign-up journey running on React.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"We wanted to offer a more streamlined web experience and no jumps between domains or pages.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"Not only, because now we own the tech stack of our site and we are comfortable with the codebase we will be faster introducing new features, such as dynamic content powered by our own APIs.\"), mdx(\"h4\", {\n    \"id\": \"so-whats-the-new-tech-stack-like\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h4\"\n  }, {\n    \"href\": \"#so-whats-the-new-tech-stack-like\",\n    \"aria-label\": \"so whats the new tech stack like permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\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\", _extends({\n    parentName: \"svg\"\n  }, {\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  })))), \"So what\\u2019s the new tech stack\\xA0like?\"), mdx(\"p\", null, \"We generate our content inside \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.contentful.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Contentful\"), \", Contentful is configured to call one of our lambdas when new content gets published, \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Gatsby\"), \" re-builds the site from scratch, publishes to \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://aws.amazon.com/s3/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"S3\"), \" and invalidates a \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://aws.amazon.com/cloudfront/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"CloudFront\"), \" Distribution.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"We are also leveraging \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://graphql.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"GraphQL\"), \" (to get the posts from Contentful) and \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.styled-components.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Styled Components\"), \" for styling the site: no more SASS or CSS, it\\u2019s all JS.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"There\\u2019s another little component: in order to serve folders we wrote a tiny Lambda that runs at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Edge\"), \" and basically rewrites the URLs (/page/ => /page/index.html).\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"As any of our other lambdas this stack is monitored with \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.iopipe.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"IOPipe\"), \" and the lambdas are configured, packaged and deployed using the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://serverless.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Serverless Framework\"), \".\"), mdx(\"p\", null, \"Architecture Diagram\"), mdx(\"h4\", {\n    \"id\": \"is-it-going-to-cost-us-more-or-less\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h4\"\n  }, {\n    \"href\": \"#is-it-going-to-cost-us-more-or-less\",\n    \"aria-label\": \"is it going to cost us more or less permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\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\", _extends({\n    parentName: \"svg\"\n  }, {\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  })))), \"Is it going to cost us more or\\xA0less?\"), mdx(\"p\", null, \"I\\u2019ve done some maths. The current hosting from \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://wpengine.co.uk/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"WP-Engine\"), \" costs about 999$ a year, that\\u2019s 2.7$ a day.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"Lambda edge costs $0.0000006 per request, in order to render the homepage we make 43 requests, it\\u2019s 1.4KB.\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"CloudFront is 0.68$ a month, assuming that the current site will consume the same bandwidth (I am sure it\\u2019s smaller), S3 will be pennies as well.\\xA0\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"So we\\u2019ll need 4.5M requests a day, that\\u2019s about 100k unique views a day on our side before the Serverless Implementation will be as expensive.\"), mdx(\"p\", null, \"So I think that it will cost way less, also, the older site wouldn\\u2019t cope with that traffic! And we\\u2019ll be really lucky if we really get so many visitors!\"), mdx(\"h4\", {\n    \"id\": \"was-it-worth-it\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", _extends({\n    parentName: \"h4\"\n  }, {\n    \"href\": \"#was-it-worth-it\",\n    \"aria-label\": \"was it worth it permalink\",\n    \"className\": \"anchor before\"\n  }), mdx(\"svg\", _extends({\n    parentName: \"a\"\n  }, {\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\", _extends({\n    parentName: \"svg\"\n  }, {\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  })))), \"Was it worth\\xA0it?\"), mdx(\"p\", null, \"Well we learnt a lot around Lambda running@Edge, Styled Components and GraphQL, \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.gatsbyjs.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Gatsby\"), \" is lovely and we\\u2019ll now make the site better and better day by day without having to swear on how slow wp-admin is and we\\u2019ll just write code instead of installing plugins. We\\u2019ll also have no worries about upgrading WordPress or security and the pages are now honestly blazing fast, like 3x times faster!\"));\n}\n;\nMDXContent.isMDXComponent = true;"},"allWebMentionEntry":{"nodes":[]}},"pageContext":{"id":"734f6512-1af6-5628-83b2-623f03ae3878","previous":{"id":"6a8d753f-2b80-5fe6-8208-87ffedc56783","fields":{"slug":"/visualise-all-things/","published":true},"frontmatter":{"redirect_from":["/visualise-all-things-82adc32bcf64"],"redirect_to":null,"title":"Visualise all things"}},"next":{"id":"fc2bdeac-1708-5625-8213-723b9251dc4a","fields":{"slug":"/real-time-data-aggregation-with-dynamodb/","published":true},"frontmatter":{"redirect_from":["/real-time-aggregation-with-dynamodb-1d4c525a4154"],"redirect_to":null,"title":"Real-time Data Aggregation with DynamoDB"}},"permalink":"https://javame.netlify.app/a-serverless-alternative-to-wordpress/","themeOptions":{"plugins":[],"config":{"title":"Antonio Terreno","description":"Antonio Terreno's blog archive","shortBio":"","bio":"Principal Consultant at Equal Experts","author":"Antonio Terreno","githubUrl":"https://github.com/aterreno/blog","siteUrl":"https://javame.netlify.app/","social":{"twitter":"javame","medium":"","facebook":"","github":"aterreno","linkedin":"antonioterreno","instagram":"tritonitri"},"goatCounterCode":null}}}},"staticQueryHashes":["4131332129","645483741"]}