Docker-ize & Deploy Node.js Applications with Caddy on DigitalOcean

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
you've been hacking away at your back end application and now it's time to deploy congratulations let me show you the easiest way to deploy your node.js application in this video i'm going to show you how to make a deployment with docker docker compose adi is the web server and we're going to deploy our application on digitalocean note that you'll need docker installed to follow along with this guide let's start by creating our dockerfile to come into your application create a new file and call it docker file with a capital d the docker file is responsible for creating the image and from the image we can start a container let's say from node colon 14 and this is going to use node version 14 as our base image if you want to use a different version of node use a different version here so if you wanted to use 16 for example you would say node 16. next we're going to move our package json into a temporary directory so we can use yarn to install let me say add package dot json to slash temp package dot json i'm going to add my yarn lock file if you're using npm you will have a npm lock file i'm going to add yarn dot lock and i'm going to add this to my temp directory slash temp slash yarn dot lock i'm going to remove my build directory if we have a look in my package.json here you can see build is going to run tsc and then if we look in the ts config file you can see we're going to build to a build directory here so i'm going to run a command to remove that directory to make sure we get a fresh install every time so i'm going to say run rm that's rf build run just means run a command rm means remove and rf means remove it recursively so remove all folders and files inside of this directory here i'm going to run another command so i'm going to run cd into our temp directory and yarn install so we're going to change directories to this temp directory here and we're going to run yarn install and this is going to install our dependencies i'm going to add dot slash and source and this is because we have a source folder here i'm going to run another command so i'm going to say run rm minus rf source slash node modules and i'm going to copy the node modules from our temp directory into our source directory i'm going to create a working directory so i'm going to say work dir source i'm going to run our build command so yarn so run yarn build if you're not using typescript you won't need to run this build command here and finally once our build command has run we can run our node.js application i'm going to say cmd and i'm going to create an array and i'm going to add node as the first command and then node is going to run out app.js that's going to be inside build source app dot js so this is our docker file complete we could build this image and then run that image but i'm going to create a docker compose file because i find that much easier to build our images and run out images in containers so let's create a new file i'm going to call this docker compose.yml i'm going to give this a version of 3.7 and this is the version of docker compose to use and we're going to have some services here so i'm going to say services and the first service we're going to have i'm just going to call this rest api secondly i'm going to give this a container name so i'm going to say container underscore name and i'm going to call this rest api you can call this whatever you like as long as these match and there will be some other places throughout the tutorial where this will need to match as well i'm going to give this a restart unless dot so our container is going to restart unless we explicitly stop it i'm going to tell docker compose to set an environment variable so i'm going to say environment and i'm going to give this one environment variable and we're going to say node n and i'm going to set this to production if you want to set some other environment variables in here you can do that as well but i'm going to use this.n file and i have config for some default config when you run your application with the node and set to production config is going to use this production file here so you can say export default and we can have some environment variables here otherwise we can set our environment variables here in custom environment variables and then we can set these in our dot n file so i'm going to give this a property of build then i'll say context is going to be our root directory and for now i'm going to expose our port and this is just going to be for demo purposes so i'm going to say ports and i'm going to expose port 1337 because our application is going to run on 1337 and i'm just going to expose that to the same port now let's try this out so to run your docker compose file you need to run docker compose up and you can run this in detached mode with dash d i'll run it in normal mode so it's going to tie up our console and if we exit our console it's going to exit the container so so the version of docker compose is invalid it should be a string and we need to wrap this in quotations that's it again and i've missed about restart here so you can see here that it's going to build our image i already have the node.js image downloaded but if you don't it will download it for you so we've got some logs here and if i open up our docker dashboard you can see here we have our rest api tutorial updated and we have our rest api and here you might not be able to see it but you can see that it's exposing port 1337. if we go back to our logs here you can see it could not connect to our database and the reason that it couldn't connect to our database is because if we have a look in default it's looking for localhost for a mongodb instance and of course in our docker container we don't have a mongodb instance the easiest way to do this is to use cloud atlas and connect to an external database you can create an instance of mongodb inside of your docker compose and connect to that but i find that to be a little bit more complicated so i have a database connection string already so i'm going to paste this into my dot n file and don't worry about trying to connect to this database because before i release tutorial i will have deleted this connection so let's try to run our container again so you can see here we couldn't connect to the database again so let's run this with a dash dash build and this is going to rebuild our image you can see it's going through the build process again you can see here our database is now connected and our application is running so let's send a curl request to local host port one three three seven slash health check and we should expect this to return with ok so that's curl http localhost1337 slash health check and we get back a 200 okay so if you would like to run your container in detached mode you can do docker compose up and you can do dash d so you can see now it says ret api is up to date and our terminal is usable again so if you come into the docker dashboard you can expand the container here and if you want to enter the command line you can click here and it will open a command line interface that is inside of your docker container so that is the docker component finished off now let's configure caddy and caddy is going to be our web server so if you're using cadi you won't need to configure any ssl certificate yourself and you won't need to use anything like nginx or apache so let's add another service to our docker compose so i'm going to collapse our rest api service here and i'm going to call this one caddy and the image is going to be caddy flash caddy version 2.2.1 and we're going to be using the alpine version which is just going to be a little bit smaller our container name is going to be caddy surface our restart correctly this time is going to be unless stopped again and we're going to expose some ports here so i'm going to expose ports and we're going to expose port 80 and we're going to use port 80 for that port and we're going to do the same for port 443 so i'm gonna say four four three four four three and port 80 is of course for http connections and 443 is for http or tls connections so we're going to add some volumes here as well it's going to say volumes and i'm going to say dollar sign uwd slash caddy file and we're going to be creating this caddy file in just a moment etc caddy caddy bile vwd site colon slash srv paddy underscore data colon slash data and caddy underscore config and slash config now we need to add these volumes so i'm going to say volumes i'm going to add caddy underscore data and i'm going to add caddy underscore config so now let's create this caddy file here inside our root directory here i'm going to create a new file i'm going to call this caddy file so you'll need to know what your domain is going to be mine is going to be rest api dot snipped dot io this is just a domain that i have lying around and i'm going to use this rest api subdomain to open up some curly brackets and we're going to use a reverse proxy so i'm going to say reverse underscore proxy rest api one three three seven so this is our container name and this is the port that that container is exposing and i'm going to add a header here and i'm going to add this header because it's going to help us get an a-plus for our tls check and i'll show you that at the end so i'm going to say header down strict transport security max age equals three one five three six thousand and we'll terminate that line so again you'll need to use your domain here and if you've used a different port you will need to use a different port here and if you've called your container something other than rest api like i've called my rest api here you will need to rename this portion as well so before we go create our digitalocean droplet i'm just going to show you a little trick that was mentioned by someone in our discord and if you have a look down here sibwebworks has told us that if you don't want to format your private and public keys onto one line you can base64 encode the keys instead and then you can use this buffer dot from base64 to string and i'm going to show you how to do that so if you come into config i'm just going to grab out this public key and i'm just going to google base 64 and code and this is going to get a decoder that i can use in the browser i'm going to encode this into a string then i'm going to come into our environment variables here and i'm going to say public key is equal to our string and then i'm going to do the same here for the private key you need to make sure this public and private key are in the custom environment variables so you can see i only have private key here i'm going to add my public key and i've called this public key and we can remove this here so now if we come into where we're using those keys i'm going to come into utils jwt utils and you can see here we have private key and it's going to be config.get and we're going to get our private key and our public key so now when we get these keys they're going to be base64 encoded strings so we just need to decode those strings let's wrap this in upper dot from and then the second argument here is just going to be base 64. and then we're going to call dot 2 string and this is going to take one argument and it's going to be ascii so let's do the same thing for our public key so i'm going to say buffer.prom base64 dot two string and we're going to use ascii let's console log these keys and we can see what they look like so i'm going to use mpx killport 1337 to kill our application that's running on port 1337 and this is going to crash docker the easier way would be to go into docker and stop the application so now let's run yarn dev and you can see here in our console we get our keys and they're formatted correctly you can see here we have our private key and our public key so that's a nice little trick so let's push all of our code up to github and i'm going to add my end file to git ignore and come over to digitalocean and click create droplet and if you don't have a digitalocean account you can use my affiliate link that i'll post in the description below and you'll get some credit for that as well and i'll get some credit so that would be really nice so you can create an image from scratch if you like using any linux distribution but i like to come over to the marketplace and just use an image that has docker pre-installed if you come here you can click docker and i just want a regular intel ssd and i can get that five dollars a month then i'm going to choose the location that's closest to me so i'm going to click singapore so for authentication i highly recommend using ssh keys and you can generate those ssh keys if you click new ssh key it'll give you all the instructions here it's really simple and this is by far the most secure way to connect to your server however i am very lazy and i'm just going to use the password because once i finish recording this video i'm just going to destroy this server so i'm going to paste my password in here and i'm going to create a name for my droplet i'm just going to call this rest api tutorial and you can add some tags if you like enable backups and i'm going to click create droplet so while your droplet is creating come over to your domain provider i'm using namecheap and you can click advanced dns in your provider it may look a little bit different if you're not also using namecheap and we need to add a new record here so i'm going to click add new record and it's an a record that we want to add so the host that i'm going to use has to match what i put in the caddy file so i'm going to put rest api and then in ip address we need to wait for our digitalocean droplet to be created and we can copy the ip address from there and put it in this ip address field here so my droplet has finished creating here and i can click copy and come over paste in the ip address and click the little tick here don't forget to click that little tick when i put a domain in here before i forgot to do that and i was wondering why my domain name wasn't pointing to my droplet for quite a long time so now we can connect to our droplet so i'm going to come back to vs code and i'm going to open a new terminal you can use any terminal you like i usually use item but i think vs code is just a little bit easier to see in the videos i'm going to say ssh root at and i'm going to paste in the ip address from digitalocean and because i'm using a password it's going to ask me for my password and we need to allow this fingerprint so i'm going to say yes i'm going to paste in my password and we're now connected to our droplet so the first thing we need to do is to install git so we can clone our repository so i'm going to say apt get update and this is just going to update linux's package repository i'm going to say apt get install yep so once git is installed we can clone our repository so i'm going to come over to github and we can click code i usually clone over ssh but unless you have the keys installed it's not going to let you do that so i'm just going to use hdbes so i'm going to cd into slash file i'm going to create a directory called www so so i'm going to say mkdir www and cd into www and i'm going to say git loan and i'm going to paste in the link to the github repository that's ls to make sure we have our folder here so you can see here we have rest api tutorial so i'm going to cd into rest and i'm going to create a dot n file so you can use vim if you like but i'm going to use nano and say dot n and i'm going to grab the dot n file that i created before i'm going to get all the contents of this and you can put whatever you like in here just again make sure they're in your custom environment variables so i'm going to paste this in here i'm going to press command x i'm going to save this now we need to run git pull in case we have any changes and we need to run docker compose but i'm very lazy so i would rather just run one command so i'm going to create a new file i'm going to call this deploy.sh i'm going to say number exclamation mark bin bash and this is just saying that we're going to run this script with bash i'm going to echo out pulling and this is just going to print to the console then i'm going to run the command git pull then i'm going to echo build building application you say docker compose up minus t because we want it to run into touch mode and we want it to rebuild every time as well so let's push this script and say b deploy script now push that script i can say git pull and we should see this script pull in here yet so you can see deploy.sh so if we try run this deploy script we're not going to have permission to do that so i can say dot slash deploy.sh and it says here permission tonight so we need to mod the permissions on this script so we can execute it so i'm going to say chmod u plus x deploy dot sh now let's try run that script again so dot slash deploy.sh and you can see here we get pulling already up to date and now it's saying that our docker compose is invalid so inside of caddy service it says port do you mean ports so let's have a look at our docker compose file and here we say port when we actually mean ports and while we're here we can remove this port here because we don't need to expose that one let's say fix addy ports and then the beauty of this deploy script is it's going to pull for us so we can just run the deploy script again you can see it's pulled the changes here and it now it's building out our image for us so you can see here that it's created two containers for us caddy service and rest api if we say docker ps it's going to list the containers we have running so this is a little bit hard to see here but you can see we have a container id here starts with 1a and its image is rest api tutorial and we have some other stuff here as well you can see it was created 12 seconds ago so if you want to view the logs for this you can say docker logs and then the container id you can see here that our app is running and our database is connected and we have our docs available and it says here that it's available on 1337 and that's because that's the internal route and so caddy is going to reverse proxy that for us so let's go see that in action so i'm going to come to a new browser i'm going to say rest api dot snipped dot io and you can see here we have a cannot get slash and that is looking promising so let's go to health check and you can see and you can see here we get back and okay so that looks really good and if we click on the little padlock here you can see that we have a secure connection so let's go test this ssl certificate so if you come over to ssl labs you can paste in your host name and click submit and this test will take a while to run but it's going to check a bunch of different security things for you with just a little bit of configuration thanks to cadi ssl labs has awarded us an a-plus for our ssl certificate if you like this video or found it helpful please make sure you give it a thumbs up and you subscribe make sure you turn notification bells on so you get notified whenever i release a new video and if you would like to ask any questions or make any suggestions please make sure you've joined the discord server thank you for watching and i'll see you in the next video you
Info
Channel: TomDoesTech
Views: 10,003
Rating: undefined out of 5
Keywords: docker, docker-compose, docker-ize, dockerise, docker nodejs, nodejs, typescript, javascript, deploy rest api, deployment, caddy server, https, ssl certificate
Id: 6TM9ds1fsug
Channel Id: undefined
Length: 28min 8sec (1688 seconds)
Published: Tue Nov 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.