8

I'm running my own Drone instance in AWS and I want it to build a docker image and push it to my repo. Drone runs its build environment in a docker container, so I basically want to build docker images from inside a docker container. I found this and saw you can Bind Mount the docker socket. How do I do this with Drone?

docker run -it -v /var/run/docker.sock:/var/run/docker.sock mycompany/buildimage

So I can run docker build from inside my container. Or do you know of another CI tool that I can run my custom script and build docker images.

hichris123
  • 9,735
  • 15
  • 51
  • 66
Bernie Perez
  • 12,073
  • 13
  • 41
  • 54

3 Answers3

19

Note that this answer applies to drone version 0.5

You can use the Docker plugin to build and publish a Docker image as a step in your build pipeline. In the example .drone.yml file below I've added a publish step that uses the docker plugin. Note that you will need to replace foo/bar with the name of the DockerHub repository you intend to publish to.

pipeline:
  build:
    image: golang
    commands:
      - go build
      - go test
  publish:
    image: plugins/docker
    repo: foo/bar

In many cases you will want to limit execution of the this step to certain branches. This can be done by adding runtime conditions:

  publish:
    image: plugins/docker
    repo: foo/bar
    when:
      branch: master

You will need to provide drone with credentials to your Docker registry in order for drone to publish. These credentials can be declared directly in the yaml file, although storing these values in plain text in the yaml is generally not recommended:

  publish:
    image: plugins/docker
    repo: foo/bar
    username: johnsmith
    password: pa55word
    when:
      branch: master

You can alternatively provide your credentials using the built-in secret store. Secrets can be added to the secret store on a per-repository basis using the Drone command line utility:

  export DRONE_SERVER=http://drone.server.address.com
  export DRONE_TOKEN=...

  drone secret add --image plugins/docker \
    octocat/hello-world DOCKER_USERNAME johnsmith

  drone secret add --image plugins/docker \
    octocat/hello-world DOCKER_PASSWORD pa55word

In the above example the --image flag is used to limit which secrets we expose our Docker credentials to, which we set to the docker plugin. The octocat/hello-world parameter represents your GitHub repository name and should be replaced with the correct value.

Mouting Voumes (alternate approach)

You also asked if it were possible to mount the Docker socket into your build environment. This is possible, but will require some additional permissions (mark your build as trusted in the UI)

pipeline:
  build:
    image: docker
    commands:
      - docker build ...
      - docker run ...
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

The only issue with this approach is if your build fails you may not be able to cleanup images or containers that were created during your build.

In addition you should not use this approach if your repository is public and accepts pull requests. Exposing your host machine Docker socket to your build environment could be exploited by malicious pull requests, allowing access to your host machine.

shgnInc
  • 1,591
  • 1
  • 17
  • 31
Brad Rydzewski
  • 2,393
  • 12
  • 16
  • 1
    How do I pull images for pipeline steps from AWS ECR? I am successfully using the the ECR plugins to build and push images but I would like to use customer containers published to ECR as the image in the build pipeline. – Nicholas Martinez Apr 19 '20 at 00:21
7

I wrote an article with steps to get Drone to output a Docker container, and I also address some of the common problems.

Keep in mind that Drone's build environment is itself a Docker container, which means you'll be in a Docker-in-Docker situation: out of the box, Docker doesn't run correctly inside a Docker container. The accepted solution is to use the wrapdocker script to start the inner Docker instance. My final setup looks like:

Docker in Drone

For Drone, you'd add something like the following to your build environment's Dockerfile:

# install docker
RUN apt-get install -y apparmor  
RUN curl -s https://get.docker.io/ubuntu/ | sudo sh  
ADD wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/wrapdocker

This assumes the wrapdocker script is available locally. Alternately, you could grab wrapdocker from github directly. Then, given a .drone.yml file like:

image: http://my-docker-registry/my-docker-image:version  
script:  
  - ./.drone/build.sh

your build.sh would look like:

#!/bin/bash
set -e  
cd /var/cache/drone/src/path/to/app

# [pass tests here]

wrapdocker &  
sleep 5

docker build -t docker-registry/image-name .  
docker push docker-registry/image-name

This is only one way to do it. The only constraint is that wrapdocker is used to start the Docker daemon within the build container.

Rustavore
  • 1,710
  • 1
  • 20
  • 30
calebds
  • 23,502
  • 7
  • 39
  • 73
  • 1
    Oh, I found dind, but it was still a little flakey. Maybe b/c I didn't have the 'sleep 5' in my script... but I've moved on. Also, you'll need to set your project to have --privileged flag. So I wanted to do Docker-ey things inside Drone's container but I don’t want to go full Docker in Docker (dind) and run in --privileged mode... never go full Docker in Docker :) This is a good article though, very clear, just not the way I went in the end. I'll upvote it and see if people like it. Thanks! – Bernie Perez Sep 05 '14 at 23:13
  • @BerniePerez sure thing. Why never full Docker in Docker? – calebds Sep 06 '14 at 19:05
1

The answer is outdated, please check @Brad's solution below, use this as reference only

In your mycompany/buildimage

Install docker client

curl https://get.docker.io/builds/Linux/x86_64/docker-latest -o /usr/local/bin/docker
chmod +x /usr/local/bin/docker 

Then you can run docker build command use docker host environment

$ docker -H unix:///var/run/docker.sock build .

To make it easy and transparent, usually DOCKER_HOST environment can be set.

$ export DOCKER_HOST="unix:///var/run/docker.sock"
$ docker build .

Not familar with the drone installation, but this is the way docker provides

Larry Cai
  • 45,222
  • 30
  • 104
  • 141
  • Trying it out today. Looks like the 'docker build' works running docker run mycompany/buildimage docker build . but docker run mycompany/buildimage docker images wasn't working.. hmm.... – Bernie Perez Jul 25 '14 at 17:22
  • can you describe more clear what is working and work is not working ? – Larry Cai Jul 28 '14 at 00:39
  • I ended up dumping Drone and building my own CI tool. It listens to githooks and pulls the repo and builds the images with Drone. I'm doing what you suggested which is to just install Docker on my own and not try and use Drone's version. I'm using this chef recipe for my Docker installation. https://github.com/bflad/chef-docker Thanks for the help! – Bernie Perez Aug 04 '14 at 18:13
  • Hey @LarryCai, I've tried your example and it yields `no permission to read from 'proc/sys/net/ipv4/route/flush'` even while running in `--privileged` mode – Pablo Fernandez Jul 23 '15 at 23:52
  • 1
    the reason this example doesn't work is that drone runs your build inside docker containers. This would therefore run Docker in Docker which is possible, but requires elevated privileges and may not work on certain Linux kernels or distributions (RedHat with DeviceMapper, for example). There is a native drone solution for building and publishing images, using the docker plugin. – Brad Rydzewski Aug 21 '16 at 00:52
  • good, I marked this in my answer (it was answered 2 years ago without extra support in drone) – Larry Cai Aug 23 '16 at 06:13
  • i think it goes without saying that DIND is not a good idea in production on a publicly accessible machine. it introduces a lot of security issues. there is some work around rootless containers that could potentially enable image building inside a container. Jessie Frazelle wrote a blogpost that can be found here https://blog.jessfraz.com/post/building-container-images-securely-on-kubernetes/. Although, for what i understand it requires a lot of patching that's not in master yet. Work's ongoing. – Victor Palade Aug 20 '18 at 11:08