# First steps with Docker after the installation

> Learn your first steps with Docker after installing it: clone the getting-started project, build an image with docker build, and run it with docker run.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2020-07-11 | Topics: [Docker](https://flaviocopes.com/tags/docker/) | Canonical: https://flaviocopes.com/docker-first-steps/

After you complete the [Docker installation](https://flaviocopes.com/docker-installation-macos/) you should have a new window that will guide you through the first steps of creating [images](https://flaviocopes.com/docker-images/) and [containers](https://flaviocopes.com/docker-containers/) with Docker:

![Docker Desktop welcome screen with "Get started with Docker in a few easy steps" and a blue Start button](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.13.23.png)

This is an interesting way to get you up to speed with downloading your first image and running it as a container.

![Docker tutorial step 1 showing clone repository instructions with git clone command and terminal on the right](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.19.32.png)

You can run the commands in the terminal on the right built-in into this app, but I prefer to run it in my own shell.

I open the macOS Terminal, run `cd dev` to go into my home `dev` folder, and I create a `docker` subdirectory, where I'll host all the Docker experiments. I run `cd docker` to go into it, then I run

```sh
git clone https://github.com/docker/getting-started
```

This command created a new `getting-started` folder with the contents of the repository https://github.com/docker/getting-started : 

![Terminal showing ls -al command output in getting-started directory with Dockerfile and project files](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.23.33.png)

Now from this folder, run the command `docker build` in this way:

```sh
docker build -t docker101tutorial .
```

This is going to build the image from the content of the current folder you're in, with the tag name `docker101tutorial`.

This is the Dockerfile 

```
*# Install the base requirements for the app.*
*# This stage is to support development.*
FROM python:alpine AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

*# Run tests to validate app*
FROM node:12-alpine AS app-base
WORKDIR /app
COPY app/package.json app/yarn.lock ./
RUN yarn install
COPY app/spec ./spec
COPY app/src ./src
RUN yarn test

*# Clear out the node_modules and create the zip*
FROM app-base AS app-zip-creator
RUN rm -rf node_modules && \
    apk add zip && \
    zip -r /app.zip /app

*# Dev-ready container - actual files will be mounted in*
FROM base AS dev
CMD ["mkdocs", "serve", "-a", "0.0.0.0:8000"]

*# Do the actual build of the mkdocs site*
FROM base AS build
COPY . .
RUN mkdocs build

*# Extract the static content from the build*
*# and use a nginx image to serve the content*
FROM nginx:alpine
COPY --from=app-zip-creator /app.zip /usr/share/nginx/html/assets/app.zip
COPY --from=build /app/site /usr/share/nginx/html
```

As you can see, it creates our image from not just one, but 3 base images: `python:alpine`, `node:12-alpine` and `nginx:alpine`.

When you run `docker build -t docker101tutorial .`, it will start by downloading the first base image:

![Terminal showing docker build command downloading python:alpine base image with download progress bars](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.26.16.png)

Then it will run all the commands we defined in the Dockerfile.

![Terminal showing Docker build process executing Dockerfile steps including WORKDIR, COPY, and RUN pip install commands](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.26.18.png)

It keeps going until we reach the end:

![Terminal showing final Docker build steps completing successfully with "Successfully tagged docker101tutorial:latest"](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.27.10.png)

Now we have the image `docker101tutorial` and we can run a container based on this image.

Run the command `docker run` with those attributes:

```
docker run -d -p 80:80 --name docker-tutorial docker101tutorial
```

We're using the option `-d` to run the container in background and print the container ID. If you miss this flag, you will not immediately get back to the shell until the container exits (but if it's long-lived, for example it runs a service like a Node app or something, it will not exit automatically).

The `-p` option is used to map port 80 of the container to the host machine port 80. The container exposes a Web server on port 80, and we can map ports on our computer to ports exposed by the container.

`--name` assigns a name to the container, and finally we have the image name (`docker101tutorial`) we should use to create the container.

If you have any doubt about a command option, run `docker <command> --help`, in this case `docker run --help` and you'll get a very detailed explanation:

![Terminal showing docker run --help command output with detailed usage options and parameters explained](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.56.36.png)

This command is very fast and you'll get the container ID back:

![Terminal showing docker run command execution returning a long container ID string](https://flaviocopes.com/images/docker-first-steps/Screen_Shot_2020-07-05_at_10.50.56.png)
