Drone CI isn’t just a CI/CD tool; it’s a Git-native pipeline that treats your .drone.yml file as a first-class citizen, deeply integrated with your version control system.

Let’s see it in action. Imagine you have a simple Dockerfile in your repository:

FROM alpine:latest
RUN apk add --no-cache nodejs npm
COPY . /app
WORKDIR /app
CMD ["npm", "start"]

And a basic package.json:

{
  "name": "my-node-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "echo 'Hello from Node!'"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Now, your .drone.yml to build and push this to Docker Hub might look like this:

kind: pipeline
type: docker
name: default

steps:
  - name: build-and-push
    image: plugins/docker
    settings:
      repo: your-dockerhub-username/my-node-app
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:7}
      dockerfile: Dockerfile
    when:
      branch: main

When you push a commit to the main branch, Drone will automatically pick up this .drone.yml. It clones your repository, executes the plugins/docker step, which by default uses the Docker daemon available to the Drone runner. This plugin handles the docker build command using the specified dockerfile. The repo setting tells it where to push, and tags specifies latest and the short commit SHA for versioning. For this to work, Drone needs to be configured with your Docker Hub credentials (usually via environment variables DOCKER_USERNAME and DOCKER_PASSWORD or DOCKER_TOKEN).

The core problem Drone solves is making CI/CD configuration as easy to manage as your application code. Instead of a separate UI for pipeline definitions, your .drone.yml lives alongside your Dockerfile and application code in Git. This means versioning, branching, and pull requests apply to your pipeline configuration as well. The kind: pipeline and type: docker at the top define the fundamental nature of the pipeline: it’s a Docker-based execution environment. The steps array lists sequential or parallel tasks. Here, we have a single step named build-and-push that utilizes the official plugins/docker image. This plugin is a specialized Docker image that contains the logic to perform Docker operations.

The settings block within a step is where you configure the plugin. For plugins/docker, repo is mandatory, specifying the target image repository. tags allows multiple tags, and Drone injects environment variables like ${DRONE_COMMIT_SHA} which are incredibly useful for immutable build artifacts. The dockerfile setting points to the specific Dockerfile to use if it’s not named Dockerfile or is in a subdirectory. The when clause controls under which conditions a step or pipeline should run; here, it’s restricted to the main branch. This ensures that only production-ready code gets built and pushed.

A common point of confusion is how the Docker daemon is accessed. In a self-hosted Drone setup, the runner typically has direct access to a Docker daemon (e.g., via /var/run/docker.sock if running the runner in Docker itself). For managed Drone services, the underlying infrastructure provides the necessary Docker environment. The plugins/docker image is designed to abstract away the direct Docker CLI commands, making your .drone.yml cleaner and more declarative. It handles authentication, building, tagging, and pushing in a single, robust step.

When you configure the plugins/docker with a repo like my-dockerhub-user/my-app and push, the plugin will execute docker build -t my-dockerhub-user/my-app:latest -t my-dockerhub-user/my-app:abcdef1 Dockerfile . followed by docker push my-dockerhub-user/my-app:latest and docker push my-dockerhub-user/my-app:abcdef1. The . at the end of the docker build command is the build context, which defaults to the repository root.

What many users overlook is the build setting within the plugins/docker settings. If your Dockerfile isn’t in the repository root, or you need to specify a different build context, you’d use build: ./path/to/your/dockerfiles. This tells the plugin where to find the Dockerfile and what directory to use as the build context.

The next step after successfully pushing your Docker image is often deploying it to a container orchestration platform.

Want structured learning?

Take the full Drone course →