When using the docker-compose.yml
file shown below, Gogs is reachable at localhost:3000
on the host, and Drone at localhost:8000
. As a result, when a repo is activated, the payload URL in the webhook is set to http://localhost:8000/hook?access_token=eyJhb...
. Then, webhook requests are not properly processed. It can be manually modified to http://localhost:8000/hook?access_token=eyJhb...
, but this is not an elegant solution.
I checked the sources of Drone, and I saw that the payload URL is defined in drone/server/repo.go#L76-L80:
link := fmt.Sprintf(
"%s/hook?access_token=%s",
httputil.GetURL(c.Request),
sig,
)
Multiple parts of the http.Request
are evaluated to set the URL. At drone/shared/httputil/httputil.go#L50-L67:
func GetHost(r *http.Request) string {
switch {
case len(r.Host) != 0:
return r.Host
case len(r.URL.Host) != 0:
return r.URL.Host
case len(r.Header.Get("X-Forwarded-For")) != 0:
return r.Header.Get("X-Forwarded-For")
case len(r.Header.Get("X-Host")) != 0:
return r.Header.Get("X-Host")
case len(r.Header.Get("XFF")) != 0:
return r.Header.Get("XFF")
case len(r.Header.Get("X-Real-IP")) != 0:
return r.Header.Get("X-Real-IP")
default:
return "localhost:8080"
}
}
Note that, in the use case below, the first case statement is enough: r.Host
. Nevertheless, none of the cases above checks DRONE_HOST
. In a use case without any reverse proxy, nor DNS server besides the embedded one in Docker, I think that DRONE_HOST
is the only way to properly set the payload URL. This should contain a hostname which is reachable from the gogs container, instead of the route used by the host (which is where the request for activation is generated).
According to the configuration below, this modification to drone/server/repo.go#L76-L80 solves the problem:
link := fmt.Sprintf(
"%s/hook?access_token=%s",
Config.Server.Host,
sig,
)
However, this modification involves getting rid of httputil.GetURL(c.Request)
, and I am sure that other use cases will break. Then, I’d like to ask for opinion before opening a PR. Which is the recommended procedure to decide when to process the request and when to use the variable?
docker-compose.yml
:
version: '2'
services:
gogs:
container_name: gogs-srv
image: gogs/gogs:latest
ports: [ "127.0.0.1:3000:3000" ]
volumes: [ "./data_gogs:/data" ]
drone-server:
depends_on: [ gogs ]
image: drone/drone:elide
restart: always
ports: [ "127.0.0.1:8000:8000" ]
volumes: [ "./data_drone:/var/lib/drone" ]
environment:
- DRONE_OPEN=true
- DRONE_HOST=http://drone-server:8000
- DRONE_GOGS=true
- DRONE_GOGS_URL=http://gogs:3000
- DRONE_SECRET=${DRONE_SECRET}
- DRONE_NETWORK=net_build
drone-agent:
depends_on: [ drone-server ]
image: drone/drone:latest
command: agent
restart: always
volumes: [ "/var/run/docker.sock:/var/run/docker.sock" ]
environment:
- DRONE_SERVER=ws://drone-server:8000/ws/broker
- DRONE_SECRET=${DRONE_SECRET}
networks:
default:
external:
name: net_ci
Start procedure (script):
$ docker network create net_ci
$ docker network create net_build
$ docker-compose up
$ docker network connect net_build elide-gogs
Cleanup proceduce (script):
docker-compose rm
docker network prune
A side question:
In order to test the modification I compiled drone with go install github.com/drone/drone/drone
. Then, I built a new image with drone/master/Dockerfie, but it wouldn’t work: drone-server_1 | standard_init_linux.go:178: exec user process caused "no such file or directory"
. I had to change FROM centurylink/ca-certs
to FROM golang
. Is this correct?