{"id":2678,"date":"2021-12-21T21:58:04","date_gmt":"2021-12-21T21:58:04","guid":{"rendered":"http:\/\/10.0.0.14:5557\/?p=2678"},"modified":"2021-12-21T23:58:02","modified_gmt":"2021-12-21T23:58:02","slug":"tdd-with-gatsby-django-docker-part-2-chapter-08-setup-gatsby-development-environment-v2","status":"publish","type":"post","link":"https:\/\/tutorials.leesonresearch.com\/tutorials\/2021\/12\/21\/tdd-with-gatsby-django-docker-part-2-chapter-08-setup-gatsby-development-environment-v2\/","title":{"rendered":"Gatsby JS TDD with Django &#038; Docker, Chapter 01 &#8212; Setting up the Gatsby Development Environment V2"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">What is Gatsby JS?<\/h1>\n\n\n\n<p>Gatsby is a <em>static site generator<\/em> built on React.<\/p>\n\n\n\n<p>In this tutorial we will be building a Todo App using Gatsby, TDD (test driven development) and Docker.<\/p>\n\n\n\n<p>Gatsby will be serving the frontend of our site but we also need an API for Gatsby to pull data from. For that we are going to use Django as our API. Using Django Graphene the API will serve Graphql end points for Gatsby to consume.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><\/h3>\n\n\n\n<p>To get started we need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Install the Gatsby command line tool (CLI) on your host machine<\/li><li>Generate a Gatsby starter site<\/li><li>Delete the Gatsby Git repo<\/li><li>Mock out the frontend file structure<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Setting Up the Directory Structure<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: Double click to copy; notranslate\" title=\"Double click to copy\">\n# 1) Install Gatsby CLI on local computer\nnpm install -g gatsby-cli\n\n# 2) Generate Gatsby starter site\ngatsby new frontend https:\/\/github.com\/gatsbyjs\/gatsby-starter-hello-world\n\n# 3) Remove the Gatsby git resources since we will use our git installation at the root of our project\nrm -rf frontend\/.git\nrm -rf frontend\/.gitignore\n\n# 4) Create our frontend Dockerfile script\ntouch frontend\/Dockerfile\n\n# 5) Create a directory for Nginx to serve in production\nmkdir nginx\n\n# 6) Create a Dockerfile and nginx.conf files for Nginx\ntouch nginx\/Dockerfile\ntouch nginx\/nginx.conf\n\n# 7) Create a new Docker Compose files for production and development\ntouch docker-compose.yml\ntouch docker-compose-dev.yml\n<\/pre><\/div>\n\n\n<p>This is how our current directory structure should look:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>todo_gatsby-django-graphene (directory root of the project)<ul><li>frontend (directory)Dockerfile<\/li><li>nginx (directory)<ul><li>Dockerfile<\/li><li>nginx.conf<\/li><\/ul><\/li><li>server (the Django Graphene app we created in Part 1)<\/li><li>docker-compose.yml<\/li><li>docker-compose-dev.yml<\/li><li>.env<\/li><li>.gitignore<\/li><li>Makefile<\/li><\/ul><\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Populate the Frontend Files<\/h4>\n\n\n\n<ol class=\"wp-block-list\"><li>Our goal is to build a todo application with Gatsby as our frontend which will interface with the Django Graphene server we built in Part 1 of this tutorial. We start by installing the Gatsby CLI on our local computer which is the main entry point for setting Gatsby up on our computer.<\/li><li>We created a new Gatsby project using the Gatsby Hello World starter site which we renamed to <strong>frontend<\/strong>.<\/li><li>When Gatsby generated its own git repo which we don&#8217;t need since we already have our git repo at the root of our project. We also deleted the .gitignore from the <strong>frontend<\/strong> directory.<\/li><li>Create our <strong>frontend<\/strong> Dockerfile to configure the Gatsby env.<\/li><li>Create a directory for nginx.<\/li><li>Create a nginx\/Dockerfile and nginx\/nginx.conf file to configure Nginx server for our production build.<\/li><li>Create two Docker Compose files, one for deploying our Gatsby build to nginx which will serve our site using <a rel=\"noreferrer noopener\" href=\"https:\/\/medium.com\/@quinn.royston\/server-side-rendering-213f66b27229\" target=\"_blank\">SSR, (server side rendering)<\/a>, which comes with the Gatsby build.<\/li><\/ol>\n\n\n\n<p>Next we populate the frontend Dockerfile with instructions on how to build the Gatsby image.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Frontend Dockerfile<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: Double click to copy; notranslate\" title=\"Double click to copy\">\n# frontend\/Dockerfile\n\n# 1)\nFROM node:16-alpine\n\n# 2)\nEXPOSE 8000\n\n# 3)\nWORKDIR \/frontend\n\n# 4)\nRUN apk update &amp;amp;&amp;amp; apk add python3 g++ make &amp;amp;&amp;amp; rm -rf \/var\/cache\/apk\/*\n\n# 5)\nRUN npm install -g gatsby-cli\n\n# 6)\nCOPY . .\n\n# 7)\nRUN npm install\n\n# 8) Building Gatsby generating public directory that can be copied to Nginx service in production\nCMD &#x5B; &quot;gatsby&quot;, &quot;build&quot; ]\n<\/pre><\/div>\n\n\n<ol class=\"wp-block-list\"><li>Using node:16-alpine image we build our node environment. I&#8217;m specifying node version 16 here because Gatsby requires a minimum of node 14 for Gatsby 3.14.4 which is the latest version at the time of writing this blog. I found that Gatsby<\/li><li>Open a port on the frontend container.<\/li><li>Set the working directory with the WORKDIR Docker command. <strong>Doing this in one of the first layers is very important otherwise when we run npm install Gatsby will be installed at the root of the container instead of the working directory frontend. When we try running Gatsby commands such as Gatsby build, an error will be thrown saying that Gatsby is not installed. Declaring the WORKDIR early fixes this problem.<\/strong><\/li><li>Since Node.js is built with node-gyp which is written in Python we need Python installed. You can read more about this Python requirement for GYP <a rel=\"noreferrer noopener\" href=\"https:\/\/stackoverflow.com\/questions\/23709739\/why-does-node-js-need-python\" target=\"_blank\">here<\/a>.<\/li><li>Install Gatsby CLI.<\/li><li>Copy the contents of the frontend directory on the host machine into the frontend container that we are building. Note that in step 3 when we set the working directory with WORKDIR, Docker creates the frontend directory for us and cd into the frontend directory so all the subsequent commands are executing in the frontend directory.<\/li><li>Install all the packages defined in the package.json file.<\/li><li>Using the Dockerfile CMD we define the default command to set Gatsby into production mode which will serve the production build from the \/www\/public.<\/li><\/ol>\n\n\n\n<p>Next populate the Nginx Dockerfile.<\/p>\n\n\n\n<p>Before we can build our frontend Gatsby image we need to update the docker-compose.yml file populated.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Docker-Compose.yml<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: Double click to copy; notranslate\" title=\"Double click to copy\">\n# docker-compose.yml\n\nversion: '3'\n \nservices:\n    database:\n        container_name: postgres\n        image: postgres:latest\n        environment:\n            - POSTGRES_DB=$DATABASE_NAME\n            - POSTGRES_USER=$DATABASE_USER\n            - POSTGRES_PASSWORD=$DATABASE_PASSWORD\n            - POSTGRES_PORT=$DATABASE_PORT\n        volumes:\n            #- .\/server\/initial.sql:\/docker-entrypoint-initdb.d\/initial.sql\n            - .\/server\/db_backups\/backup.sql:\/docker-entrypoint-initdb.d\/backup.sql\n            - postgres-data:\/var\/lib\/postgresql\/data\n \n    server:\n        build: .\/server\/\n        container_name: dj02\n        working_dir: \/var\/www\/server\n        ports:\n            - '$SERVER_PORT:$SERVER_PORT'\n        volumes:\n            - .\/server\/:\/var\/www\/server\n        command: python manage.py runserver 0.0.0.0:$SERVER_PORT\n        environment:\n            - DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE\n            - PGHOST=$DATABASE_HOST\n        env_file:\n            - .env\n        depends_on:\n            - database\n\n    \n    # 1)\n    frontend:\n        # 2)\n        build:\n            context: .\/frontend\n            dockerfile: Dockerfile\n        # 3)\n        ports:\n            - 8000:8000\n        # 4)\n        volumes:\n          - .\/frontend\/:\/frontend\n        # 5)\n        container_name: frontend\n        # 6)\n        depends_on:\n          - server\n\nvolumes:\n    postgres-data:\n<\/pre><\/div>\n\n\n<p>With the docker-compose.yml file we are defining the backend service infrastructure (database and server) which we built in part I of this tutorial as well as our new frontend Gatsby service.<\/p>\n\n\n\n<p>Lets look at the frontend service in detail:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Name of service.<\/li><li>Tell docker-compose where the Dockerfile is for the frontend service.<\/li><li>Map the outside port 8000 to port 8000 the container&#8217;s port.<\/li><li>Map the \/frontend files from the frontend container onto our host machine which allows us to edit and save files from our host machine dynamically updating the files in the frontend container and triggers a browser hot-reload.<\/li><li>Give the container the name frontend<\/li><li>Using depends_on tell the frontend to wait for the server to finish launching<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Development Docker Compose Override<\/h3>\n\n\n\n<p>To run Gatsby in development mode we override the docker-compose file with the docker-compose-dev file.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: Double click to copy; notranslate\" title=\"Double click to copy\">\n# docker-compose-dev.yml\nversion: '3'\n\nservices:\n  frontend:\n    # 1)\n    command: gatsby develop --host 0.0.0.0 --port 8000\n<\/pre><\/div>\n\n\n<ol class=\"wp-block-list\"><li>The command: develop &#8211;host 0.0.0.0 &#8211;port 8000 sets Gatsby in development mode<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Building the Frontend Service<\/h3>\n\n\n\n<p>With  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is Gatsby JS? Gatsby is a static site generator built on React. In this tutorial we will be building a Todo App using Gatsby, TDD (test driven development) and Docker. Gatsby will be serving the frontend of our site&#8230; <a class=\"more-link\" href=\"https:\/\/tutorials.leesonresearch.com\/tutorials\/2021\/12\/21\/tdd-with-gatsby-django-docker-part-2-chapter-08-setup-gatsby-development-environment-v2\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2678","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/posts\/2678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/comments?post=2678"}],"version-history":[{"count":13,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/posts\/2678\/revisions"}],"predecessor-version":[{"id":2692,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/posts\/2678\/revisions\/2692"}],"wp:attachment":[{"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/media?parent=2678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/categories?post=2678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tutorials.leesonresearch.com\/tutorials\/wp-json\/wp\/v2\/tags?post=2678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}