github.com/jaegerpicker/docker@v0.7.7-0.20150325003727-22dba32b4dab/docs/sources/project/set-up-dev-env.md (about)

     1  page_title: Work with a development container
     2  page_description: How to use Docker's development environment
     3  page_keywords: development, inception, container, image Dockerfile, dependencies, Go, artifacts
     4  
     5  # Work with a development container
     6  
     7  In this section, you learn to develop like a member of Docker's core team.
     8  The `docker` repository includes a `Dockerfile` at its root. This file defines
     9  Docker's development environment.  The `Dockerfile` lists the environment's
    10  dependencies: system libraries and binaries, go environment, go dependencies,
    11  etc. 
    12  
    13  Docker's development environment is itself, ultimately a Docker container.
    14  You use the `docker` repository and its `Dockerfile` to create a Docker image, 
    15  run a Docker container, and develop code in the container. Docker itself builds,
    16  tests, and releases new Docker versions using this container.
    17  
    18  If you followed the procedures that <a href="/project/set-up-git" target="_blank">
    19  set up Git for contributing</a>, you should have a fork of the `docker/docker`
    20  repository. You also created a branch called `dry-run-test`. In this section,
    21  you continue working with your fork on this branch.
    22  
    23  ##  Clean your host of Docker artifacts
    24  
    25  Docker developers run the latest stable release of the Docker software; Or 
    26  Boot2docker and Docker if their machine is Mac OS X. They clean their local
    27  hosts of unnecessary Docker artifacts such as stopped containers or unused
    28  images. Cleaning unnecessary artifacts isn't strictly necessary but it is
    29  good practice, so it is included here.
    30  
    31  To remove unnecessary artifacts.
    32  
    33  1. Verify that you have no unnecessary containers running on your host.
    34  
    35          $ docker ps
    36  
    37      You should see something similar to the following:
    38  
    39      <table class="code">
    40        <tr>
    41          <th>CONTAINER ID</th>
    42          <th>IMAGE</th>
    43          <th>COMMAND</th>
    44          <th>CREATED</th>
    45          <th>STATUS</th>
    46          <th>PORTS</th>
    47          <th>NAMES</th>
    48        </tr>
    49      </table>
    50  
    51      There are no running containers on this host. If you have running but unused
    52      containers, stop and then remove them with the `docker stop` and `docker rm`
    53      commands.
    54  
    55  2. Verify that your host has no dangling images.
    56  
    57          $ docker images
    58  
    59      You should see something similar to the following:
    60  
    61      <table class="code">
    62        <tr>
    63          <th>REPOSITORY</th>
    64          <th>TAG</th>
    65          <th>IMAGE ID</th>
    66          <th>CREATED</th>
    67          <th>VIRTUAL SIZE</th>
    68        </tr>
    69      </table>
    70  
    71      This host has no images. You may have one or more _dangling_ images. A
    72      dangling image is not used by a running container and is not an ancestor of
    73      another image on your system. A fast way to remove dangling containers is
    74      the following:
    75  
    76          $ docker rmi -f $(docker images -q -a -f dangling=true)
    77  
    78      This command uses `docker images` to lists all images (`-a` flag) by numeric
    79      IDs (`-q` flag) and filter them to find dangling images (`-f
    80      dangling=true`). Then, the `docker rmi` command forcibly (`-f` flag) removes
    81      the resulting list. To remove just one image, use the `docker rmi ID`
    82      command.
    83  
    84  	
    85  ## Build an image
    86  
    87  If you followed the last procedure, your host is clean of unnecessary images 
    88  and containers. In this section, you build an image from the Docker development
    89  environment.
    90  
    91  1. Open a terminal.
    92  
    93      Mac users, use `boot2docker status` to make sure Boot2Docker is running. You
    94      may need to run `eval "$(boot2docker shellinit)"` to initialize your shell
    95      environment.
    96  
    97  3. Change into the root of your forked repository.
    98  
    99          $ cd ~/repos/docker-fork 
   100          
   101  	If you are following along with this guide, you created a `dry-run-test`
   102  	branch when you <a href="/project/set-up-git" target="_blank"> set up Git for
   103  	contributing</a>
   104  
   105  4. Ensure you are on your `dry-run-test` branch.
   106  
   107          $ git checkout dry-run-test
   108          
   109      If you get a message that the branch doesn't exist, add the `-b` flag so the
   110      command both creates the branch and checks it out.
   111  
   112  5. Compile your development environment container into an image.
   113  
   114          $ docker build -t dry-run-test .
   115  
   116      The `docker build` command returns informational message as it runs. The
   117      first build may take a few minutes to create an image. Using the
   118      instructions in the `Dockerfile`, the build may need to download source and
   119      other images. A successful build returns a final status message similar to
   120      the following:
   121  
   122          Successfully built 676815d59283
   123  
   124  6. List your Docker images again.
   125  
   126          $ docker images
   127  
   128      You should see something similar to this:
   129  
   130      <table class="code">
   131        <tr>
   132          <th>REPOSTITORY</th>
   133          <th>TAG</th>
   134          <th>IMAGE ID</th>
   135          <th>CREATED</th>
   136          <th>VIRTUAL SIZE</th>
   137        </tr>
   138        <tr>
   139          <td>dry-run-test</td>
   140          <td>latest</td>
   141          <td>663fbee70028</td>
   142          <td>About a minute ago</td>
   143          <td></td>
   144        </tr>
   145        <tr>
   146          <td>ubuntu</td>
   147          <td>trusty</td>
   148          <td>2d24f826cb16</td>
   149          <td>2 days ago</td>
   150          <td>188.3 MB</td>
   151        </tr>
   152        <tr>
   153          <td>ubuntu</td>
   154          <td>trusty-20150218.1</td>
   155          <td>2d24f826cb16</td>
   156          <td>2 days ago</td>
   157          <td>188.3 MB</td>
   158        </tr>
   159        <tr>
   160          <td>ubuntu</td>
   161          <td>14.04</td>
   162          <td>2d24f826cb16</td>
   163          <td>2 days ago</td>
   164          <td>188.3 MB</td>
   165        </tr>
   166        <tr>
   167          <td>ubuntu</td>
   168          <td>14.04.2</td>
   169          <td>2d24f826cb16</td>
   170          <td>2 days ago</td>
   171          <td>188.3 MB</td>
   172        </tr>
   173        <tr>
   174          <td>ubuntu</td>
   175          <td>latest</td>
   176          <td>2d24f826cb16</td>
   177          <td>2 days ago</td>
   178          <td>188.3 MB</td>
   179        </tr>
   180      </table>
   181  
   182      Locate your new `dry-run-test` image in the list. You should also see a
   183      number of `ubuntu` images. The build process creates these. They are the
   184      ancestors of your new Docker development image. When you next rebuild your
   185      image, the build process reuses these ancestors images if they exist. 
   186  
   187      Keeping the ancestor images improves the build performance. When you rebuild
   188      the child image, the build process uses the local ancestors rather than
   189      retrieving them from the Hub. The build process gets new ancestors only if
   190      DockerHub has updated versions.
   191  
   192  ## Start a container and run a test
   193  
   194  At this point, you have created a new Docker development environment image. Now,
   195  you'll use this image to create a Docker container to develop in. Then, you'll
   196  build and run a `docker` binary in your container.
   197  
   198  1. Open two additional terminals on your host.
   199  
   200      At this point, you'll have about three terminals open.
   201  
   202      ![Multiple terminals](/project/images/three_terms.png)
   203  
   204      Mac OSX users, make sure you run `eval "$(boot2docker shellinit)"` in any new 
   205      terminals.
   206  
   207  2. In a terminal, create a new container from your `dry-run-test` image.
   208  
   209          $ docker run --privileged --rm -ti dry-run-test /bin/bash
   210          root@5f8630b873fe:/go/src/github.com/docker/docker# 
   211  
   212      The command creates a container from your `dry-run-test` image. It opens an
   213      interactive terminal (`-ti`) running a `/bin/bash shell`.  The
   214      `--privileged` flag gives the container access to kernel features and device
   215      access. It is this flag that allows you to run a container in a container.
   216      Finally, the `-rm` flag instructs Docker to remove the container when you
   217      exit the `/bin/bash` shell.
   218  
   219      The container includes the source of your image repository in the
   220      `/go/src/github.com/docker/docker` directory. Try listing the contents to
   221      verify they are the same as that of your `docker-fork` repo.
   222  
   223      ![List example](/project/images/list_example.png)
   224  
   225  
   226  3. Investigate your container bit. 
   227  
   228      If you do a `go version` you'll find the `go` language is part of the
   229      container. 
   230  
   231          root@31ed86e9ddcf:/go/src/github.com/docker/docker# go version
   232          go version go1.4.2 linux/amd64
   233  
   234      Similarly, if you do a `docker version` you find the container
   235      has no `docker` binary. 
   236  
   237          root@31ed86e9ddcf:/go/src/github.com/docker/docker# docker version
   238          bash: docker: command not found
   239  
   240      You will create one in the next steps.
   241  
   242  4. From the `/go/src/github.com/docker/docker` directory make a `docker` binary
   243  with the `make.sh` script.
   244  
   245          root@5f8630b873fe:/go/src/github.com/docker/docker# hack/make.sh binary
   246  
   247      You only call `hack/make.sh` to build a binary _inside_ a Docker
   248      development container as you are now. On your host, you'll use `make`
   249      commands (more about this later). 
   250  
   251      As it makes the binary, the `make.sh` script reports the build's progress.
   252      When the command completes successfully, you should see the following
   253      output:
   254  
   255          ---> Making bundle: ubuntu (in bundles/1.5.0-dev/ubuntu)
   256          Created package {:path=>"lxc-docker-1.5.0-dev_1.5.0~dev~git20150223.181106.0.1ab0d23_amd64.deb"}
   257          Created package {:path=>"lxc-docker_1.5.0~dev~git20150223.181106.0.1ab0d23_amd64.deb"}
   258  
   259  5. List all the contents of the `binary` directory.
   260  
   261          root@5f8630b873fe:/go/src/github.com/docker/docker#  ls bundles/1.5.0-dev/binary/
   262          docker  docker-1.5.0-dev  docker-1.5.0-dev.md5  docker-1.5.0-dev.sha256
   263  
   264      You should see that `binary` directory, just as it sounds, contains the
   265      made binaries.
   266  
   267  
   268  6. Copy the `docker` binary to the `/usr/bin` of your container.
   269  
   270          root@5f8630b873fe:/go/src/github.com/docker/docker#  cp bundles/1.5.0-dev/binary/docker /usr/bin
   271  
   272  7. Inside your container, check your Docker version.
   273  
   274          root@5f8630b873fe:/go/src/github.com/docker/docker# docker --version
   275          Docker version 1.5.0-dev, build 6e728fb
   276  
   277      Inside the container you are running a development version. This is version
   278      on the current branch it reflects the value of the `VERSION` file at the
   279      root of your `docker-fork` repository.
   280  
   281  8. Start a `docker` daemon running inside your container.
   282  
   283          root@5f8630b873fe:/go/src/github.com/docker/docker#  docker -dD
   284  
   285      The `-dD` flag starts the daemon in debug mode; You'll find this useful
   286      when debugging your code.
   287  
   288  9. Bring up one of the terminals on your local host.
   289  
   290  
   291  10. List your containers and look for the container running the `dry-run-test` image.
   292  
   293          $ docker ps
   294  
   295      <table class="code">
   296        <tr>
   297          <th>CONTAINER ID</th>
   298          <th>IMAGE</th>
   299          <th>COMMAND</th>
   300          <th>CREATED</th>
   301          <th>STATUS</th>
   302          <th>PORTS</th>
   303          <th>NAMES</th>
   304        </tr>
   305        <tr>
   306          <td>474f07652525</td>
   307          <td>dry-run-test:latest</td>
   308          <td>"hack/dind /bin/bash</td>
   309          <td>14 minutes ago</td>
   310          <td>Up 14 minutes</td>
   311          <td></td>
   312          <td>tender_shockley</td>
   313        </tr>
   314      </table>
   315  
   316      In this example, the container's name is `tender_shockley`; yours will be
   317      different.
   318  
   319  11. From the terminal, start another shell on your Docker development container.
   320  
   321          $ docker exec -it tender_shockley bash
   322  
   323      At this point, you have two terminals both with a shell open into your
   324      development container. One terminal is running a debug session. The other
   325      terminal is displaying a `bash` prompt.
   326  
   327  12. At the prompt, test the Docker client by running the `hello-world` container.	
   328  
   329          root@9337c96e017a:/go/src/github.com/docker/docker#  docker run hello-world
   330  
   331      You should see the image load and return. Meanwhile, you
   332      can see the calls made via the debug session in your other terminal.
   333  
   334      ![List example](/project/images/three_running.png)
   335  
   336  
   337  ## Restart a container with your source
   338  
   339  At this point, you have experienced the "Docker inception" technique. That is,
   340  you have:
   341  
   342  * built a Docker image from the Docker repository
   343  * created and started a Docker development container from that image
   344  * built a Docker binary inside of your Docker development container
   345  * launched a `docker` daemon using your newly compiled binary
   346  * called the `docker` client to run a `hello-world` container inside
   347    your development container
   348  
   349  When you really get to developing code though, you'll want to iterate code
   350  changes and builds inside the container. For that you need to mount your local
   351  Docker repository source into your Docker container. Try that now.
   352  
   353  1. If you haven't already, exit out of BASH shells in your running Docker
   354  container.
   355  
   356      If you have followed this guide exactly, exiting out your BASH shells stops
   357      the running container. You can use the `docker ps` command to verify the
   358      development container is stopped. All of your terminals should be at the
   359      local host prompt.
   360  
   361  2. Choose a terminal and make sure you are in your `docker-fork` repository.
   362  
   363          $ pwd
   364          /Users/mary/go/src/github.com/moxiegirl/docker-fork
   365  
   366      Your location will be different because it reflects your environment. 
   367  
   368  3. Create a container using `dry-run-test` but this time mount your repository
   369  onto the `/go` directory inside the container.
   370  
   371          $  docker run --privileged --rm -ti -v `pwd`:/go/src/github.com/docker/docker dry-run-test /bin/bash
   372  
   373      When you pass `pwd`, `docker` resolves it to your current directory.
   374  
   375  4. From inside the container, list your `binary` directory.
   376  
   377          root@074626fc4b43:/go/src/github.com/docker/docker# ls bundles/1.5.0-dev/binary
   378          ls: cannot access binary: No such file or directory
   379  
   380      Your `dry-run-test` image does not retain any of the changes you made inside
   381      the container.  This is the expected behavior for a container. 
   382  
   383  5. In a fresh terminal on your local host, change to the `docker-fork` root.
   384  
   385          $ cd ~/repos/docker-fork/
   386  
   387  6. Create a fresh binary but this time use the `make` command.
   388  
   389          $ make BINDDIR=. binary
   390  
   391      The `BINDDIR` flag is only necessary on Mac OS X but it won't hurt to pass
   392      it on Linux command line. The `make` command, like the `make.sh` script
   393      inside the container, reports its progress. When the make succeeds, it
   394      returns the location of the new binary.
   395  
   396  
   397  7. Back in the terminal running the container, list your `binary` directory.
   398  
   399          root@074626fc4b43:/go/src/github.com/docker/docker# ls bundles/1.5.0-dev/binary
   400          docker	docker-1.5.0-dev  docker-1.5.0-dev.md5	docker-1.5.0-dev.sha256 
   401  
   402      The compiled binaries created from your repository on your local host are
   403      now available inside your running Docker development container.
   404  
   405  8. Repeat the steps you ran in the previous procedure.
   406  
   407      * copy the binary inside the development container using
   408        `cp bundles/1.5.0-dev/binary/docker /usr/bin`
   409      * start `docker -dD` to launch the Docker daemon inside the container
   410      * run `docker ps` on local host to get the development container's name
   411      * connect to your running container `docker exec -it container_name bash`
   412      * use the `docker run hello-world` command to create and run a container 
   413        inside your development container
   414  
   415  ## Where to go next
   416  
   417  Congratulations, you have successfully achieved Docker inception. At this point,
   418  you've set up your development environment and verified almost all the essential
   419  processes you need to contribute. Of course, before you start contributing, 
   420  [you'll need to learn one more piece of the development environment, the test
   421  framework](/project/test-and-docs/).