Get Started

Get Started

Welcome! We are excited that you want to learn Docker. The Docker Get Started Tutorial teaches you how to:

Set up your Docker environment (on this page) Build an image and run it as one container Scale your app to run multiple containers Distribute your app across a cluster Stack services by adding a backend database Deploy your app to production Get Started, Part 1: Orientation and setup

Get Started :: Part 1 :: Orientation

user@workstation:~$ docker --version
Docker version 17.12.1-ce, build 7390fc6
user@workstation:~$ sudo docker info
Containers: 3
 Running: 0
 Paused: 0
 Stopped: 3
Images: 2
Server Version: 17.12.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 9b55aab90508bd389d7654c4baf173a981477d55
runc version: 9f9c96235cc97674e935002fc3d78361b696a69e
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.13.0-36-generic
Operating System: Ubuntu 16.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.55GiB
Name: workstation
ID: DLNC:VNQA:EV5K:B7Y5:NDAK:EWZW:JEFE:QQWF:HITS:LF5I:6577:7UMM
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support
user@workstation:~$
user@workstation:~$ sudo docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              f2a91732366c        3 months ago        1.85kB
user@workstation:~$
user@workstation:~$ sudo docker container ls --all
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
d21edb2d78ac        hello-world         "/hello"            About a minute ago   Exited (0) About a minute ago                       cocky_wozniak
user@workstation:~$

Get Started :: Part 2 :: Containers

Dockerfile defines what goes on in the environment inside your container. Access to resources like networking interfaces and disk drives is virtualized inside this environment, which is isolated from the rest of your system, so you need to map ports to the outside world, and be specific about what files you want to “copy in” to that environment. However, after doing that, you can expect that the build of your app defined in this Dockerfile behaves exactly the same wherever it runs.

user@workstation:~$ mkdir dockerapp
user@workstation:~$ cd dockerapp/
user@workstation:~/dockerapp$ nano Dockerfile
# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]
user@workstation:~/dockerapp$ nano requirements.txt
Flask
Redis
user@workstation:~/dockerapp$ nano app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)
user@workstation:~/dockerapp$ ls
app.py  Dockerfile  requirements.txt
user@workstation:~/dockerapp$ sudo docker build -t friendlyhello .
[sudo] password for user: 
Sending build context to Docker daemon  4.608kB
Step 1/7 : FROM python:2.7-slim
2.7-slim: Pulling from library/python
d2ca7eff5948: Pull complete 
cef69dd0e5b9: Pull complete 
50e1d7e4f3c6: Pull complete 
861e9de5333f: Pull complete 
Digest: sha256:e9baca9b405d3bbba71d4c3c4ce8a461e4937413b8b910cb1801dfac0a2423aa
Status: Downloaded newer image for python:2.7-slim
 ---> 52ad41c7aea4
Step 2/7 : WORKDIR /app
Removing intermediate container 693c4ac2aaa3
 ---> 653aa5dbfb86
Step 3/7 : ADD . /app
 ---> 1b1e78d2dd61
Step 4/7 : RUN pip install --trusted-host pypi.python.org -r requirements.txt
 ---> Running in 865494427eeb
Collecting Flask (from -r requirements.txt (line 1))
  Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
Collecting Redis (from -r requirements.txt (line 2))
  Downloading redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting itsdangerous>=0.21 (from Flask->-r requirements.txt (line 1))
  Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.4 (from Flask->-r requirements.txt (line 1))
  Downloading Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting Werkzeug>=0.7 (from Flask->-r requirements.txt (line 1))
  Downloading Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting click>=2.0 (from Flask->-r requirements.txt (line 1))
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask->-r requirements.txt (line 1))
  Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
  Running setup.py bdist_wheel for itsdangerous: started
  Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
  Running setup.py bdist_wheel for MarkupSafe: started
  Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis
Successfully installed Flask-0.12.2 Jinja2-2.10 MarkupSafe-1.0 Redis-2.10.6 Werkzeug-0.14.1 click-6.7 itsdangerous-0.24
Removing intermediate container 865494427eeb
 ---> 2ceb1fa8eac0
Step 5/7 : EXPOSE 80
 ---> Running in 11283ab6af81
Removing intermediate container 11283ab6af81
 ---> f5a18d53f350
Step 6/7 : ENV NAME World
 ---> Running in 1a4cadf70acf
Removing intermediate container 1a4cadf70acf
 ---> bf77b64bccbe
Step 7/7 : CMD ["python", "app.py"]
 ---> Running in 161d6d53a217
Removing intermediate container 161d6d53a217
 ---> 23f8ef6f5ce3
Successfully built 23f8ef6f5ce3
Successfully tagged friendlyhello:latest
user@workstation:~/dockerapp$ sudo docker image ls 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
friendlyhello       latest              2cbea11b7d6b        8 seconds ago       148MB
python              2.7-slim            52ad41c7aea4        3 weeks ago         139MB
hello-world         latest              f2a91732366c        3 months ago        1.85kB
user@workstation:~/dockerapp$
user@workstation:~/dockerapp$ sudo docker run -p 4000:80 friendlyhello
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

Open http://127.0.0.1:4000/

Hello World!
Hostname: 24d781335957
Visits: cannot connect to Redis, counter disabled

Last updated