Welcome to HooDev

My name is Daniel Hookins, I am a professional Software Engineer.

This site is about building software. It's about exploration and trying out new things.

My goal is to take this site from humble HTML files to build out some cool web apps.

Note: The purpose of this site is to just have some fun and learn / teach things along the way, please don't take it too seriously!

See All Articles

Serving up some HTML files with Nginx - Using Docker and Git

The first project is getting this up on the net. I'm going to use Digital Ocean, because I already have a Digital Ocean droplet kicking around that I'm not actually using.

I'll use a Basic Linux Server and get this HTML file up on the net.

Some More Details

It may seem simple, upload the HTML file, make sure the domain is pointing to the server and then Boom! done. But there are a few more complexities we are gonna add.

Git

We are going to make sure that we are doing some version control here.

Dockerization

We are going to use docker to make sure we are working with similar environments, wether it be development or production.

Environment

We're going to be doing all of this on Linux. It's free to download and use if you want to follow along. You can even fire up a virtual machine if you don't want to create a partition and boot into it.

A lot of these things will work directly on Mac, but you may need to adjust accordingly. Windows users... well, you're probably best of getting a flavour of linux up and running in a virtual machine. Trust me, you will save yourself a lot of pain.

Let's do this. Create the HTML File

This part is fairly straight-forward. Just put some HTML together and save it with the .html extension.

I use emmet in VS Code to get started with some boiler-plate code.

emmet-html-5-vscode

From here it will generate the boiler-plate HTML5 Code and you can fill in whatever you want.

html-5-boilerplate

Add Version Control

Now that we've spent a lot of time on making a pretty HTML page, we want to add some version control so that we don't loose our work.

I'm gonna initialise a new git repo and commit my changes so far.

git-init

Of course having it stored locally doesn't really back it up, so we will need to push it to a remote repo.

I like Bitbucket by Atlassian.

push-to-remote

We should also set up a Staging branch. This is for the version of the code that we are going to test out before we go live with it.

It means we can work on our site / app / program and get a new version ready before we push it to production.

I'll also push my most recent changes to this new Staging branch.

push-staging-to-remote

Okay, there is a lot more we can do with git, but for now we'll just use these staging and master branches to keep our code.

In the future we will set up feature branches, do merge requests and so on, but right now we don't need to.

Dockerization

Now let's containerize or dockerize our "app".

I'm going to assume you have docker installed. If not, go to the Docker official website and look at their guide on how to get it setup on your own machine.

We will also need Docker Compose (docker-compose) you can find details on this on the Docker Website too.

Now we need to create a Dockerfile.

FROM We're just going to use nginx because it's a purely static website (just this beautiful html file).

COPY We will copy all our static files over (in my case it's images and the html file)

dockerfile

We will use docker compose for this in a minute. But first, let's see it build.

This will build it with a friendly name and tag in the local directory.

docker-build

Just for funsies we can do a docker run to run the container we just built.

By giving it port 80 we can run it and access it locally in our browser by going to localhost

docker=run

Sweet success!

Well, sortof. Try and make any changes to your html file and refresh the page. Nothing.

This is because the html files have been copied over during the build, but these files are now copies of the ones we edited originally. In order to have them update automatically, we will need to map the volume - but that's getting ahead of ourselves a little bit.

Docker Compose

Okay, so we've got docker running, but we're going to need to set up Docker Compose. This will give us a lot more flexibility - especially later on when we add a whole bunch more services to the web app.

To set up Docker Compose we need to create a docker-compose.yml file:

docker-compose file

A quick little run-down on this.

What we are doing is creating the "web" service (our webserver) we are specifiying that during the build process we should use the current directory as the context and the Dockerfile we created as the Dockerfile.

We are then mapping the port 80 in the docker container to port 80 on our local machine (so we can just go to localhost in our browser).

And finally, we are creating a volume. This allows us to map our current directory "." to the directory in the docker conatiner "/usr/share/nginx/html". This part will allow us to see instant updates.

Now, before we docker-compose up, lets kill the running docker conatiner from before. You can see all of the docker containers running using docker ps

docker-ps

A great way to quickly kill all of the current docker containers is to do a docker kill $(docker ps -q) this will get all of the container ids in a list so it can kill them all at once.

docker-kill

Now we can run docker-compose up --build to use docker compose and run our webserver.

Note: we only add the --build part for this first time, as it hasn't been built yet. You don't need to build it every time, and after this you can probably just docker-compose up (unless you have made any changes to the Dockerfile or docker-compose.yml that you need to re-build.

docker-compose-up-build

Edit the HTML file and then refresh your browser. Ah, nice! there are our changes.

As you access different files from your webserver, you will notice the requests come up in your terminal. If you don't want to see this you can run docker-compose in detach mode - but personally, I like seeing what's going on. It makes debugging easier.

docker-requests

You can down docker-compose by hitting Ctrl + C

If running in Detach mode, or in a separate terminal window you can run docker-compose down

Okay, commit your changes, push them to staging and then let's go live!

Go Live! Production

First, a little disclaimer. Docker Compose is not really designed for use in production.

It can be used in production, but the biggest problem with it is that it needs to run on a single server, and therefore your containers won't be able to be distributed across multiple machines.

If you need to do this, Docker do have a product called Docker Swarm. But for us, a single machine is all we need for our little web app.

Set up your Production Server

I'm probably going to skip over a few steps here, and your setup could be totally different if you're following along.

I'm using Digital Ocean, and I have created a Droplet with Ubuntu and Docker (and Docker Compose) already installed. I have also modified the SSH settings so that I can SSH into the box and do the admin from my local machine.

Assuming you're at the same step, SSHed into your server, as root, with Docker and Docker-Compose installed... let's continue.

First, I'm going to create a new user to run Docker. I'm gonna call them hoodev

We also need to add that user to the docker and sudo groups so they can do what they need to do.

add-hoodev-to-groups

Now, logout from root.

Commit your latest changes and merge them into the Production branch (master)

merge-staging-to-master

Then push those bad boys to the remote origin

push-master

Get the files up and running on the production server

Okay, now we're getting down to the business end of things.

SSH into your production server as that user you created.

Once you're in, clone the git repo (you may need to set up your SSH keys and so on accordingly)

git-clone-on-prod

Wahoo! The files are now up on the Prod server, now we can cd in and docker-compose up.

docker-compose-up-prod-first

A few things of note here:

--build Notice that we need to build it again, this is because it hasn't been built on production yet.

--detach We are going to be running this in detach mode. This is just so we don't have the ongoing log and we can exit out of the terminal window.

If everything ran smoothly, you should now be able to access this docker container by hitting the domain.

We don't have SSL or anything yet, so no https:// but this is a good start. We are up and running in production!

basic-site-up-on-prod

If you want to take the site down you can simply docker-compose down in the project directory.

However, you are now free to disconnect from the prod server and the site will continue to run.

Read More Articles