A simple educational tutorial to get you to spin up your first Docker container. This repo includes a "hello world" node app that you should clone down (you don't need node.js on your local machine if you don't want to run the app locally). You'll go through the steps of building a Docker image for this app and running the container to run the app with Docker. Optionally, you can also push this image to Docker Hub and pull it down on another machine to get a feel for the "magic" of Docker.
0. Install Docker. Start Docker. Create a Docker Hub account. Login on the Docker client running on your local machine. Clone this repo. Navigate to the root directory of this app on your local machine. Take a quick look at the Dockerfile and .dockerignore file.
A Dockerfile
is just instructions for Docker on how to spin up your application inside a Docker container. If you look closely below, at some point Docker will run npm install
and npm start
. These are commands you would normally run manually if you wanted to run this Node app locally. FROM node:8
is telling Docker it needs to pull down an image of Node 8 (which you can find on Docker Hub) in order to run this app. There are a bunch of other commands you can put in a Dockerfile, which we won't go over. .dockerignore
is like .gitignore
, which tells Docker what directories to not include in the image. Refer to the Docker official docs for way more information.
FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm install --only=production
# Bundle app source
COPY . .
EXPOSE 3001
CMD [ "npm", "start" ]
node_modules
Npm-debug.log
We are going to first build a Docker image for this app. A Docker image works sort of like a "class" in object-oriented programming, whereas a Docker container is sort of like an instance of that "class". CD into the root directory of the app and run:
docker build -t [your Docker Hub username]/dockerdemo .
-t
sets the image tag. Remember to precede the tag with your Docker Hub username.
.
this period is not a typo! It tells docker to include everything in this directory in the image.
You'll now watch Docker pull down any dependencies (eg. Node 8) and run any commands you indicated in your Dockerfile.
Your local Docker should now have this image in it's "library". You can see all the images that are currently in your local Docker by running:
docker images
Once you have a Docker image, you can "run" it to create a Docker container.
docker run -p 80:3030 -d kapolyak/dockerdemo
-p
sets the relationship between a port in the host machine (where Docker is installed) and a port in Docker.
The port mapping here is important to understand. Docker is a runtime that is running on a host machine - its basically another host running in your computer. The number to the left of the colon is the port on your local machine that you want Docker to listen to. In this case, Docker is listening directly to http requests that come to your local machine. The number to the right is the port in Docker that your app is listening to. You can see in the node app that all this server knows is to handle requests coming in on port 3030, regardless of the host it is running on. The Node app doesn't need to know that it is inside a Docker container!
-d
runs the image in detached head mode, so it will continue running when you exit the terminal window.
Run this command to confirm the container is running.
docker ps
In a browser, navigate to localhost
- you should be hitting the Node app! We know it's inside Docker because you don't need to specify a port (80 is default here). If you run this app locally, you'll have to specify localhost:3030
.
You can access the "console" for this app inside Docker too.
docker logs [container id]
Pro-tip: you only need to type the first three characters of a container ID to reference that container.
You should see app listening on port 3030
.
docker stop [container id]
We are pushing the image to Docker Hub, not the container.
docker push kapolyak/dockerdemo
Once on Docker Hub, you can pull this image down onto any host machine (that has Docker installed). You can also go to your Docker Hub account and see the image there.
docker pull kapolyak/dockerdemo
Docker system prune --all
Docker is non-destructive and won’t delete any containers you have previously built. This can quickly hog your machine’s storage as these containers tend to be large. There are a few different ways to clean the system, but this is the most useful one during development. Here is Docker’s own warning regarding this command:
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all build cache