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