Pass environment variables to pipeline

I’d like to copy some files from my code to my host.

Here is the docker-compose.yml that runs my drone instances (from the doc):

version: '3.5'

services:
  drone-server:
    image: drone/drone:0.8
    ports:
      - ${DRONE_AGENT_SERVER_PORT}:9000
    volumes:
      - ${DRONE_DATA_DIR}:/var/lib/drone/
    restart: always
    environment:
      - DRONE_OPEN=${DRONE_OPEN}
      - DRONE_ORGS=${DRONE_ORGS}
      - DRONE_ADMIN=${DRONE_ADMIN}
      - DRONE_HOST=${DRONE_HOST}
      - DRONE_BITBUCKET=true
      - DRONE_BITBUCKET_CLIENT=${DRONE_BITBUCKET_CLIENT}
      - DRONE_BITBUCKET_SECRET=${DRONE_BITBUCKET_SECRET}
      - DRONE_SECRET=${DRONE_SECRET}
      - DOC_DIR=${DOC_DIR}

  drone-agent:
    image: drone/agent:0.8
    command: agent
    restart: always
    environment:
      - DOC_DIR=${DOC_DIR}
    depends_on:
      - drone-server
    volumes:
      - ${DOCKER_HOST_SOCKET}:/var/run/docker.sock
    environment:
      - DRONE_SERVER=drone-server:${DRONE_AGENT_SERVER_PORT}
      - DRONE_SECRET=${DRONE_SECRET}

And here is my pipeline:

pipeline:

  copydoc:
    image: alpine:latest
    commands:
      - echo $DOC_DIR
      - echo ${DOC_DIR}
      - cp ./documentation/* -R /hostdocs/
    volumes:
      - ${DOC_DIR}:/hostdocs/

As you can see, I would like to copy files to DOC_DIR, which is set in a .env file next to the docker-compose.yml file on my host.

From the test commands in the pipeline, ${DOC_DIR} is not valued.

I tried to put the real host dir in pipeline.volumes, instead of the variable, it works fine.

What am I doing wrong ?

In your example you are passing DOC_DIR to the agent. The problem with your example is that builds do not run in the agent, which means they will not inherit agent environment variables. Builds are run in their own docker containers spawned by the agent on the host machine, using the docker socket that you mount into the agent.

Thank you for your quick reply !

So I understand why the commands

echo $DOC_DIR
echo ${DOC_DIR} 

do not display anything.

But the volumes instructions are interpreted by the agent, right? So in the pipeline

volumes:
      - ${DOC_DIR}:/hostdocs/

should be interpreted, as it is defined in the agent, no ?

But the volumes instructions are interpreted by the agent, right?
should be interpreted, as it is defined in the agent, no ?

Nope, this isn’t quite how things work

  1. The server parses the yaml and interpolates parameters, not the agent
  2. The server interpolates internal variables only. It does not interpolate from the environment. If you want drone to interpolate custom variables it needs to be explicitly configured http://docs.drone.io/configure-global-environment/

Ok, I understand better, thanks for the details.
I tried to configure it, but it did not work. I think it is because of its unavailability on the community edition.

Any plan to put the global environment feature in the open-source version?

I think you can try somthing like “DRONE_RUNNER_ENV_FILE=/proc/1/environ” when you start your agent. This will pass your host’s environment into every step.

This actually doesn’t work because of the format,
while you can do something like

steps:
- name: deploy-promote
  image: dtzar/helm-kubectl
  privileged: true
  volumes:
  - name: hostEnv
    path: /.hostEnv
  commands:
  #  read env varialbes
  - export $(tr '\0' '\n' < /.hostEnv | grep ANY_ENVIRONMENT_VARIABLE)


volumes:
  - name: hostEnv
    host:
      path: "/proc/1/environ"

I am using this trick.

If you need to customize Drone in order to pass additional environment variables to your pipeline, the recommended approach is to create an environment extension. See https://docs.drone.io/extensions/environment/

It sounds like an environment extension (described above) is the best approach if you need something more dynamic and custom, but you can also load global environment variable from a file by providing the runner with an environment file:
https://docs.drone.io/runner/docker/configuration/reference/drone-runner-env-file/