Drone + Gitea over docker compose: OAuth cannot exchange code

Hi,

I want to deploy a gitea + drone environment using docker-compose (in a first step for an local develop and test environment). Therefore I’ve created the following docker-compose.yaml:

version: '3'

services:
  postgres:
    container_name: postgres-gitea
    image: postgres:13
    environment:
      POSTGRES_DB: gitea-db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    networks:
      - cicdnet
    restart: always

  gitea:
    container_name: gitea
    image: gitea/gitea:1.15
    environment:
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=postgres:5432
      - GITEA__database__NAME=gitea-db
      - GITEA__database__USER=postgres
      - GITEA__database__PASSWD=password
    ports:
      - "22:22"
      - "3000:3000"
    networks:
      - cicdnet
    depends_on:
      - postgres
    restart: always

  drone-server:
    container_name: drone-server
    image: drone/drone:2.4
    ports:
      - 80:80
      - 443:443
      - 8000:8000
    environment:
      - DRONE_GITEA_SERVER=http://localhost:3000
      - DRONE_RPC_SECRET=very-secret
      - DRONE_SERVER_PROTO=http
      - DRONE_SERVER_HOST=localhost:80
      - DRONE_GITEA_CLIENT_ID=xxx #from Gitea OAuth Client-ID
      - DRONE_GITEA_CLIENT_SECRET=xxx #from Gitea OAuth Client-Secret
      - DRONE_GITEA_SKIP_VERIFY=true
    networks:
      - cicdnet
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./drone:/var/lib/drone
    depends_on:
      - gitea
    restart: always

  drone-runner:
    container_name: drone-runner
    image: drone/drone-runner-docker:1.7
    ports:
      - "3001:3000"
    environment:
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone-server:80
      - DRONE_RPC_SECRET=very-secret
      - DRONE_RUNNER_NAME=drone-runner
    networks:
      - cicdnet
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - gitea
    restart: always

networks:
  cicdnet:

For configuring the OAuth application, I first start the postgres and gitea containers:
docker-compose up postgres-gitea gitea

Then I create my admin user and go to settings - applications, where I create a new OAuth application with the following values:

After that I take Client-ID and Client-Secret from Gitea and fill it into the docker-compose.yaml. Now the rest of the containers can be started:
docker-compose up drone-server drone-runner

Now I should be able to go to localhost:3000 and authorize drone to gitea, but after clicking the authorize-button and the redirect happens, I get the following error message in the Drone UI:
Post "http://localhost:80/login/oauth/access_token": dial tcp 127.0.0.1:80: connect: connection refused

And the log error message states:
oauth: cannot exchange code: xxx: Post \"http://localhost:80/login/oauth/access_token\": dial tcp 127.0.0.1:80: connect: connection refused

I have already tried using Gitea version 1.8.1 instead, but the same issue happens. Volumes for gitea and postgres have no impact on the result. I have also already tried it with different ports. Using network_mode: host I was able to authorize Drone to Gitea with OAuth, but I don’t want the docker containers to run on my host.

What am I missing here?

1 Like

I can’t really analyze the problem because there are details missing and I can’t reproduce your setup on my laptop. However there is one thing that is most certainly a problem: localhost/127.0.0.1 is local to the container/host and since the containers run on their own network this is bound to create communication problems. You would probably have better luck specifying the actual IP of the target container, which you can obtain with something like:

docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" nameofcontainer

Thanks for the advice. This hint got me an idea about what could be the problem. Indeed, it was a network problem. The OAuth authentication is done in the webbrowser, while docker uses its own network.

To fix this, I gave every container a static IP and changed the rest of the file accordingly. Now I was able to use the IP of the drone server for the OAuth application and the redirect worked accordingly.

This probably isn’t the perfect solution, because static IP addresses aren’t ideal. For development it should be fine, but later on I will probably use a DNS.

Here is my current docker-compose.yml:

version: '3'

services:
  postgres:
    container_name: postgres-gitea
    image: postgres:13
    environment:
      POSTGRES_DB: gitea-db
      POSTGRES_USER: <db-user>
      POSTGRES_PASSWORD: <db-password>
    ports:
      - "5432:5432"
    networks:
      cicdnet:
        ipv4_address: 172.22.0.2 # static address
    volumes:
      - ./volumes/postgres:/var/lib/postgresql/data
    restart: always

  gitea:
    container_name: gitea
    image: gitea/gitea:1.15
    environment:
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=postgres:5432
      - GITEA__database__NAME=gitea-db
      - GITEA__database__USER=<db-user>
      - GITEA__database__PASSWD=<db-passwort>
      - HTTP_PORT=11080
      - ROOT_URL=http://172.22.0.3:11080/
#      - LOCAL_ROOT_URL=http://172.22.0.3:11080/
    ports:
      - "11022:22"
#      - "11080:3000"
      - "11080:11080"
    networks:
      cicdnet:
        ipv4_address: 172.22.0.3
    volumes:
      - ./volumes/gitea:/data
    depends_on:
      - postgres
    restart: always

  drone-server:
    container_name: drone-server
    image: drone/drone:2.4
    ports:
      - 12080:80
      - 12443:443
      - 8000:8000
    environment:
      - DRONE_GITEA_SERVER=http://172.22.0.3:11080
      - DRONE_RPC_SECRET=very-secret
      - DRONE_SERVER_PROTO=http
      - DRONE_SERVER_HOST=172.22.0.4:80
      - DRONE_GITEA_CLIENT_ID=8a2aaf74-f2f1-45bf-b70b-51e456c936be
      - DRONE_GITEA_CLIENT_SECRET=JfWTfZ9zJIhY4sFbsfqYtq4SFdVWVW3AKWMuQeII4fxc
      - DRONE_GITEA_SKIP_VERIFY=true
      - DRONE_COOKIE_SECRET=super-secret
    networks:
      cicdnet:
        ipv4_address: 172.22.0.4
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./volumes/drone2:/var/lib/drone
    depends_on:
      - gitea
    restart: always

  drone-runner:
    container_name: drone-runner
    image: drone/drone-runner-docker:1.7
    ports:
      - "3000:3000"
    environment: # 2 instances by default
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=172.22.0.4:80
      - DRONE_RPC_SECRET=very-secret
      - DRONE_RUNNER_NAME=drone-runner
      - DRONE_RUNNER_NETWORKS=docker-compose_cicdnet
    networks:
      cicdnet:
        ipv4_address: 172.22.0.5
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - gitea
    restart: always

networks:
  cicdnet:
    ipam:
      config:
        - subnet: 172.22.0.0/24

Another problem I encountered was that when the drone pipeline was starting, it could not connect to the Gitea repository to pull. This was a network problem of the drone runner. To fix this, I put DRONE_RUNNER_NETWORKS=docker-compose_cicdnet as a environment variable of the drone runner. I figured out the network name by using the command ‘docker network ls’.

I hope this might help others :slight_smile: