DigitalOcean App Platform Deployment
Building A Travel Guide With Gatsby, Neo4j, & GraphQL: Part 5
We take a look at deploying our Neo4j GraphQL API and Gatsby site using DigitalOcean's new App Platform service!
Links And Resources#
- Hey everyone. 01:51 Welcome to the Neo4j stream. 01:53 My name is Will. 01:55 And 01:56 today we are 01:59 continuing working 02:01 on our Gatsby Neo4j 02:04 and GraphQL Travel Guide. 02:09 So just picking up from where we left off last time. 02:15 Let's review just where we are 02:18 at this point real quick. 02:19 I'll drop the link to the GitHub repo 02:24 in the chat. 02:29 There we go. 02:34 And 02:38 where we left off last time, 02:40 so we've been working 02:41 on this travel guide application. 02:46 If we look at the code, 02:48 we can see there are basically two pieces 02:52 to our application. 02:55 We have 02:59 the Neo4j-GraphQL, GraphQL API. 03:04 And this is using 03:06 the Neo4j-GraphQL JS package 03:10 to build a GraphQL API, 03:13 talking to a Neo4j sandbox instance 03:16 or using the OpenStreetMap Neo4j sandbox instance. 03:21 Let me drop a link to that 03:26 in the chat as well. 03:27 So this link will directly open 03:32 a OpenStreetMap instance. 03:40 Looks like there might be 03:42 an issue with posting 03:46 in the chat. 03:49 Let's restart 03:52 my chat app. 04:01 Hopefully that helps. 04:07 Let's try that again. 04:08 Okay, here's the link 04:10 to the Neo4j sandbox or OpenStreetMap, 04:15 hopefully you get that. 04:17 Okay, so we have this inverted GraphQL API, 04:23 where we're basically exposing points of interest. 04:27 You can see we have this point 04:29 of interest type here 04:31 and this is running locally right now. 04:36 So we query that on Localhost 04:40 3003 04:43 That is an old query. 04:45 Zoom in a little bit. 04:48 You can see the entry points. 04:50 We have points point of interest. 04:56 So I can search for points 04:57 of interest by name. 05:00 Look at the first three. 05:05 I can retrieve 05:09 any tags for the point of interest 05:12 in this tag data, 05:13 this comes from OpenStreetMap. 05:17 We also added 05:20 pulling in data from Wikipedia. 05:21 So we have a Wikipedia field there 05:25 that I can pull in data from Wikipedia 05:28 and then we also have photos 05:30 that we've added 05:33 from Mapillary. 05:39 Rights and, we need to add latitude 05:43 and longitude to our selection set 05:45 if we want to use photos, 05:49 because we are relying 05:51 on our custom resolver, 05:55 which we've defined here, 05:58 to have access to latitude and longitude, 06:02 to call the Mapillary API. 06:04 Okay, so we have that data 06:07 for these points of interest. 06:09 Last time, we added the ability 06:12 to do routing between points of interest. 06:16 So if I also return the node OSM ID, 06:21 so that's the ID, 06:24 referencing the point of interest. 06:27 So let's copy this one. 06:29 And now if I want to route 06:31 from the Jacqueline Kennedy Onassis reservoir 06:40 to the, 06:44 what was this one? 06:45 the conservatory water. 06:52 I can add that 06:53 to the GraphQL selection sets. 06:55 And behind the scenes, 06:58 we are using the graph Data Science Library. 07:03 Here, 07:05 the shortest path algorithm, 07:08 which by default is Dykstra's algorithm 07:11 to find the shortest path 07:14 between these two points of interest in Central Park. 07:18 So we have that data in a GraphQL API 07:21 that we've exposed. 07:23 And what we want to do is pull that 07:27 into Gatsby. 07:29 So we have a separate project here, 07:34 which is our Gatsby application, 07:37 which also should be running, 07:40 have that running in this tab here. 07:47 So Gatsby uses a GraphQL API 07:53 to pull in all of its content 07:58 and so we can see here. 08:06 if we look at the Gatsby GraphQL API 08:12 that we have stitched 08:13 in our GraphQL API 08:17 that we've exposed from Neo4j, 08:19 under this poi field. 08:23 So here, under the poi query field, 08:26 we have the point of interest field available, 08:34 which is basically just running queries 08:36 against this GraphQL API. 08:37 So Gatsby makes it really easy 08:39 if you have data in a GraphQL API to pull that in, 08:43 we're using the, look in the gatsby-config, 08:48 we're using the Gatsby source GraphQL, 08:53 I think it's called, yeah, 08:54 here it is the Gatsby source GraphQL plugin 08:58 to essentially stitch in our own GraphQL API 09:01 into the Gatsby API, 09:03 which we can then use to populate our site. 09:07 So we started off 09:08 with the Gatsby starter blog. 09:12 Which is why this kind of looks like, 09:14 we expect to see a list of blog posts here 09:17 and we click on one of these 09:19 we see details for the point of interest we selected. 09:25 These are the tags that we have 09:27 from OpenStreetMap. 09:31 And then we have the data 09:31 that we pulled in from Wikipedia 09:34 for each of our points of interest. 09:37 Cool, so that's where we left off. 09:40 The last session was all about efficient routing09:45 with graph algorithms. 09:46 So we took a look at cipher shortest path, 09:50 we took a look at the algorithms 09:53 in the graph Data Science Library for routing, 09:55 so Dykstra and A-star specifically, 09:58 and we took a look at the Neo map, graph app 10:02 for Neo4j desktop 10:03 that allows us to visualize spatial data. 10:06 So the recordings are available. 10:10 Here again, I'll link 10:11 the GitHub repo 10:15 in the chat. 10:20 Cool, so what I want to do today 10:24 is take a look at how we can deploy our application. 10:28 And I thought this would be a good time 10:32 to look at a brand new product 10:36 from DigitalOcean 10:38 that was released just a couple days ago, 10:42 earlier this week called DigitalOcean App Platform. 10:50 So what we're going to do today is see 10:52 how we can use 10:54 this new DigitalOcean App Platform service 10:57 to deploy both our Neo4j-GraphQL API, 11:04 and then also to deploy our Gatsby site. 11:13 So with that, 11:16 let's dive right in. 11:22 Cool, so we have 11:25 our site running locally, 11:27 both the Neo4j-GraphQL. API, 11:30 and the Gatsby project. 11:34 And what we want to do is 11:36 deploy this somewhere 11:38 so that it's accessible 11:40 from some from some domain. 11:43 So we're going to take a look 11:44 at this new DigitalOcean App Platform, 11:47 which if we look at the the announcement, blog post, 11:50 let me link the announcement blog post 11:56 in the chat there. 11:59 Basically, what this is, 12:02 is sort of a managed solution 12:07 for building and deploying applications 12:12 that basically gives you 12:15 platform specific containers. 12:18 So it looks like we can connect GitHub repositories, 12:22 does some detection of hey, is this a NodeJs app, 12:27 is this a static site, 12:29 and then allows us to deploy those 12:32 as web services, or static sites, 12:36 which we can then scale 12:40 up and down 12:41 as we need. 12:43 And there's a fixed cost with these. 12:45 So as as kind of a 12:50 the opposite direction of serverless, 12:54 where we're sort of our costs are dependent 12:59 on usage, where we're sort of paying per invocation, 13:03 looks like without platform, 13:04 we have a fixed, understood cost 13:07 and I guess, as we scale our application, 13:10 adding more containers, 13:12 then I guess the cost goes up, 13:14 we're linearly there, perhaps. 13:18 So I should say, 13:18 I don't know much about this service yet. 13:22 It just came out a couple days ago 13:25 but I like DigitalOcean. 13:26 So let's, 13:28 let's give it a try. 13:29 So I'm going to sign into 13:32 a DigitalOcean account. 13:40 Cool, looks like Maria signed in. 13:44 These are my projects. 13:48 I'm interested in apps. 13:54 So like apps, there we go. 13:58 And it says launch your app. 14:02 Let's um, 14:04 let's bring up the documentation. 14:10 Slash docs. 14:14 So if you're not familiar with DigitalOcean, 14:16 DigitalOcean is a cloud provider. 14:20 So you can think of something like 14:24 what AWS or Google Cloud Platform or Azure, right, 14:28 so Cloud Platform along those lines. 14:32 And I think DigitalOcean has focused 14:37 on sort of developer simplicity. 14:39 So they don't have as many services 14:42 as AWS, right, AWS has a service 14:45 for pretty much everything 14:48 but if you've ever used the AWS console 14:51 or the AWS CLI, there can be a bit 14:57 bit of a overhead in understanding 15:01 how to properly use those services. 15:04 Whereas DigitalOcean's approach, 15:06 I think has been, you know, 15:07 let's, let's limit the number of services, 15:12 number of offerings that we have 15:14 but let's focus on just really 15:16 a dead simple developer experience. 15:19 So a very user friendly to use cloud services. 15:23 This maybe a way to think of DigitalOcean. 15:27 So I think when I first started using DigitalOcean, 15:30 the only service they had were Droplets, 15:32 which were, which are sort of VPS. 15:37 So virtual private servers. 15:41 They've since added several other services, 15:45 including, you know, Block Storage, Kubernetes. 15:50 So we can, we can create Kubernetes clusters 15:55 on DigitalOcean. 15:56 They now have a Managed Database service 15:59 and then the newest product that they have, 16:03 as of this week is App Platform. 16:08 Cool from the chats, 16:11 what a coincidence, 16:12 actually planning on setting up Neo4j today, 16:14 great to work with my Flask app on DigitalOcean. 16:18 Flask running just we need setup 16:21 and connect it's Neo4j. 16:22 Cool, great. 16:23 Yeah, I think for development, 16:28 you might want to think about initially 16:30 just connecting that to Neo4j sandbox. 16:35 Which sandbox instances only live 16:39 for initially, three days, 16:43 you can extend them up to a week, I think 16:46 but it's an easy way just to get started. 16:48 And then Neo4j Aura is a manager Neo4j service 16:59 that you might also be interested in, 17:04 that allows you to basically just click 17:07 a couple of buttons 17:08 and then have a Neo4j cluster deployed 17:10 and managed for you. 17:13 Later on in the stream, 17:14 I think we'll take a look at 17:16 how we can deploy a Neo4j cluster ourselves. 17:21 Maybe maybe using 17:22 the DigitalOcean Kubernetes Service, 17:27 that might be something interesting to look at 17:29 but for today, 17:32 we'll focus on deploying our GraphQL application 17:36 and the Gatsby site 17:38 since we already have the Neo4j instance 17:41 that we want to use in Neo4j sandbox. 17:47 Cool. 17:52 So with App Platform, 17:54 if you look at the Quickstart here, 17:57 basically what we do is pointed 18:01 at a GitHub repository, 18:04 does some inference then 18:07 to figure out what 18:11 what type of project we have, 18:14 we can scale it, deploy it, 18:15 set up a custom domain, and so on. 18:19 So there's lots of different languages 18:21 and frameworks. 18:22 We can even just write our own Docker file, 18:25 if we want to deploy that. 18:30 Let's look at concepts. 18:32 So we can come back to this if we need to 18:38 but I think basically what's going on here is 18:41 our application is getting its own container, 18:47 or maybe multiple containers here. 18:50 And we're sort of configuring 18:52 how we want our application 18:55 to be built. 18:57 Yeah, and and as you're pointing out 19:00 in the chat, Abdul, 19:02 yeah, they only support GitHub currently. 19:05 I saw though the the the plans are 19:08 to add GitLab 19:12 and other hosted 19:15 get services as well. 19:18 So I think that's, I think that's on the roadmap. 19:20 I'm sure there are, you know, some initial features 19:23 they wanted to, to roll out 19:25 but since this, you know, 19:27 just launched a couple days ago, 19:30 there may be some things not quite included yet. 19:34 So we'll see, 19:35 see what we can, what we can find today. 19:39 Okay, so there's the docs 19:40 if you need to check those out, 19:41 but let's go ahead and launch an application. 19:48 And so let's see, 19:51 I can choose a repository. 19:53 I've already connected my GitHub user, 19:57 so that's cool. 19:58 I can dig into that. 20:00 Let's let's maybe let's choose 20:02 a demo application to launch here initially, 20:05 before we try to deploy our Gatsby project, 20:09 just to see how this works. 20:10 So we'll choose the NodeJs project, 20:13 give it a name, choose a region. 20:18 As soon as is pointed 20:19 at some template GitHub project 20:25 yep, NodeJs, okay, cool. 20:28 That's the web pack you'll use, I guess, 20:31 with a, to build, whats the right terminology there , 20:35 the BuildPack. 20:37 That's (indistinct). 20:39 Right , so the BuildPack defines 20:43 the language and framework 20:45 and how it gets built. 20:50 Many of which came from Heroku. 20:53 It make sense. 20:58 Okay, so a web service or static site, 21:00 this is a web service, 21:02 you can pass environment variables. 21:05 Build Command, we don't need to worry about. 21:07 I can got going to connect database. 21:12 Give that a deploy. 21:15 So because this is a web service, 21:19 it's not on the free tiers. 21:21 Looks like the free tier is just 21:23 for static content, okay. 21:27 So it's gonna be basic. 21:30 We can just do one container, 21:33 we can choose the size of the container. 21:38 Let's choose the smallest 21:41 and give that a deploy. 21:43 So this is just going to deploy 21:45 whatever the sample application is. 21:52 While this is building, 21:53 let's take a look at the logs. 21:58 So notice, BuildPack, 22:03 installing some packages 22:10 and 22:13 building a Docker container, it looks like. 22:22 What else do we have look at here? 22:24 So on overview. 22:26 So we can look at some metrics once it's deployed. 22:31 Insights. 22:33 I guess, these are the metrics. 22:35 Yeah, but we don't have any data for 22:37 since it hasn't been deployed yet. 22:41 History of our deployments. 22:47 No runtime logs, 22:49 because we're still deploying, yep. 22:51 No Console. 22:54 Okay, the Components. 22:55 So Scaling, so here, 22:57 I guess we can add more containers, 22:59 Environment variables, Http routes we want to expose. 23:04 Oh yeah, the Health Checks. 23:05 Yeah, so the health checks. 23:06 This is important, I guess, 23:07 when we have multiple containers 23:11 so when we're scaled horizontally, 23:15 I guess we have multiple containers, 23:18 there's some load balancer here, 23:20 that's sending health checks 23:21 to the different containers to make sure that 23:24 the container is online 23:27 and healthy before sending it a request, 23:30 which makes sense. 23:32 The commands to build and start it 23:35 and then the HTTP port. 23:37 So this is going to be whatever port 23:38 our service application is listening on. 23:42 This is going to be routed to 443 23:47 or 80 for the public requests. 23:54 Okay, it says it's deployed. 23:56 Let's take a look. 23:58 So we get our own subdomain 24:04 on the on DigitalOcean.app domain. 24:06 Cool. 24:08 So I guess this is going to be specific 24:10 for each one of our deployments, which is nice. 24:12 So other services have this 24:15 this sort of preview deploy, 24:19 where we can trigger a deployment on based 24:24 on some pull request, 24:25 or maybe some specific branch, 24:28 and then share that with our boss 24:31 or with with someone 24:32 who doesn't want to build the whole application 24:35 just to see how it works. 24:36 The other thing that's really nice here is 24:37 we we get the certificates managed 24:41 for us so you get an HTTPS.end points. 24:45 Yeah as as you're pointing out in the chat, Abdullah, 24:48 very similar to Heroku. 24:51 Okay yeah. 24:52 It's good observation. 24:54 So this app is looks 24:57 like it's generating random words. 25:01 If I if I refreshed, I get different 25:05 contents no. 25:07 Okay, cool. 25:09 We can now 25:12 that we have it running, 25:14 do we see runtime logs? 25:17 Yes, so there's the app starting, 25:21 some ASCII arts and then the logs 25:24 if you go to the console, 25:25 and here we can see, 25:28 yeah, there we go. 25:29 So this is basically giving us a terminal 25:32 in the container. 25:33 We can take a look at the readme. 25:42 Yeah, so this is how to deploy this as an app. 25:48 Can we look at the code? 25:50 So app.js, index.js. 25:54 Let's see what this is. 25:56 So this is an Express app. 26:05 Mounting some logging. 26:10 And 26:17 index router. 26:19 There's also a user's route 26:22 that's commented out. 26:24 Okay, so the index router. 26:26 Where does that come from? 26:30 Routes index. 26:34 Routes. 26:38 Index.js. 26:40 Oh, yeah, here we go. 26:41 Here's our bunch of functions 26:44 to randomly generate somewhere words. 26:50 Oh yeah in the schools. 26:51 We have a list of adverbs., 26:56 adjectives, 26:59 verbs, 27:00 okay, cool. 27:01 And so we're sort of randomly selecting 27:03 from like, noun, adjective, 27:07 noun, adverb, verb kind of thing for sentences. 27:10 Okay, that's clever. 27:12 Cool. 27:14 Okay, so neat. 27:18 Let's deploy our Gatsby application. 27:24 So let's create app, choose a repository. 27:26 So I've already 27:29 authorized GitHub. 27:30 So I have it in the central-perk repo. 27:38 And you can call it central-perk. 27:41 Region is fine. 27:42 There's only one branch. 27:44 Auto Deploy code changes, this is really nice. 27:46 So this allows us to do sort of GitOps 27:49 where we push up something 27:52 to GitHub in this case, 27:54 and then that triggers a deployment. 27:56 Cool, that's nice. 27:59 Okay, configure your app. 28:00 App detection failed, we're sorry 28:03 that weren't able to detect anything 28:05 with the app platform concurrently run 28:07 in the repository you selected. 28:10 Please try a different repository. 28:14 Okay, so I think what's going on there, 28:17 if we look at our code, 28:20 if we look at our code here, 28:22 we kind of have two separate applications 28:25 in here, right? 28:27 So the, the terminology for like 28:28 what you would call this as I guess, a mono repo, 28:32 where we have one repository 28:33 that has our Neo4j-GraphQL API code. 28:39 So this is an NodeJs-Express application. 28:45 Well, NodeJs application 28:47 at least serving a GraphQL endpoint. 28:52 And then we have kind of a separate project 28:58 that is our Gatsby project. 29:01 So it looks like we can't point 29:06 at a specific folder 29:09 and say, hey, deploy this separately, 29:13 but instead, we need 29:14 a separate repository. 29:19 So let's break these out 29:23 into two repositories. 29:26 I guess we could also, 29:28 if we look here for what languages 29:31 and frameworks are supported, 29:34 I guess we could write our own Docker file 29:39 and use that to deploy both of these maybe 29:44 but don't want to do that. 29:45 So let's create 29:50 a new repo. 29:54 And we'll call this central-perk API. 30:11 and upload existing file. 30:18 Ooh, can we just be lazy 30:20 and do this from the web? 30:22 Let's see. 30:23 JS files. 30:26 Central-perk. 30:29 Gatsby site. 30:34 Just is I guess I don't have a read me. 30:37 That's fine. 30:40 So I'm just pulling out our Neo4j-GraphQL. 30:45 project from inside our mono repo. 30:51 Which knows up. 30:54 Commit failed, oh no. 30:58 What happened there? 31:02 GitHub central-perk. 31:04 We can't just do it 31:05 from the web UI. 31:11 Not sure. 31:13 I've never I've never actually uploaded files, 31:19 ever uploaded files like this and GitHub before. 31:28 Okay, cool. 31:29 That worked. 31:30 Let's add a readme. 31:34 Add some content to that later. 31:36 That's fine. 31:41 Yeah, I see some discussion in the chat 31:43 about Heroku. 31:46 Yeah, definitely use Heroku before 31:50 for lots of projects, 31:56 pluses and minuses there yeah. 32:04 Okay, so do we need 32:06 to do anything else here 32:07 to try to deploy the API part of our application? 32:10 I don't think so. 32:11 I think we can go back to DigitalOcean 32:16 and try a different repository. 32:28 Let's see. 32:29 Does it find? 32:31 Let's, let's start this again. 32:36 So maybe it needs to refresh, 32:40 my GitHub repos. 32:42 Since I just created a new one. 32:45 Actually, what did I call it? 32:47 Central-perk API. 33:02 Give it access to all repos, yes. 33:15 Central-perk API. 33:21 So just fiddling 33:24 with the GitHub permissions there. 33:27 Okay, there it is. 33:28 This is the one I want to deploy. 33:35 Region, actually what regions are available? 33:38 Okay, so New York 33:39 or a couple in Europe. 33:41 Okay. 33:43 Main branch, Auto Deploy. 33:45 Yes, we want to do that. 33:50 Okay, so now it says, 33:53 this is a NodeJs app. 33:55 Web Service. 33:56 Yes, since this is going to be a GraphQL API. 34:00 And now we do need 34:01 to add some environment variables. 34:05 So if we look, here, 34:14 we have some environment variables 34:17 to connect to need are Neo4j sandbox instance. 34:21 So we want, Neo4j URI is this. 34:31 And then for Neo4j user, 34:35 let's create a read only user, 34:39 so I'm going to switch to 34:40 our sandbox instance 34:41 and jump into Neo4j browser. 34:45 So the user that we get here 34:48 in the sandbox UI and our connection details. 34:52 This is an admin user 34:55 but let's create a read only user 35:00 so that when we deploy this, 35:02 someone can't mess around with our data. 35:07 So colon server user add. 35:14 What should we call this? 35:17 Let's just username OSM for OpenStreetMap. 35:24 And we'll give it just the role of reader. 35:28 So the only thing this user will be able to do is, 35:36 is reading data from the database. 35:42 So if we go to Neo4j user is OSM, 35:51 Neo4j password is OSM 35:53 and then 35:56 the Mapillary key is this. 36:00 So Mapillary key we're using 36:02 to fetch photos from the Mapillary API. 36:07 Build Command, there's no build command 36:10 since we're not using any transpolation or anything. 36:14 NPM start. 36:15 I think, 36:17 if we look at package JSON, 36:21 NPM start, 36:23 now this really be start dev or something. 36:25 So we're doing nodemon. 36:28 Nodemon is good for watching. 36:32 So if we're, if we make some changes to a file, 36:36 it will restart 36:37 but we don't need to do that. 36:41 Here, it can actually kind of slow things down 36:45 for a deployed app. 36:49 So we can just do node index.js, 36:53 and then the HTTP port. 36:55 So this is the port 36:56 that our GraphQL server is listening on 37:00 that then gets routed 37:03 to the requests coming in 443 37:09 or Port 80, that the load balancers is taking care of. 37:13 I think we hard coded this in our application. 37:18 Yeah, so we hard coded this, 37:21 to listen on port 3003. 37:26 So 37:29 we will listen on port 3003. 37:33 Okay, I think that is all the configuration we need to do. 37:39 So what's the difference 37:41 between basic and pro here? 37:43 So per minute application metrics, okay. 37:47 So if we do pro we get more metrics, 37:53 horizontal scaling, 37:56 so I'm guessing, adding containers, high availability. 38:01 So if we can have multiple instances 38:04 of our container, 38:06 and then it's highly available, 38:08 because if one goes down, 38:12 the load balancer will route to the other one, okay. 38:16 Oh, yeah, let's go ahead. 38:17 We'll, we'll take this down in a second. 38:20 Let's go ahead and select Pro 38:22 and, sure, let's go., 38:26 let's go all out 38:27 and we'll set up three containers 38:32 that are going to serve our API, why not? 38:41 Okay, so take a look at the logs. 38:51 We got the environment variables, 38:56 installing 38:59 some packages 39:07 and uploading our Docker image. 39:28 Okay, it's built our image. 39:35 While we're waiting, 39:37 is there anything in the docs about 39:41 the architecture that this runs on? 39:43 I'm curious. 39:44 I imagine there's 39:46 some sort of Kubernetes architecture under 39:52 under the hood here that's supporting all of this. 39:59 Oh, there's also a command line tool. 40:01 That's interesting. 40:04 Doctl. 40:07 Cool. 40:08 So we can create our apps from the command line 40:11 as well. 40:13 It's nice, It's handy. 40:15 But what did I say? 40:16 I want to know 40:19 how this runs under the hood. 40:25 I guess this is a good point. 40:26 So when should I not use that platform? 40:35 App Platform is optimized for ease of deployment. 40:39 That makes sense, rather than deep customization 40:41 of the underlying infrastructure. 40:44 If you require more control 40:46 over your production environments, 40:49 think about using DigitalOcean Kubernetes, 40:51 which we talked about, 40:53 or your own droplets, your own VPS. 40:59 Yeah, okay. 41:00 Makes sense. 41:08 Just a minute, so okay, cool. 41:10 See if that's deployed. 41:11 Deploy successful. 41:13 Okay, cool. 41:14 So here's the URL for our graph. qL API. 41:20 Take a look at GraphQL playground 41:25 we have 41:30 interests, name, type, 41:34 location. 41:39 Great. 41:41 Cool. 41:42 So that works. 41:43 Excellent. 41:45 The next thing we want to do is 41:48 deploy our Gatsby site 41:53 and point it at this API. 42:01 I guess we need to create 42:04 a new app to do that. 42:09 And we need a new GitHub repository. 42:14 So I don't think our 42:20 I don't think our mono repo approach is going to work 42:25 with App platform, at least for now. 42:28 That's fine. 42:29 We can create central-perk-gatsby. 42:44 And 42:48 can we upload our files again? 42:51 Let's let's try this because 42:56 because I'm lazy. 43:03 I don't want... 43:06 Some of these are... 43:07 I don't want to check in node modules. 43:12 Some of this is built as well. 43:15 Yeah, let's not be lazy. 43:16 Let's 43:20 let's 43:24 do this on the command line. 43:30 So let's 43:34 copy 43:41 Gatsby site 43:43 to a new directory. 43:50 We call this central-perk-gatsby. 43:59 Copy that out of our mana repo 44:02 and then we'll create a new Git repo locally, 44:07 make a commit and then push that up 44:10 to our new GitHub repo. 44:13 And then we should be able 44:14 to deploy that on App Platform. 44:24 So it's interesting if looking at app platform, 44:27 if you look at some of the other similar services, 44:31 you know, folks are comparing this to Heroku, 44:33 which I think is a good one, 44:35 if you look at some of the newer services like Netlify, 44:40 or Percell, which are very much focused 44:43 on certainly static content, for sure, 44:48 we can deploy static sites on Netlify 44:52 and there's a Netlify CDN 44:55 but we can also do serverless things as well. 44:58 So With Netlify functions, 45:01 we can deploy serverless functions. 45:04 In one of our previous projects on the stream, 45:07 if you remember, 45:09 we deployed this on Netlify. 45:12 This was Willow which was 45:15 our real estate search app. 45:20 And we deployed this on Netlify 45:24 using a lambda function 45:30 for our GraphQL API, 45:36 which is in here. 45:40 Source functions. 45:44 Right. 45:45 So here, we use Apollo server lambda, 45:47 to do this on Netlify, 45:49 which doesn't allow us to deploy arbitrary containers 45:53 but does give us the ability to deploy functions. 45:55 So in this case, we're deploying a container 45:59 on App Platform, 46:03 which is serving express app. 46:06 So I wonder, 46:07 I wonder how we could do sort of the equivalent 46:10 sort of Functions as a Service on DigitalOcean, I guess. 46:17 I guess, that doesn't fit 46:20 into their current product offering. 46:23 Maybe maybe I haven't looked at that enough. 46:25 Anyway, okay. we've copied those files. 46:27 So let's CD to GitHub at Montana, 46:35 central-perk-gatsby, 46:39 create a new Git repo. 46:46 Add everything, git commit. 46:51 Initial commit. 46:55 And connect that 47:01 to GitHub. 47:09 And push it up. 47:17 And there it is on GitHub. 47:20 So it still has the readme 47:21 for the blog starter. 47:23 It's fine. 47:27 Okay, cool. 47:27 So now let's jump back 47:29 to App platform. 47:34 Create app. 47:37 And oh, yeah, 47:38 I need to change GitHub permissions 47:41 because I only gave it access 47:44 to one 47:49 repository. 47:50 Let's add central-perk-gatsby. 48:10 And let's deploy a central-perk-gatsby. 48:18 Regions fine name is fine. 48:20 Auto Deploy, there's only one branch. 48:22 Great. 48:24 And cool. 48:25 So Gatsby detected. 48:26 So if we look at the docs, 48:28 languages and frameworks, 48:29 I guess Gatsby is one of these BuildPacks that it has. 48:35 Yep. 48:36 So it knows 48:37 how to build Gatsby sites out of the box. 48:40 That's nice. 48:43 Okay, environment variables. 48:45 Do we need to set any environment variables? 48:49 Well, if we look at our Gatsby site 48:52 and in Gatsby-config. 49:00 Here, as I mentioned earlier that 49:02 we're using Gatsby source GraphQL plug in, 49:05 to stitch in the Neo4j-GraphQL API. 49:10 And we just have that hard coded here. 49:13 So we want to change this 49:16 to an environment variable 49:17 that we can specify 49:24 via an environment variable what API to pull in. 49:30 Let's, let's just change this on GitHub. 49:33 Let's make this easy. 49:37 And gatsby-config. 49:44 Edit. 49:49 And here 49:53 we want this to be process.env. 50:00 Let's call it 50:02 Neo4j-GraphQL API. 50:15 So then variables will specify Neo4j-GraphQL API, 50:22 and that is going to be this URL. 50:32 It's important to note, I guess that 50:34 this URL is is specific for this deployment. 50:38 I'm assuming if I do a new deployment, 50:41 I get a different URL 50:42 with maybe where this hash changes. 50:46 So we should think about setting up 50:49 a custom domain for our API. 50:54 So that this will live 50:55 through multiple deployments. 50:56 I know I'm just assuming that's 50:57 that's specific to this deployment, 50:59 you want to check that 51:00 but anyway, 51:02 I think that's the only environment variable we need. 51:04 So let's go ahead 51:07 and deploy this static content is free. 51:12 That's nice. 51:15 Up to one gig, outbound, 51:17 and oh, and 100 build minutes. 51:20 Okay. 51:22 Cool. 51:25 Launch that. 51:31 Okay, so that's running, 51:35 we can look at the logs 51:37 and watch it, build up these. 51:40 That's the runtime logs, 51:41 here's the build logs. 51:44 It's gonna install a bunch of packages 51:46 and build our project. 51:59 While this is building, 52:01 let's take a look in the console 52:04 at our API application. 52:08 And let's see what we can see here. 52:09 So 52:12 we look at the insights see what kind of metrics we get. 52:19 Let's narrow this down a bit. 52:21 So the last hour, you can see, so remember, 52:25 we deployed three containers. 52:30 So we have three instances, 52:32 central-perk, central-perk API, zero, one and two. 52:37 So three containers, hosting our applications. 52:40 So there's a load balancer somewhere 52:43 that is routing requests, 52:47 assuming some sort of round robin. 52:49 So that's, that's a nice way 52:52 to scale our GraphQL application. 52:57 Ingress. 52:59 Bandwidth. 53:00 Average latency. 53:02 I guess, there're not many requests coming in. 53:15 But that's neat. 53:18 Okay, let's see if our Gatsby app is built yet. 53:22 Central-perk-gatsby 53:32 still building. 53:40 Okey doke. 53:42 Back to our API. 53:46 Okay, so we looked at the insights, 53:51 deployments, 53:53 or history of deployments, 53:55 the logs. 53:59 So, it looks like it's taking the logs 54:05 from each instance and just dumping those all in here. 54:09 I guess we 54:10 what we should have done is started this 54:18 in dev mode. 54:22 So we can see the generated cipher queries. 54:27 Let's see. 54:29 We can set that up to work. 54:41 So the way that we enabled dev mode is 54:44 by setting an environment variable. 54:49 Where do we set our environment variables? 54:53 Deploy settings is that in deploy settings? 54:56 No. 54:58 Domains, oh this is how we change them. 55:03 APP spec. 55:08 Yeah, so here's our, 55:12 with some YAML oh, this is the actual configuration. 55:16 Okay, how do we edit that though? 55:17 Use to edit Advanced Settings. 55:25 How do we edit that? 55:27 Manage components? 55:29 There we go. 55:30 Okay. 55:32 So for environment variables 55:38 so we gonna we say dev equals Noe4j-GraphQL.jsjs 55:44 And that will enable 55:47 debug mode for Neo4j-GraphQL.js. 55:50 And 55:53 that will then log the generated cipher queries for us, 55:56 at least. 55:57 This is something we can see in the logs 55:58 and changing that looks like triggered 56:00 a new deployments. 56:02 Cool. 56:04 That's while that's deploying 56:05 so my question is, is this still running? 56:14 Oh, yes, tags needs key and value. 56:19 So, yeah, 56:20 so it's deploying a new 56:24 a new instance of our application 56:27 but our old one still lives on 56:30 while that's being deployed. 56:31 Good. 56:33 That's what we want. 56:33 Okay, let's check in on Gatsby. 56:41 We look at deployments. 56:45 Got an error okay. 56:49 What is the error?. 56:51 Cannot query fields on type markdown remark. 56:54 Well, markdown remark. 56:55 This is the markdown processor 57:01 that we aren't using anymore. 57:05 So we started with the Gatsby Blog Starter, 57:09 which was pulling content from markdown files. 57:15 We took that out. 57:16 So we shouldn't be querying 57:21 anything related to MarkdownRemark. 57:25 I thought we had taken all that out. 57:26 Oh, Gatsby, plug in feed. 57:30 Oh, okay. 57:32 So Gatsby plug in feed, 57:32 I think is what is generating our RSS feed? 57:42 Yeah, so Gatsby plug in feed is going to generate 57:45 an RSS feed for our application. 57:48 And the reason we weren't getting this error 57:50 when we were running Gatsby develop locally, 57:54 I guess is this probably only 57:59 is touched 58:01 when we do Gatsby build. 58:05 Yeah, plug in, only generates the XML file 58:07 when run in production mode. 58:09 And we haven't run this in production mode yet. 58:11 So that explains why we didn't get that error. 58:16 Let's just remove this 58:17 because we don't don't need an RSS feed, 58:22 since we're building a travel guide. 58:25 So let's go ahead and remove this, 58:30 we'll just edit this in GitHub directly 58:33 since we can do that. 58:37 Gatsby plugin feed. 58:39 If we just delete this 58:43 from gatsby-config, 58:47 I think that will address our issue. 58:53 We also test if that triggers a new deployment. 58:56 Yep, cool. 58:58 It triggered a new deployment. 59:03 Cool let's check on that new deploy 59:06 of our API. 59:09 So we updated app-spec. 59:12 Yep. 59:13 So we enabled 59:17 debug mode. 59:20 Oh, interesting. 59:21 We don't get a different 59:24 URL doing this. 59:25 This stays the same. 59:27 central-perk API 7ndn8, 59:32 7ndn8. 59:33 Yeah, interesting. 59:33 Okay, so I was wrong. 59:34 I was thinking we would get a new URL 59:37 for each deployment. 59:41 But looks like we don't. 59:42 Okay, that's fine. 59:44 So if we take a look at the logs 59:52 we should see a couple messages here saying 59:55 that graphical API is ready listening on 60:01 port 3003 60:03 but then as we run GraphQL queries, 60:08 the Neo4j-GraphQL.js library that 60:10 that's sort of the core library 60:11 that is running our GraphQL server, 60:17 which is 60:21 doing two things, really. 60:22 One, I guess is it, 60:23 it augments the GraphQL schema. 60:25 So when we go 60:25 from the GraphQL type definitions, 60:29 we take a look at the code here, 60:32 or our object GraphQL API. 60:36 We go from these type definitions, 60:38 which can include some fields 60:41 where we've attached a cipher query 60:44 to add custom logic with the cipher schema directive. 60:47 So here for Wikipedia, this is kind of fun. 60:51 We're using a cipher procedure, apoc.load JSON 60:54 to go out to the Wikipedia API 60:58 to grab some data for that point of interest 61:02 so some custom logic 61:04 but basically, we don't have to write any resolvers 61:07 for data that we're fetching from the database. 61:09 So when we're searching for points of interest, 61:12 by location, type, and so on, 61:17 you know, the only resolver we wrote is the one 61:19 to call it to the Mapillary API. 61:21 So that make augmented schema function 61:25 from Neo4j-GraphQL.js is taking care 61:27 of all of the logic for fetching data from the database. 61:30 So the the main backbone 61:33 of our graphical API is this Neo4j-GraphQL.js library. 61:38 Anyway, what we want to see here, 61:40 let's maybe refresh this log view, 61:43 what we want to see here, 61:44 now that we enable debug mode, 61:47 is the generated cipher queries 61:50 for each request each GraphQL request 61:52 that we make. 61:53 So that library is translating these GraphQL requests 61:57 into data fetching code, and cipher 62:02 that then hits Neo4j. 62:06 It's like, we can't see the logs right now. 62:09 We'll come back to that in a sec. 62:11 It's fine. 62:13 So is Gatsby still deploying? 62:15 Or did we 62:18 did we encounter an error? 62:19 So the first one errored out. 62:20 That was the RSS feed plug in 62:24 that was trying to access some fields 62:28 that we had removed 62:31 since we switched to all the content being populated 62:36 from our Neo4j graphical API instead of 62:39 from markdown files. 62:42 And we're still building the new deployment. 62:46 Let's see where we are in that process. 62:55 Cool, looks like we're done with that 63:01 and we've generated our static content. 63:05 Now it's like this is , 63:07 our static files are being uploaded 63:09 to the CDN, 63:13 which I'm assuming is CloudFlare. 63:16 Cool so that should be online soon. 63:21 Let's jump back to our API application. 63:24 Take a look at those logs. 63:44 Okay, so we might not be able 63:47 to see the logs there. 63:53 Let's check in on the Gatsby deploy. 63:59 Core still uploading 64:03 our static content. 64:06 There we go. 64:08 So we generated 481 files. 64:11 Most of those are the HTML 64:14 for our individual point of interest pages. 64:20 Okay, so we are online. 64:24 Deployed successfully. 64:25 We have our own subdomain. 64:30 Here's all of our list of points of interests. 64:33 We select one, 64:35 we see cooler photo for Mapillary, 64:39 our tags that come from Neo4j, 64:44 which come from the OpenStreetMap data set, 64:47 and then pulling in data 64:50 from Wikipedia. 64:53 Cool. 64:55 So that's, that is our application. 65:02 That's what we want to see. 65:03 Great. 65:05 So we deployed this 65:08 using DigitalOcean app platform. 65:14 We had to deploy two applications here 65:17 since it didn't look like we could use a mono repo. 65:19 If anyone knows how 65:20 how to use mono repos with App Platform, 65:24 let me know 65:25 and we can update our deployments to use that. 65:31 But we deployed 65:34 one application that was our GraphQL API. 65:37 And then the other is our Gatsby project 65:40 with our static content, 65:42 pulling in content from that GraphQL API. 65:47 Neat. 65:49 Let's see. 65:50 What else do we want to do? 65:51 Oh, I guess it would be nice 65:52 to have a custom domain. 65:55 How do we set that? 65:55 So instead of central-perk-gatsbyondigitalocean.app, 65:58 maybe we want 66:02 I don't know, like central-perk.grantstack.io 66:06 or something like that. 66:10 How do we set that up? 66:11 We go to Settings. 66:18 Components. 66:25 Some settings, I'm sorry. 66:28 Oh, yeah. domains and certificates, cool. 66:31 Add domain. 66:34 So domain and subdomain, 66:36 we want this let's say centralperk.granstack.io. 66:45 And it tells me to create a CNAME record 66:49 on my DNS provider I think, I think grand stack. 66:55 We have set up on Netlify for the DNS provider. 66:59 So let's add that domains. 67:03 Yeah, grand stack, DNS record. 67:08 In order to say it said add a CNAME alias 67:14 So central-perk 67:20 is the sub domain and then the value... 67:24 Where was that? 67:25 That was us here. 67:29 C, CNAME alias we want. 67:32 So create that and then 67:37 add the domain. 67:44 So now let's try that centralperk.granstack.io on 1001. 67:47 It'll take a few minutes 68:04 for the website's information to be distributed. 68:06 Yeah, fair enough. 68:07 We've just created this DNS entry. 68:10 So we need to wait a second 68:22 to 68:25 populate? 68:26 Cool. 68:29 Well, that I guess is 68:33 a quick look at DigitalOcean's 68:36 new App Platform. 68:41 Anyone has any suggestions 68:42 for something else to look at here 68:46 with the the App Platform? 68:49 Feel free to send any ideas 68:50 but I think we got 68:53 I think we accomplished what we wanted to. 68:55 So we deployed our GraphQL API application 69:01 and we deployed our Gatsby application pulling in data 69:05 from the GraphQL API, 69:09 which I think is that's what we wanted to do for today. 69:16 So yeah, let's let's wrap it up there. 69:21 We deployed our application, 69:24 we set up a custom domain 69:26 and now we can share that with the world. 69:31 Next time, I do want to get to adding some maps 69:37 to our application, both here on the Index page 69:40 and then for each individual page, 69:43 just to show where it is in Central Park 69:46 and then take advantage 69:48 of the routing functionality 69:50 that we added last time. 69:53 So now that we know how to deploy our application, 69:57 I think that is the big missing feature, 70:03 missing functionality that we want to add, 70:06 which we'll take care of next time, 70:08 looking at map components. 70:13 If anyone has an opinion on 70:14 what map components for React to use 70:18 or for specific to Gatsby, 70:21 if there's some map plugin for Gatsby, 70:24 specifically, I'm not sure. 70:28 We've used previously 70:30 a couple of different wrappers I guess, 70:36 React component wrappers around the matte boxes, 70:41 Web GL, 70:43 Matte box GL.js 70:45 but if anyone has any opinions for looking at 70:48 a different React based map component library 70:52 or mapping specific to Gatsby, let me know. 70:56 Ping the ping me on Twitter 71:01 which my Twitter handle exists on the screen there, 71:07 @lynwj. 71:08 I'll drop a link to that in the chat. 71:10 So definitely let me know 71:14 what map component you'd like to explore. 71:17 And, and we'll pick that up next time. 71:20 Cool. 71:21 So thanks for joining today 71:22 and we'll see you again next week. 71:26 So we do these streams live 71:30 every Thursday at 2:00 pm Pacific. 71:34 I should point out, it's not just 71:37 that time there. 71:39 That's my time slot specifically 71:42 but there's some other folks that stream 71:46 on the Neo4j Twitch stream, 71:50 you'll find our schedule there. 71:52 Yeah, here's the schedule. 71:53 So if you go to our Twitch stream, 71:56 if you're watching on YouTube, 71:57 and on Twitch stream right now, 71:59 you can see the schedule. 72:03 We usually have Adam looking at building applications 72:10 with Neo4j, 72:11 Lu who tends to look at digging 72:14 into specific datasets 72:16 and covering some of the, 72:18 this weekend you have J articles 72:20 and then Michael, on Wednesdays digging 72:24 into all kinds of various topics. 72:27 I think the the last thing Michael looked at was 72:29 the finCEN files in the Neo4j applying 72:35 some graph data science algorithms to them. 72:39 Certainly check out some of those 72:40 other time slots on the stream. 72:42 You can find all the recordings 72:44 on the YouTube channel Neo4j as well 72:47 which I will also link. 72:49 Cool, that's all 72:52 from me today. 72:53 We'll see you next time. 72:55 Bye bye
Subscribe To Will's Newsletter
Want to know when the next blog post or video is published? Subscribe now!