Skip to content

Commit

Permalink
Improvise get started docs
Browse files Browse the repository at this point in the history
  • Loading branch information
usha-mandya committed May 21, 2020
1 parent 8716eb0 commit ba08845
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 68 deletions.
115 changes: 59 additions & 56 deletions get-started/part2.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ Work through the orientation and setup in [Part 1](index.md).

## Introduction

Now that you've set up your development environment, thanks to Docker Desktop,
you can begin to develop containerized applications. In general, the development workflow looks like this:
Now that you've set up your development environment, you can begin to develop containerized applications. In general, the development workflow looks like this:

1. Create and test individual containers for each component of your application by first creating Docker images.

2. Assemble your containers and supporting infrastructure into a complete application.

3. Test, share, and deploy your complete containerized application.

In this stage of the tutorial, let's focus on step 1 of this workflow: creating the images that your containers will be based on. Remember, a Docker image captures the private filesystem that your containerized processes will run in; you need to create an image that contains just what your application needs to run.

> **Containerized development environments** are easier to set up than traditional development environments, once you learn how to build images as we'll discuss below. This is because a containerized development environment will isolate all the dependencies your app needs inside your Docker image; there's no need to install anything other than Docker on your development machine. In this way, you can easily develop applications for different stacks without changing anything on your development machine.
## Set up

