Build image in build step and using it in the next one

See also Build Docker image and re-use in the next step


im using a specific image for testing my python code. and i want ti build a fresh image on every build without uploading it to a registry all the time. so i thought if i build it, tag it, it will be available to the agent. but doesnt seem to be the case. does the agent use a own docker daemon? why it doesnt seem local images?

here is my .drone.yml

kind: pipeline
name: default

steps:

  - name: build test image
    image: docker:latest
    volumes:
      - name: docker_sock
        path: /var/run/docker.sock
    commands:
      - docker build --no-cache -t cookiecutter-python-tests -f Dockerfile.tests .

  - name: py36
    image: cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py36

  - name: py37
    image: cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py37

  - name: flake8
    image: cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e flake8

  - name: pylint
    image: cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e pylint

  - name: black
    image: cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e black-only-check

volumes:
  - name: docker_sock
    host:
      path: /var/run/docker.sock

the building works fine… but the agent cant find the image… i get this error:

Error response from daemon: pull access denied for cookiecutter-python-tests, repository does not exist or may require ā€˜docker login’

1 Like

i forget to say… everything else works. the agent is started with /var/run/docker.sock volume… i just dont know why the image cant be found.

Perhaps drone is trying to pull the image from docker.io by default. Have you tried pushing the image to a docker.io repo and redefining your images to match new image path?

steps:

  - name: build test image
    image: docker:latest
    volumes:
      - name: docker_sock
        path: /var/run/docker.sock
    commands:
      - docker build --no-cache -t ORG/cookiecutter-python-tests -f Dockerfile.tests .
      - docker push ORG/cookiecutter-python-tests:latest

  - name: py36
    image: ORG/cookiecutter-python-tests:latest
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py36
...

i think i found a way that this works… even if i dont know why it does :wink:

kind: pipeline
name: default

steps:

  - name: build test image
    image: docker:latest
    volumes:
      - name: docker_sock
        path: /var/run/docker.sock
    commands:
      - docker build --no-cache -t cookiecutter-python-tests:${DRONE_COMMIT} -f Dockerfile.tests .

  - name: py36
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py36

i set a own tag aka the DRONE_COMMIT hash. and then it works. no idea why its like this.

It works because you are mounting the docker socket, thus the image is already present locally.

@Raffo
Perhaps I’ve missed something, but it seems to me that @xsteadfastx posted two versions, both mounted the socket. The working version used an env var (DRONE_COMMIT) to tag the image. As he said, that seems to be the reason it suddenly works.

Does drone allow steps to be executed on different agents?

I’m unsure why it works actually, the ā€œlatestā€ tag should also work as it’s no different from the other tag.

it doesnt work with latest. i posted two version. i shortened it… here is the full one:

kind: pipeline
name: default

steps:

  - name: build test image
    image: docker:latest
    volumes:
      - name: docker_sock
        path: /var/run/docker.sock
    commands:
      - docker build --no-cache -t cookiecutter-python-tests:${DRONE_COMMIT} -f Dockerfile.tests .

  - name: py36
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py36

  - name: py37
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py37

  - name: flake8
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e flake8

  - name: pylint
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e pylint

  - name: black
    image: cookiecutter-python-tests:${DRONE_COMMIT}
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e black-only-check

volumes:
  - name: docker_sock
    host:
      path: /var/run/docker.sock

and the whole difference was the docker image tag. with latest i dont get it working.

this is because drone behaves the same way as kubernetes, and will always try to pull the latest tag from the registry. In your case, this results in your cached latest tag being replaced with the image from the remote registry. If you do not desire this behavior, you can override the default pull behavior like this:

  - name: py36
    image: cookiecutter-python-tests:latest
+   pull: if-not-exists
    environment:
      TOX_WORK_DIR: /tmp/tox
    commands:
      - tox -e py36

See also Build Docker image and re-use in the next step

3 Likes

this is great. thanks for the answer. that explains it well.