Docker Basics : Local Development Workflow with Docker

Objectives


  • Share code between container and host
  • Use a simple local development workflow

Discussion


Docker containers are perfect for local development. Let's pull a web application image to see how to use a Docker container for local development.

Steps


Step 1

$docker pull training/namer

The training/namer image is based on the Ubuntu image. It contains:

  • Ruby
  • Sinatra
  • Required dependencies

You will see:

latest: Pulling from training/namer
e9e06b06e14c: Pull complete 
a82efea989f9: Pull complete 
...
15faf92cfc78: Already exists 
Digest: sha256:23c65dee5c9f8fe46dcf9a9dbd1c91e7550235bd772df9839094dcec460386a4
Status: Downloaded newer image for training/namer:latest

Step 2

Adding our source code. Download our application source code.

git clone https://github.com/docker-training/namer.git
cd namer
ls -l

You will see:

-rw-r--r--  1 zepho  staff  342 Jun 14 14:27 Dockerfile
-rw-r--r--  1 zepho  staff   79 Jun 14 14:27 Gemfile
-rw-r--r--  1 zepho  staff   81 Jun 14 14:27 README.md
-rw-r--r--  1 zepho  staff  513 Jun 14 14:27 company_name_generator.rb
-rw-r--r--  1 zepho  staff  115 Jun 14 14:27 config.ru

Step 3

Let's create a container from our image. We have an image, source code and now we can add a container to run that code.

$docker run -d -v $(pwd):/opt/namer -w /opt/namer -p 80:9292 training/namer rackup

• The -d flag indicates that the container should run in daemon mode (in the background).
• The -v flag provides volume mounting inside containers.
• The -w flag sets the working directory inside the container.
• The -p flag maps port 9292 inside the container to port 80 on the host.

You will see:

06fe017c75a4161d6b743bb3d959228390795d104297787700e8b4ec4694c122

We have launched the application with the training/namer image and the rackup command. Notes on Mounting volumes inside containers: The -v flag mounts a directory from your host into your Docker container. The flag structure is:

[host-path]:[container-path]:[rw|ro]

• If [host-path] or [container-path] doesn't exist it is created.
• You can control the write status of the volume with the ro and rw options.
• If you don't specify rw or ro, it will be rw by default.

Step 4

Now let's see if our new container is running.

$docker ps

You will see:

CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS                  NAMES
06fe017c75a4        training/namer:latest   "rackup"            7 minutes ago       Up 7 minutes        0.0.0.0:80->9292/tcp   sharp_galileo    

Step 5

Let's browse to our web application on http://:80

You can find your IP address by running:

$boot2docker ip

In my case the URL is http://192.168.59.103:80. This will fail on both Mac OS and Ubuntu. The reason is that the server binds to localhost. So we need to start the Rack app like this :

root@f6b5cf85fafe:/opt/namer# rackup -o 0.0.0.0

inside the container to bind the server to 0.0.0.0. You will see:

[2015-06-21 02:52:17] INFO  WEBrick 1.3.1
[2015-06-21 02:52:17] INFO  ruby 1.9.3 (2013-11-22) [x86_64-linux]
[2015-06-21 02:52:17] INFO  WEBrick::HTTPServer#start: pid=19 port=9292
192.168.59.3 - - [21/Jun/2015:02:52:25 +0000] "GET / HTTP/1.1" 200 381 0.8535
192.168.59.3 - - [21/Jun/2015:02:52:25 +0000] "GET /favicon.ico HTTP/1.1" 404 541 0.0018
192.168.59.3 - - [21/Jun/2015:02:56:01 +0000] "GET / HTTP/1.1" 200 381 0.0065

Then you can browse to http://192.168.59.103/ on the host to view the application. The Container Basics article shows how to get inside a container.

Step 6

$docker stop sharp_galileo

Step 7

$docker ps

Summary


In this article, we saw how to share code between container and host. We also saw a simple local development workflow.


Related Articles


Create your own user feedback survey