Let us download an example project from the [Docker Samples](https://github.com/dockersamples/node-bulletin-board) page.
Let us download the `node-bulletin-board` example project. This is a simple bulletin board application written in Node.js.

<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#clonegit">Git</a></li>
Expand Down Expand Up @@ -85,85 +84,44 @@ cd node-bulletin-board-master/bulletin-board-app
<hr>
</div>

The `node-bulletin-board` project is a simple bulletin board application, written in Node.js. In this example, let's imagine you wrote this app, and are now trying to containerize it.

## Define a container with Dockerfile

Take a look at the file called `Dockerfile` in the bulletin board application. Dockerfiles describe how to assemble a private filesystem for a container, and can also contain some metadata describing how to run a container based on this image. The bulletin board app Dockerfile looks like this:

```dockerfile
# Use the official image as a parent image.
FROM node:current-slim

# Set the working directory.
WORKDIR /usr/src/app

# Copy the file from your host to your current location.
COPY package.json .

# Run the command inside your image filesystem.
RUN npm install

# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080

# Run the specified command within the container.
CMD [ "npm", "start" ]

# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .
```

Writing a Dockerfile is the first step to containerizing an application. You can think of these Dockerfile commands as a step-by-step recipe on how to build up your image. This one takes the following steps:

- Start `FROM` the pre-existing `node:current-slim` image. This is an *official image*, built by the node.js vendors and validated by Docker to be a high-quality image containing the Node.js Long Term Support (LTS) interpreter and basic dependencies.
- Use `WORKDIR` to specify that all subsequent actions should be taken from the directory `/usr/src/app` *in your image filesystem* (never the host's filesystem).
- `COPY` the file `package.json` from your host to the present location (`.`) in your image (so in this case, to `/usr/src/app/package.json`)
- `RUN` the command `npm install` inside your image filesystem (which will read `package.json` to determine your app's node dependencies, and install them)
- `COPY` in the rest of your app's source code from your host to your image filesystem.

You can see that these are much the same steps you might have taken to set up and install your app on your host. However, capturing these as a Dockerfile allows you to do the same thing inside a portable, isolated Docker image.

The steps above built up the filesystem of our image, but there are other lines in your Dockerfile.
After downloading the project, take a look at the file called `Dockerfile` in the bulletin board application. Dockerfiles describe how to assemble a private filesystem for a container, and can also contain some metadata describing how to run a container based on this image.

The `CMD` directive is the first example of specifying some metadata in your image that describes how to run a container based on this image. In this case, it's saying that the containerized process that this image is meant to support is `npm start`.

The `EXPOSE 8080` informs Docker that the container is listening on port 8080 at runtime.

What you see above is a good way to organize a simple Dockerfile; always start with a `FROM` command, follow it with the steps to build up your private filesystem, and conclude with any metadata specifications. There are many more Dockerfile directives than just the few you see above. For a complete list, see the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).
For more information about the Dockerfile used in the bulletin board application, see [Sample Dockerfile](#sample-dockerfile).

## Build and test your image

Now that you have some source code and a Dockerfile, it's time to build your first image, and make sure the containers launched from it work as expected.

> **Windows users**: this example uses Linux containers. Make sure your environment is running Linux containers by right-clicking on the Docker logo in your system tray, and clicking **Switch to Linux containers** if the option appears. Don't worry - all the commands in this tutorial work the exact same way for Windows containers.
Make sure you're in the directory `node-bulletin-board/bulletin-board-app` in a terminal or PowerShell using the `cd` command. Let's build your bulletin board image:
Make sure you're in the directory `node-bulletin-board/bulletin-board-app` in a terminal or PowerShell using the `cd` command. Run the following command to build your bulletin board image:

```script
docker build --tag bulletinboard:1.0 .
```

You'll see Docker step through each instruction in your Dockerfile, building up your image as it goes. If successful, the build process should end with a message `Successfully tagged bulletinboard:1.0`.

> **Windows users:** you may receive a message titled 'SECURITY WARNING' at this step, noting the read, write, and execute permissions being set for files added to your image. We aren't handling any sensitive information in this example, so feel free to disregard the warning in this example.
> **Windows users:**
>
> This example uses Linux containers. Make sure your environment is running Linux containers by right-clicking on the Docker logo in your system tray, and clicking **Switch to Linux containers**. Don't worry - all the commands in this tutorial work the exact same way for Windows containers.
>
> You may receive a message titled 'SECURITY WARNING' after running the image, noting the read, write, and execute permissions being set for files added to your image. We aren't handling any sensitive information in this example, so feel free to disregard the warning in this example.
## Run your image as a container

1. Start a container based on your new image:
1. Run the following command to start a container based on your new image:

```script
docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0
```
There are a couple of common flags here:
- `--publish` asks Docker to forward traffic incoming on the host's port 8000, to the container's port 8080. Containers have their own private set of ports, so if you want to reach one from the network, you have to forward traffic to it in this way. Otherwise, firewall rules will prevent all network traffic from reaching your container, as a default security posture.
- `--publish` asks Docker to forward traffic incoming on the host's port 8000 to the container's port 8080. Containers have their own private set of ports, so if you want to reach one from the network, you have to forward traffic to it in this way. Otherwise, firewall rules will prevent all network traffic from reaching your container, as a default security posture.
- `--detach` asks Docker to run this container in the background.
- `--name` specifies a name with which you can refer to your container in subsequent commands, in this case `bb`.
Also notice, you didn't specify what process you wanted your container to run. You didn't have to, as you've used the `CMD` directive when building your Dockerfile; thanks to this, Docker knows to automatically run the process `npm start` inside the container when it starts up.
2. Visit your application in a browser at `localhost:8000`. You should see your bulletin board application up and running. At this step, you would normally do everything you could to ensure your container works the way you expected; now would be the time to run unit tests, for example.
3. Once you're satisfied that your bulletin board container works correctly, you can delete it:
Expand All @@ -180,6 +138,51 @@ At this point, you've successfully built an image, performed a simple containeri
[On to Part 3 >>](part3.md){: class="button outline-btn" style="margin-bottom: 30px; margin-right: 100%"}
## Sample Dockerfile
Writing a Dockerfile is the first step to containerizing an application. You can think of these Dockerfile commands as a step-by-step recipe on how to build up your image. The Dockerfile in the bulletin board app looks like this:
```dockerfile
# Use the official image as a parent image.
FROM node:current-slim
# Set the working directory.
WORKDIR /usr/src/app
# Copy the file from your host to your current location.
COPY package.json .
# Run the command inside your image filesystem.
RUN npm install
# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080
# Run the specified command within the container.
CMD [ "npm", "start" ]
# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .
```

The dockerfile defined in this example takes the following steps:

- Start `FROM` the pre-existing `node:current-slim` image. This is an *official image*, built by the node.js vendors and validated by Docker to be a high-quality image containing the Node.js Long Term Support (LTS) interpreter and basic dependencies.
- Use `WORKDIR` to specify that all subsequent actions should be taken from the directory `/usr/src/app` *in your image filesystem* (never the host's filesystem).
- `COPY` the file `package.json` from your host to the present location (`.`) in your image (so in this case, to `/usr/src/app/package.json`)
- `RUN` the command `npm install` inside your image filesystem (which will read `package.json` to determine your app's node dependencies, and install them)
- `COPY` in the rest of your app's source code from your host to your image filesystem.

You can see that these are much the same steps you might have taken to set up and install your app on your host. However, capturing these as a Dockerfile allows you to do the same thing inside a portable, isolated Docker image.

The steps above built up the filesystem of our image, but there are other lines in your Dockerfile.

The `CMD` directive is the first example of specifying some metadata in your image that describes how to run a container based on this image. In this case, it's saying that the containerized process that this image is meant to support is `npm start`.

The `EXPOSE 8080` informs Docker that the container is listening on port 8080 at runtime.

What you see above is a good way to organize a simple Dockerfile; always start with a `FROM` command, follow it with the steps to build up your private filesystem, and conclude with any metadata specifications. There are many more Dockerfile directives than just the few you see above. For a complete list, see the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).

## CLI references

Further documentation for all CLI commands used in this article are available here:
Expand Down
31 changes: 19 additions & 12 deletions get-started/part3.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ Work through the steps to build an image and run it as a containerized applicati

## Introduction

At this point, you've built a containerized application in [Part 2](part2.md) on your local development machine, thanks to Docker Desktop. The final step in developing a containerized application is to share your images on a registry like [Docker Hub](https://hub.docker.com/), so they can be easily downloaded and run on any destination machine.
At this point, you've built a containerized application described in [Part 2](part2.md) on your local development machine.

The final step in developing a containerized application is to share your images on a registry like [Docker Hub](https://hub.docker.com/){: target="_blank" class="_”}, so they can be easily downloaded and run on any destination machine.

## Set up your Docker Hub account

If you don't yet have a Docker ID, follow these steps to set one up; this will allow you to share images on Docker Hub.
If you don't have a Docker ID, follow these steps to create one. A Docker ID allows you to share images on Docker Hub.

1. Visit the Docker Hub sign up page, [https://hub.docker.com/signup](https://hub.docker.com/signup).
1. Visit the [Docker Hub sign up](https://hub.docker.com/signup){: target="_blank" class="_”} page.

2. Fill out the form and submit to create your Docker ID.

Expand All @@ -30,33 +32,38 @@ If you don't yet have a Docker ID, follow these steps to set one up; this will a

5. Fill in your new Docker ID and password. After you have successfully authenticated, your Docker ID appears in the Docker Desktop menu in place of the 'Sign in' option you just used.

> You can do the same thing from the command line by typing `docker login`.
You can also sign into Docker Hub from the command line by typing `docker login`.

## Create a Docker Hub repository and push your image

At this point, you've set up your Docker Hub account and have connected it to your Docker Desktop. Now let's make our first repo, and share our bulletin board app there.
>
> Before creating a repository, ensure you’ve set up your Docker Hub account and have connected it to your Docker Desktop.
Now let's create your first repository, and push your bulletin board image to Docker Hub.

1. Click on the Docker icon in your menu bar, and navigate to **Repositories > Create**. You'll be taken to a Docker Hub page to create a new repository.
1. Click on the Docker icon in your menu bar, and navigate to **Repositories > Create**. You'll be redirected to the **Create Repository** page on Docker Hub.

2. Fill out the repository name as `bulletinboard`. Leave all the other options alone for now, and click **Create** at the bottom.
2. Type the repository name as `bulletinboard` and click **Create** at the bottom of the page. Do not fill any other details for now.

![make a repo](images/newrepo.png){:width="100%"}

3. Now you are ready to share your image on Docker Hub, but there's one thing you must do first: images must be *namespaced correctly* to share on Docker Hub. Specifically, you must name images like `<Docker ID>/<Repository Name>:<tag>`. You can relabel your `bulletinboard:1.0` image like this (of course, please replace `gordon` with your Docker ID):
3. You are now ready to share your image on Docker Hub, however, there's one thing you must do first: images must be *namespaced correctly* to share on Docker Hub. Specifically, you must name images like `<Your Docker ID>/<Repository Name>:<tag>`.

Make sure you’re in the `node-bulletin-board/bulletin-board-app` directory in a terminal or PowerShell then and run:

```shell
docker tag bulletinboard:1.0 gordon/bulletinboard:1.0
docker tag bulletinboard:1.0 <Your Docker ID>/bulletinboard:1.0
```

4. Finally, push your image to Docker Hub:

```shell
docker push gordon/bulletinboard:1.0
docker push <Your Docker ID>/bulletinboard:1.0
```

Visit your repository in Docker Hub, and you'll see your new image there. Remember, Docker Hub repositories are public by default.
Visit your repository in [Docker Hub](https://hub.docker.com/repositories){: target="_blank" class="_”}, and you'll see your new image there. Remember, Docker Hub repositories are public by default.
> **Having trouble pushing?** Remember, you must be signed in to Docker Hub through Docker Desktop or the command line, and you must also name your images correctly, as per the above steps. If the push seemed to work, but you don't see it in Docker Hub, refresh your browser after a couple of minutes and check again.
> **Having trouble pushing?** Remember, you must be signed into Docker Hub through Docker Desktop or the command line, and you must also name your images correctly, as per the above steps. If the push seemed to work, but you don't see it in Docker Hub, refresh your browser after a couple of minutes and check again.
## Conclusion
Expand Down

0 comments on commit ba08845

Please sign in to comment.