Automatically Deploy Docker + Wordpress To Digitalocean With Github Actions - CI&CD

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] welcome back today we're going to be creating a continuous integration platform with wordpress digital ocean github actions self-hosted runners we're going to go all the way through from a docker compose file which is the very first step creating the first line and then we'll go all the way through to actually deployment and where you don't have to worry about anything you can just commit your code to a branch and it will pick up everything and deploy it all all for you okay to get started i've gone ahead and created a new repository and if i could just click reload just to show you obviously this is a completely blank repository um and what i'm going to do is i'm going to make a directory call this docker wordpress change directory into that that and then open it up with visual studio code fantastic and then let's get started with some um docker compose files or i say files file so docker hyphen compose.yaml and just to start it off we're going to type in version three i've got a video which talks a little bit more in depth as to what's actually going on so i'm going to say services and i'll link to that down at the bottom so i'm going to specify my database and this is going to be image of my sql 5.7 then i'm going to mount with some volumes volumes and this is going to be our db underscore data it's going to map to slash far slash lib slash mysql next i want to put my restart policy and that is always so make sure you always restart environment variables i am going to declare word oh not wordpress mysql mysql underscore database mysql undergo database and i'm just going to say wp and because that's the database we're going to be working with then i'm going to say mysql underscore root user user and this is going to be um i'll say root password not root user and this is just going to be password next it's going to be mysql underscore user and mysql underscore password so user i'm just going to keep it as root and then mysql underscore uh password is just going to be password as well you know what i'm just going to move that line up so root password is at the top because i want to keep my database my user and my password together not because it would change anything just because my ocd um okay networks let's link these up in a moment so this is going to be our wordpress so let's just say wp network and then i'm going to knock down on a couple lines i'm going to say wordpress and give this a name so we're going to refer to our web server as wordpress and then i'm going to open up some ports reports i'm going to open up i'm actually going to specify some environment variables a little bit later but for now let's just go ahead and export expose port let's say 8 000 so ports knock down onto a new line hyphen and then i'm going to say port 8 000 is going to go to or 80 within the container so our 8 000 is going to 80 in the container then i'm going to say depends on db because we obviously need this database which is up here to be running in order to run our wordpress instance then i'm going to um mount some volumes so volumes and specify an array because we may want more for um more than just one folder that to be mounted in in the future so i'm going to say anything.html folder is going to get mounted to slash var slash www.html because this wordpress image that we're about to pull in a moment and actually um it mounts it brings down apache with it so this is the default location in apache you know what let's just put that up here so image is going to be wordpress and then let's just say the latest again we may put some environment variables in here later so um people can specify the version that they want to run on their particular machine but then on the production server it'll always run this you know the the one that we want okay so we've got um our volumes so let's move on to our environment variables and then i'm just going to say my that's like wordpress underscore db underscore host and this is db obviously up here we're referencing our database db and then we want to go to port 3306 and then it's word uh wordpress underscore um db user these all just the standard environment variables when uh when downloading the image then wordpress underscore db let's go password and we called this password i think it was wasn't it let's just double check root and password yep okay next i want to knock down and just connect those networks up again so network and this is part of the wp and then i'm going to say networks wp and then volumes db underscore data let me just double check did we call it db underscore data yes we did okay brilliant and next i'm going to come uh let's just connect this file up with uh git so actually you know what let's make let's make sure it's working before we connect anything up but first things first um i'm going to open up my integrated terminal and i'm going to use control and backtick once that runs then i'm going to make sure docker is running so docker hyphen v and again if i just use um spotlight i can just make sure docker is running from here then i'm going to do docker iphone compose up hyphen d and just run docker compose in detach mode and then we've got an error and because services depends on contains an invalid type so let's have a look um wordpress depends on db okay so i have um not put on it so his new line save that docker can pose up we go we're creating everything and it's done now if we're on docker ps and let's just make this full screen for a moment go and i can zoom out with this just to put it all on one line great so we've got our two containers wordpress running latest and mysql one in 5.7 and these were created a few months ago so port 8000 is going to port 80 and so if we pulled up our um window here and we went to localhost port 8000 we get a fail so let's find out what's going on here docker ps it is running local host 8 000 i've done something wrong there so i still be hyphen um login there you go it's just because it hasn't it hasn't installed okay next what i'm going to do is i'm just going to initialize git but obviously because we've um we've cloned we've run docker compose it's gone ahead and pulled down all of wordpress we're gonna have a lot of issues um with basically we're gonna have a lot of new files um but i'm not gonna go through and worry too much about the git ignore and so i'm just going to commit everything so i'm just going to say git add add the whole lot may take a second there we go git commit let's just say initial commit and then i think i didn't actually name it the same i've cloned it into a different repository of that so let's just go ahead and grab this so get branch main so just declare our main branch push through origin and then uh sorry declare our origin and then push domain so let's just go and paste that in it's uploading everything give it a moment and it should be done so now if we come back over to our chrome reload this we've got a working uh docker wordpress github actions with all of our files in there so next what i want to do is go ahead and set up a workflow in github so i'm going to come over here and click on actions now if we scroll down to the very bottom i think it's just more there's a simple um simple setup somewhere simple there you go simple workflow that's the one that we're looking for simple workflow then i'm going to go ahead and delete everything usually what i do is just create this as a file and then commit it but let's just go and create it in here digitalocean underscore deploy and you can name this whatever you want and and you can have multiple versions of your workflows and so i'm just going to start typing out in here and i'm going to say name is digitalocean i'm just going to deploy and then i'm going to knock down a couple of lines and i'm going to say on a push to a particular branch and i'm going to say that branch is main so when we push to main i want you to do whatever it is that you know that i'm going to specify down below so i'm going to come down a couple of lines and then i'm going to say jobs these are the jobs that i want you to do and i want you to run a build now this build here i've called it something you know this could be your test or this could be whatever i'm just calling this build then i want you to do let's say runs iphone on and i'm going to say self hyphen hosted now the reason i'm putting self hosted here is because i don't want it to run within github i don't want it to run on ubuntu or anything like that i want this to this action to be performed on our actual instance so our droplet instance that we'll go ahead and create next i'm going to knock down a couple of lines and i'm going to say the steps that you need to take um steps is you are going to use actions slash checkout and then i want you to check out main so i'll make sure that you're on the main branch and then i'm going to say name um hyphen name and this is going to first of all create a um a m file so the reason that we want to create a dot m file is because we've got let me just pull up my docker compose here we've got um you know specific versions we've got passwords and usernames and ports in here and now this is obviously really insecure if someone is um if someone gets hold of this file essentially they're going to get hold of all of our databases all of you know all of our configurations what i want to do is pass in some secrets into this file that it will be used as an environment variable and then we can basically make sure that we've we've looked after you know our our users and our user data so i'm going to come back and i'm going to say run and then what is it i want you to run well i want you to echo and then i'm just going to say oh port is equal to and then i want to give you a secret and then close that off and then i'm going to echo that into dot m so if i wanted to manipulate this i could just add in like a load of um environment variables and whatever but i just want to show you how we can get just get one working report is going to be equal to and then i want to pass in a secret that secret is going to be secrets dot port and where we get this port and this variable from is over here in our settings so on the repository that we've created i've go over to options scroll down to secrets and then i'm going to create a new repository secret and i'm going to call this port that was it all capitals yeah all capitals so port and then i'm going to say this port is 80. what i'm hoping to do is our port actually overwrites um basically local will run on port 8000 but whenever we deploy it's going to run on port 80. so we'll uh we'll hook that up in a second so i'm going to come back over here i'm going to echo port equals port in into our m file next i want to create this wizzy wig is frustrating next i want to create um something else so i'm giving it a name again so this name is just basically when when the the build is actually happening what's what's going to be shown back to me as in what's the current process and the steps that it's taking so if it for any reason it crashes at this point i'll know it's crash creating the env so i'm going to say run build and this is literally just going to be run docker hyphen compose up hyphen d i'm just gonna commit that and i'm gonna commit it to the main branch and that should be everything so now if i uh pull down what we should have is a github and our digital ocean so digital ocean underscore deploy this is our workflow but and when we push to remain and then we've got the jobs that we need to do okay so just to make sure that our environment variables uh up and working or or will work we obviously need to change our docker compose file i'm going to come back over to docker hyphen compose.yaml and then where we've got our ports what i'm going to do is i'm going to put in a dollar sign open close curly brackets i'm going to say port in here colon hyphen and then the reason i'm putting a colon hyphen here is because i'm going to fall back onto a default port so if if there is no environment environment variable it will just always declare like port 8000 obviously we can go ahead and let you know change this so i could say up here and let's do this and say i don't know um root underscore password and then hyphen and then call it whatever you know the default is always going to be password um but i said you know we're just going to keep it simple and just do just do the one so now that we've got our port what i'm going to do is i'm going to turn down our container so i'm going to say docker compose down that should stop these containers from running there you go and it's removed them so if i do docker ps um we now have um nothing in here now what i want to do is just come over here and create a new file so i'm going to do dot m and you know what whilst we're here let's just make sure that we've got a dot ignore and we want to ignore anything with a dime okay so that's never going to get committed for you know by mistake for whatever reason i'm going to say port is equal to and let's just say 1 2 3 4. i'm going to save this and then i'm going to clear this out and do docker iphone compose up hyphen d run that and it should be creating our uh or recreating our containers now if we do a docker ps and we have still got our file because i didn't save it of course i didn't so let's just turn that down a second docker hyphen compose down and docker compose up hyphen d docker ps and now we have mapped locally to port one two one two three four is mapping to port 80 in our container okay great now just to recap we've gone through we've set up docker compose we've put environment variables in there we've got that working with environment variables and we've committed everything to a repository we've also set up a workflow and we have passed in the secrets from our github into our dot m file within our workflow now in order to do that what we need to do is go ahead and um basically set up our droplet so i'm going to open up digitalocean and i'm just going to call this tutorials um and select the purpose so let's just say just trying out i'm going to skip this for now okay this has created a project where area for me we don't need to i just didn't want to get muddled in with some of my other droplets i'm going to click um create a new droplet and then within here if i go to marketplace what you'll see is docker this docker um image basically creates a droplet for us with docker and docker compose already pre-installed so we can just get started i'm going to come and select the the basic plan because it's going to get deleted at the end of this select a region it doesn't really matter where i'm going to keep my ssh ssh keys and then leave everything else as is so now that that's gone ahead and been created what i can do is come over back to my terminal window and we need to ssh into this particular box so i'm going to click copy on the ip and i'm just going to do ssh root at and then specify a um an ip address now obviously the um this ip is not going to exist after this because i'm going to i'm going to kill it off and the only reason i'm going to be able to ssh in straight away is because i've i've already pre done my ssh keys so if you don't select ssh keys you can obviously have to use a username and password which would be emailed to you so um i'm happy with this i'm going to type yes and we should be into our box and we are so what i can do now is let's actually let's just clear the window so do clear and then i'm going to do docker hyphen v just to make sure that docker is installed on this machine fantastic it is so we've created a droplet we've added our ssh keys and we've also checked the docker version next what i want to do is i want to add a user now the reason that i want to add a user is because we're going to be creating a runner in a second within get so um in a minute we're going to come to actions and as part of running that we need to specify some files to run and those files cannot run in sudo and by default because we've gone in as root those files won't run um ahead of time so i'm going to go ahead and create as a user which will allow us to run those files so enough talking let's actually just do it okay i'm going to add a user and i'm just going to say chris i say okay so we're adding a new user what's the user for chris i'm just going to say password and then password and let's just hit enter a few times and it's this information correct okay so we've got a really really insecure user next what we want to do is i want to make sure that this user has got pseudo permissions because we need to be able to escalate our privileges i'm going to say use a mod hyphen a g sudo chris okay so now chris has got sudo permissions and then what i can do is i can log in as as chris so i'm going to say sudo su super user and then who do i want to go in as i'm going to go in as chris so we're now in the exact same box as where we were a minute ago however we're now logged in as chris as opposed to root right so now what i want to do is i want to add that runner i want to make sure that whenever this action happens that um you know so this workflow happens here and it and it runs a build we need to something needs to be reaching out and waiting for a um a particular um 14 minutes ago i wonder why oh because we've committed stuff um okay so what i want to do is click on settings because obviously we've already gone ahead and set up our um deploy sorry our our work our workspace sorry it thinks that files are going ahead and it's failed because it's got no permissions or whatever because it's obviously self-hosted so what i want to do is click on settings so before we go to actions and down here on the actions tab and click on that and if you scroll all the way down to the very bottom you've got self-hosted runners this is basically um our server watching out for changes i'm going to click on add of runner what's important to note and this has tripped me up a couple of times is operating system and architecture and now i've gone ahead and just selected these uh commands to run and then forgot that i'm obviously on a linux on the actual droplet so just make sure that you change your operating system then it's literally a case of copy and paste so i want to copy the actions runner folder so i'm going to come over here basically make a directory and then change into that directory so i'm going to run that then i'm going to clone a or copy over a table so i'm gonna copy that paste and it's just curling a a massive tar file and then we're gonna just extract that so this tar command here is just tar extract extract zip and file and then what file do we want to extract inside the file that we've just downloaded and now what we should have within this particular folder if i do an ll we should have a list of files that has been extracted fantastic so now we want to configure it so by moving down a couple of lines and i've got this configure and this is going to give us a token that our server can watch out for so i'm going to paste that in there and what it'll do is it'll take us through a little window that we can basically just define some some parameters the first one is the name of the runner and i like to just call this github hyphen runner you can call it whatever you know you may have multiple runners in the future so i'll call it something logical so github runner and then do we want to add any labels i've not found any use for adding any additional labels yet so i'm just going to leave that as is but that runner has been set up now what it's asking for is the name of the work folder but basically whenever you do something and you push your changes live and it goes on to the main branch this is going to be where the files get copied into but the default is underscore underscore work but you might have a folder structure which is like um i don't know um builds or whatever and but i'm going to leave it as default and show you what happens with it with the default certain configuration so by just hitting enter it's just going to default to underscore work and i think it should create that now ahead of time no it hasn't okay because it's obviously not run any any file so um let's just leave that for the time being it will create it in a moment so let's clear the window just so we've got some some readability so now we've created our um our runner we've changed obviously changed our os we've added that token and we've declared a path that it's going to go into now what i need to do is i need to make sure that chris has got um has got docker permissions and the reason that i'm going to do that is because if i run um dot sh here actually let's run it and intentionally break it and i'll show you what what tripped me up a couple of times i've got to do in ll and here we've got a few um uh bash scripts that we can run i want to run the run so run and i'm just going to leave that what that's going to do is it's going to create this runner and it's going to activate it so we're now connected to github and it's listening for jobs okay so if i come over to our actions go back to action settings and scroll down to the very bottom you can see we've got a green icon here and it's saying it's idle that's basically github a word that we've got our github runner that we've just declared a second ago and it it knows that there's a connection there so what i can do now is i can come over to our actions file and then on our digital ocean deploy there's no point in me pushing any additional changes so what i'm going to do is i'm just going to rebuild this job so let's just rerun it see what happens but this is taking a little while i've i stopped it a second ago i stopped the record a second ago but it looks like the build has failed so no running matching the specific labels was found was self-hosted so let's find out what's going on jobs build and build okay sorry um i hadn't actually checked it i should i should have checked this first because i knew that this was coming i actually i usually i actually even said as well ahead of time that is gonna fail um so i thought it was giving us a different error anyway enough of that so the error that we was getting here is permission died that denied and this is intentional um because a moment ago when i said that if i cancelled this off we needed to add the user chris to um to a docker folder if i do an ll now what you'll see is that we've got this work folder this workfold has been created so i can change directory into it and i have to do an ll again what you'll see is we've got docker wordpress github actions so the name of our repo i'm going to change directory into that and then let's just clear the window just for um so we can actually see things and again we i don't know why it creates the uh a duplicate so i'm just going to change directory into it again so docker change the dive train to there clear the window again one ll and now what we've got is our docker compose and our html folder that was was talking about and it's also created a dot in for us and so if i do an ll on dot m sorry a cat on dot m um what you'll see is port 80 because that's taking our environment variable from um github and echoed it into a m folder so that's perfect we know that that's working we know that our docker compose file has come over because if we run a cat on our docker compose and we know that this is you know what we what we typed out there shouldn't be anything on the server is what i'm trying to get at because there wasn't an underscore work folder a moment ago until we run this command now the reason it failed is because it's got permission denied that permission denied is because i'm logged in as chris and chris doesn't have access to run a docker file so if i run docker hyphen composer up hyphen d here what we'll see is we actually get the exact same error as what we're getting in our actions and that is because out the user chris cannot access um uh docker so to solve that what we need to do is we just need to make sure that chris is part of the docker group so let's clear that off and um i suppose first things first i'm going to exit this out and that will put me back in as root and just to show you all of the folders that are all of the user groups that are sorry that do exist if i do a cat on slash etc group this will give me a list of all of the groups that have been set up so if we go right down to the bottom i've got a group called docker so i know that that docker group already exists but if for any reason it does doesn't exist what you want to do is you want to do sudo group group add docker that's going to tell us that the docker group already exists and but that is the command that you would need to run now they already exist what i can do is i can say sudo user mod hyphen a g docker and then i can put in a user so in our case in our case it was chris and then what we can do is i can log back in as chris so pseudo s u and then the user that i want to log in as so in this case chris let's clear this window so where we are we're at the very we're at the top level we're in the um the root folder so i'm going to change direction to actions and then in here we had our work folder in here we had was it wordpress or what did we call it our docker wordpress and then we had docker wordpress again right now if we're doing ll what we're what we've got is our m our docker compose and our html now if we run docker hyphen composer um docker compose up hyphen d what we'll get is it's creating our network it starts it goes off it fetches the images it's going to be creating everything i'm going to go ahead and cancel this because i don't want to run it just here i want it to run whilst the actual runner is is working and everything so clear this all out i'm going to change directory i'm going to go up three levels because i need to make sure that that runner is working and by that runner i mean the run dot sh so let's just run that run.sh oh connect to github brilliant it's connected we'll change this in a second so that this service is always running and we don't need to be running this runner um but let's go over to our um our github and re-run this this uh this earlier i can't speak for some reason let's rerun this job and so you'll see that the builders has been has been initiated and this build here is as we said earlier if i if i pull up our um our jobs it's directly referencing that so we've had success in creating the dot m it's spat out port into that particular file we could create multiple of these if we wanted or or append onto the end of the dot m and then if you see here we've got the the build and what it's doing is it's actually processing our docker compose up in a detached mode state so it's watching for any changes uh sorry it's not watching for any changes it's it's building everything as we speak and then that should give us a success so click on main brilliant so we've had a success now and if we went to our uh ip address and now previously i now got in the the file was one two three four if we go here this is not gonna work it's not gonna work all together so let's go to google for some reason and it likes to just do this every now and then now let's go to that and then the port of one two three four it's just it's not gonna load anything the port isn't working however if we take that off and we go to port 80 okay so that was taking quite a while and i couldn't figure out i couldn't figure out like off the top of my head as to why it was taking so long so i needed to cancel the actual server so what i did is um held control and c and it canceled this and the reason that i needed to do that is because it took an unusual amount of time so um if we run docker ps what we'll get is we'll get the containers that have been built and that are running and we can see that everything's running fine like so we've got wordpress latest and mysql however if we come over here we can see that we've got localhost and it's mapped from port 8000 to port 80. so if i come back to my chrome window and on our uh the failure to actually render the the page if i do colon 8 000 we get a working instance and that is because we're using an old commit what i'm going to do i suppose this is a is a good example as to our our docker instance running and i'm going to come back over here i'm going to clear the window and i'm going to run our runner so we should connect to github or connected listening for jobs but now i'm going to come and have a look at what's changed and we have made a commit that's right we've made a change to our reports and we didn't commit this line which is look for the environment variable or default to port 8 000. so let's just say um changed um port m in docker compose it doesn't really matter what the message is okay so we've made those changes next i'm gonna push that up and to our main branch let that finish and then i'm going to open up our github so i'm going to come back over here to our actions and then we you can see that it's picked up on the fact that we've changed the port um environment variable in docker compose we can click into it and see what's going on with the build and it's it looks like it's it's all been completed so it's created the dot m if it's around the build and the post checks have been uh successful now if i come back we should have uh listening for jobs running on port yeah the area and it's been like a running job job build completed with result of success so i succeeded so i'm going to cancel that off and i'm going to run docker ps now what we've got is our image wordpress image is mapped from port 80 to um the actual 80 within the container and that's because it's listening to our m that was created so if we come back over here and we get rid of port 8000 we should get a working version and obviously this demonstrates the fact that our continuous deployment would obviously work as well because we've created another commit we've pushed that up the um the actions have acknowledged it and it's it's made the change so i suppose the only final bit to do now is to make sure that we don't have to keep on running this runner because if we weren't running run and it wouldn't pick up on the fact that this and this action has been performed it would come over here to our our settings our actions it would look for runners and this this runner if i refresh this page right now it would say it's offline but we want to obviously make sure that this is always online and that we're not having to log into the server to actually sort that out so the way that we do that is we navigate back up um to our actions folder which i'm obviously already in there but um just make sure that you are in action actions hyphen runner providing that you've copied my my um you know the same convention as me so we're doing it ll we should see run but we also see this services so i'm going to sudo the service oh sv c and then i'm going to install this so password for chris i think it was password wasn't it there you go so we've installed the service then i want to run the same command again pretty much but however now i want to start it and now the action has been started and if for any reason we wanted to find out as to what's going on we can run um sudo and we can run a status on it and that will give us the status as to you know what's going on with with this particular runner so right now that runner is always happening in the background and again just i suppose just to verify that what we could do is we could make a change to some file so let's come over to um here make a new file call it test.php and let's just put in some file and say echo hello world terminate our line save that and we've obviously got a change so we need to commit this and add it to test i'll push this up to our repository i'm going to open up our actions it's added a test so you can see how quick that is that you know it's almost immediate that it's acknowledged the the the change so it's added a test the build is is in queue at the moment setting it all up running the build perform the post actions and everything's been successful i've come back over here we've got no issues obviously no issues because we're not running anything and but now if i come on to our um our live website hit that we still got success and we should be able to get to test.php now hello world fantastic so guys i hope that makes sense you know we've done quite a bit in this this video we've uh we've done some ssh we've done some um docker compose we've set up digital ocean droplets we've done actions we've done runners we've done actually getting a wordpress instance up and running in relatively short space of time but also more importantly we've got that continuous integration and that continuous deployment so you can literally just worry about writing code now commit it to your branches as long as you're happy with it and then it will just deploy the code for you oh if you do have any questions as always please feel free to leave some comments down below but until next time take it easy
Info
Channel: The Tech Team
Views: 4,511
Rating: undefined out of 5
Keywords:
Id: -nT1Xs7-qqA
Channel Id: undefined
Length: 37min 20sec (2240 seconds)
Published: Tue Dec 08 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.