Building a Web Server using Docker: A How To for MacOS
Tags: tech, devops, development, docker
Published: 2018-02-23 15:11:45

---
title: "Building a Web Server using Docker: A How To for MacOS"
published: true
description: A how to tutorial for setting up a web server with Docker on macOS. 
tags: tech, devops, development, docker
---
<em>Contributed by [Dylan Aspden](https://www.linkedin.com/in/dhaspden/)</em>
![alt text](https://cdn-images-1.medium.com/max/2000/1*Spug1WjvET_0D9iyLQ2uew.png)


<h3>Back up a second, what is Docker?</h3>
For those unfamiliar, [Docker](www.docker.com) is a software technology to create, deploy and run an application or group of applications in containers. What is a container you ask? A container is a package that contains everything needed to run your application. That includes the operating system and any programs on that operating system that are needed to run the application.

![alt text](https://cdn-images-1.medium.com/max/800/1*iTtfM-VA1zDIDONFqHniKg.png)

In our case, most of our containers are an install of Linux (Ubuntu, Alpine, etc.) with Node.js installed. Containers can be reused infinitely many times by saving the contents into something called an image.

Docker is extremely useful for deploying scaling services to production. You can launch new instances which only have to pull your Docker image down and run the entry command to get a running application. It’s also useful for developing new applications. Not only can Docker be used to deploy applications, but you can also develop locally inside of the container. This means that when you deploy to production you know what to expect. When you develop on MacOS you may run into cases where programs do not operate the same way when run on Debian, Ubuntu, etc. Docker allows you to foresee those potential problems before they ever see the light of day.

Docker is also useful for new hires learning the ropes on projects. All they have to do is install Docker and they can immediately jump into a project because all of the dependencies run inside of containers.

<h3>Is Docker the only solution out there?</h3>
No. There are other tools — Vagrant being one. However, the community adoption and support for Docker far exceeds other solutions, making Docker a lot simpler to use. Developing locally and deploying to production is a breeze with Docker. The largest hosts such as Azure, Google Cloud Platform, and Amazon Web Services completely support, and can scale, a Docker environment. This shifts a lot of the DevOps work to the cloud and lets you focus on the important part — building your application.

<h1>Ok! Let’s build a web server in Docker.</h1>


<h3>First, let’s get everything you’ll need.</h3>
Alright, to get started, you’ll need a few resources. If you don’t already have Homebrew — now’s the time. Open up your terminal and run the following command: ```$ /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”```

Follow the prompts — it may take a few minutes to install the XCode command line tools. Once that is complete, you need to update the Homebrew repository and install Docker For Mac. You are also going to need Node.js, you can install that now too. ```$ brew update
$ brew cask install docker
$ brew install node```

The first command updates the Homebrew repository. The second command will install Docker For Mac on your machine. The last command installs Node onto your machine. Once Docker For Mac is installed, you may need to run it by looking for it in your Applications folder and opening the program. Follow the steps on-screen to setup Docker.


<h3>Next — let's get Node set up.</h3>
You now have all of the tools you’ll need to create your Node application with Docker. Let’s create a new Node project.

You will not be using any libraries or frameworks to build the Node application, but the procedure would be the same if you did. Navigate to the folder you want to create the project in, and run the following commands. ```$ npm init --yes
$ touch index.js```

The first command creates a new Node project with the default values. The second command creates your JavaScript file that you will use as the application entrypoint.

Next, you are going to create a basic JavaScript file which starts an HTTP server on port 1337 and responds to all requests with “Hello, world!” Open the index.js file in your favourite editor and add the following code. ```const http = require(‘http’);
const server = http.createServer((request, response) => {
response.end(‘Hello, world!’);
});
server.listen(1337);```

Your Node application is done! Now all we have to do is create what is called a Dockerfile to define the image that will run our application.

<h3>Let’s create the Dockerfile.</h3>
You will need a container which runs an operating system and has Node installed. Many popular software products have associated Docker images to make it easier. Node is no exception. If you’re really curious, you can find additional resources here: https://hub.docker.com/_/node/.

You can use the LTS version of Node, which is codenamed “Carbon.” To get started creating your Docker image, you will need to create a Dockerfile in your project root. Use the touch command below to make that happen. ```$ touch Dockerfile```

Now open the Dockerfile and add the following. ```FROM node:carbon
WORKDIR /src
COPY . /src/
CMD [“node, “index.js”]
EXPOSE 1337```

The first line says that this image inherits from the image provided by the Node creators. This means that you get an install of Linux with Node LTS installed by default. Next, the working directory will be the /src folder. This means all commands that are run in the container are run inside of that directory. Now you can copy all files in your project into the /src folder. This means that your index.js is copied into the container. The fourth line defines the command that is used to start your application. You’ll want to run the application using Node. In future endeavours, you may want to consider a process manager which restarts the application automatically on failure. pm2 is good for this. The last command says that this container has your application port 1337 open by default so you can make requests against the server.

All that remains is to build and run your new application. Docker For Mac installs the Docker command line tools, which you can use to build your image. Run the following commands in your terminal. ```$ docker build -t webapp .
$ docker run -p 1337:1337 webapp```

The first command builds the image and the second command runs the image. Tell the second command that all requests to port 1337 on the local machine will be forwarded to port 1337 in the container (ie your application!).

All that remains is to open a new tab in your browser and navigate to http://localhost:1337. You should see a friendly greeting from your server inside of the Docker container.

Congratulations, you have deployed a Node application into a Docker container, and saved it to an image you can deploy anywhere! You can now theoretically load that image onto a service like Amazon Web Services, and create a cluster which scales this application for you automatically.


<i><h3>Additional Resources:</h3></i>
   1. [Deploying Docker Containers on AWS](https://aws.amazon.com/getting-started/tutorials/deploy-docker-containers/)
   2. [Deploying Docker Containers on Google Cloud Platform](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app)
   3. [Deploying Docker Containers on Azure](https://docs.docker.com/docker-for-azure/deploy/)



Like this tutorial? Keep an eye on [Hifyre's DevTips channel](https://medium.com/hifyre/dev-tips/home) for bi-weekly tips & tricks.

Oh and did we mention that we're hiring? [Reach out to us](https://hifyre.bamboohr.com/jobs/).