All local gogs + drone: subnet issues, cannot fetch

Hello,

Trying to set up a local configuration of Gogs and Drone, I am finding it difficult to make Drone fetch and clone Gogs repos during the default build procedure. I’d like to underline that all local means that the host is expected to be running without any external net connection; it will be an ‘isolated’ box with all the required docker images downloaded already. However, at now, it is connected, so that I can try different approaches.

I believe that this use case is slightly different from 281:

The main difference being that I do not have any explicit DNS services. I am not playing any tricks neither, but I do rely on local names and docker networking resources.


At this initial point, I don’t mind about security (if you have physical access, you own the machine). I want just a minimal proof of concept. So, following [1] and [2], this is the docker-compose.yml I am using to bootstrap the services (where DRONE_HOST=drone-server:8000):

[1] readme.drone.io/admin/installation-guide
[2] readme.drone.io/admin/setup-gogs

version: '2'

services:
  gogs:
    image: gogs/gogs:latest
    ports:
      - "127.0.0.1:3000:3000"
      - "127.0.0.1:10022:22"
    volumes: [ ./data:/data ]

  drone-server:
    depends_on: [ gogs ]
    image: drone/drone:latest
    restart: always
    ports: [ "127.0.0.1:80:8000" ]
    volumes: [ ./drone:/var/lib/drone ]
    environment:
      - DRONE_OPEN=false
      - DRONE_HOST=${DRONE_HOST}
      - DRONE_GOGS=true
      - DRONE_GOGS_URL=http://gogs:3000
      - DRONE_SECRET=${DRONE_SECRET}

  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}

Note that drone-server depends on gogs in order to have IPs assigned in a known order.

This is the directory structure:

  • tmpci/
    • data/
    • docker/
    • docker-compose.yml

After launching, docker-compose up I check the following info through portainer:

Containers
State		Name			Image 			IP Address 	Published ports
running 	tmpci_drone-agent_1	drone/drone:latest 	172.18.0.4 	-
running 	tmpci_drone-server_1 	drone/drone:latest 	172.18.0.3 	80:8000
running 	tmpci_gogs_1 		gogs/gogs:latest 	172.18.0.2 	10022:22 3000:3000
running 	portainer 		portainer/portainer 	172.17.0.2 	9000:9000
Networks
Name 		Id 		Scope 	Driver 	IPAM Driver 	IPAM Subnet 	IPAM Gateway
none 		8a0cf... 	local 	null 	default 	- 		-
host 		ad840... 	local 	host 	default 	- 		-
bridge 		14de5... 	local 	bridge 	default 	172.17.0.0/16 	172.17.0.1
tmpci_default	b5fc7... 	local 	bridge 	default 	172.18.0.0/16 	172.18.0.1

Then, I can reach Gogs from a browser running on the host, through either localhost:3000 or 172.18.0.2:3000. Since this is the first run, I configure it. The configuration file is saved to data/gogs/conf/app.ini:

APP_NAME = Gogs
RUN_USER = git
RUN_MODE = prod

[database]
DB_TYPE  = sqlite3
HOST     = 127.0.0.1:3306
NAME     = gogs
USER     = root
PASSWD   =
SSL_MODE = disable
PATH     = data/gogs.db

[repository]
ROOT = /data/git/gogs-repos

[server]
DOMAIN           = localhost
HTTP_PORT        = 3000
ROOT_URL         = http://172.18.0.2:3000
DISABLE_SSH      = false
SSH_PORT         = 22
START_SSH_SERVER = false
OFFLINE_MODE     = false

[mailer]
ENABLED = false

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL     = false
DISABLE_REGISTRATION   = true
ENABLE_CAPTCHA         = false
REQUIRE_SIGNIN_VIEW    = false

[picture]
DISABLE_GRAVATAR        = true
ENABLE_FEDERATED_AVATAR = false

[session]
PROVIDER = file

[log]
MODE      = file
LEVEL     = Info
ROOT_PATH = /app/gogs/log

[security]
INSTALL_LOCK = true
SECRET_KEY   = <secret>

Now, I create a repo through the Gogs frontend, which I can clone in the host with either https://localhost:3000/<user>/<repo>.git or https://localhost:3000/<user>/<repo>.git.

Then I log in to the Drone frontend through http://localhost (with the same user and password created in Gogs), I check that the repo is shown in the list, and I activate it. This results in a webhook with the following payload URL being created in the Gogs repo: http://drone-server:8000/hook?access_token=eyJhb.... When the hook is triggered, it works as expected.

This is the request:

Headers
Request URL: http://drone-server:8000/hook?access_token=eyJhb...
Request method: POST
Content-Type: application/json
X-Gogs-Delivery: eae5a...
X-Gogs-Event: push
X-Gogs-Signature: 11c24...

Payload
{
  "ref": "refs/heads/master", "before": "b1c3e...", "after": "6ae1c...",
  "compare_url": "http://172.18.0.2:3000/<user>/<repo>/compare/b1c3e......6ae1c...",
  "commits": [ {
      "id": "6ae1c...",
      "message": "Add netwworks to .drone.yml\n",
      "url": "http://172.18.0.2:3000/<user>/<repo>/commit/6ae1c...",
      "author": { "name": "<author>", "email": "<author>@users.noreply.github.com", "username": "" },
      "committer": { "name": "<committer>", "email": "<committer>@users.noreply.github.com", "username": "" },
      "added": [], "removed": [],
      "modified": [ ".drone.yml", "hello.py" ],
      "timestamp": "2017-05-25T00:08:58Z"
  } ],
  "repository": {
    "id": 8,
    "owner": { "id": 1, "login": "<user>", "full_name": "", "email": "<email>", "avatar_url": "http://172.18.0.2:3000/avatars/1", "username": "<user>" },
    "name": "<repo>", "full_name": "<user>/<repo>", "description": "", "private": false, "fork": false, "mirror": false,
    "html_url": "http://172.18.0.2:3000/<user>/<repo>",
    "ssh_url": "git@localhost:<user>/<repo>.git",
    "clone_url": "http://172.18.0.2:3000/<user>/<repo>.git",
    "website": "", "stars_count": 0, "forks_count": 0, "watchers_count": 1, "open_issues_count": 0, "default_branch": "master",
    "created_at": "2017-05-24T15:00:44Z", "updated_at": "2017-05-24T15:01:35Z"
  },
  "pusher": { "id": 1, "login": "<user>", "full_name": "", "email": "<email>", "avatar_url": "http://172.18.0.2:300/avatars/1", "username": "<user>" },
  "sender": { "id": 1, "login": "<user>", "full_name": "", "email": "<email>", "avatar_url": "http://172.18.0.2:3000/avatars/1", "username": "<user>" }
}

And the response:

Headers
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate, value
Content-Length: 672
Content-Type: application/json; charset=utf-8
Date: Thu, 25 May 2017 00:10:22 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Last-Modified: Thu, 25 May 2017 00:10:22 GMT
X-Content-Type-Options: nosniff
X-Drone-Version: 0.6.0+build.1103
X-Frame-Options: DENY
X-Xss-Protection: 1; mode=block

Body
{"id":13,"number":4,"parent":0,"event":"push","status":"pending","error":"","enqueued_at":1495671022,"created_at":1495671022,"started_at":0,"finished_at":0,"deploy_to":"","commit":"6ae1c...","branch":"master","ref":"refs/heads/master","refspec":"","remote":"","title":"","message":"Add netwworks to .drone.yml\n","timestamp":1495671022,"sender":"<user>","author":"<user>","author_avatar":"http://172.18.0.2:3000/avatars/1","author_email":"","link_url":"http://172.18.0.2:3000/<user>/<repo>/compare/b1c3e......6ae1c...","signed":false,"verified":true,"reviewed_by":"","reviewed_at":0}

As a result, the build is properly triggered. However, the build container is unable to access the gogs service. This is the build log:

+ git init
Initialized empty Git repository in /drone/src/172.18.0.2:3000/<user>/<repo>/compare/6ae1c32c765f5467f4068f6d1922cea35af19411...a30be5fbd153bec305e95f305a65fcaf8f35dce6/.git/
+ git remote add origin http://172.18.0.2:3000/<user>/<repo>.git
+ git fetch --no-tags origin +refs/heads/master:
fatal: unable to access 'http://172.18.0.2:3000/<user>/<repo>.git/': Failed to connect to 172.18.0.2 port 3000: Operation timed out
exit status 128

I tried changing ROOT_URL=http://172.18.0.2:3000 to ROOT_URL=http://gogs:3000 in the Gogs configuration, i.e., removed everything and started again with that modification. But I get the same result.

This is the .drone.yml file in the repo that is being built:

pipeline:
  build:
    image: python
    commands:
      - python hello.py

networks:
  default:
    driver: bridge

While the build is running, portainer shows that a new subnet is created and the build container is connected to it:

running 	0_349414548106078995_clone 	plugins/git:latest 	172.19.0.2 	-
0_2058417003406259118_default 	a940b... 	local 	bridge 	default 	172.19.0.0/16 	172.19.0.1

As a possible solution, according to [#1268], I tried replacing the networks part with:

[#1268] github.com/drone/drone/issues/1268

networks:
  tmpci_default:
    driver: bridge

The result is still the same.

For completeness, this is the info of the host:

Version 	17.05.0-ce
API version 	1.29
Go version 	go1.8.1
OS type 	linux
OS 		Arch Linux
Architecture 	amd64
Kernel version 	4.11.2-1-ARCH

Note that, compared to latest replies to 281, I am not relying on hostname resolution for the git fetch step. I’d like to do so, and I have tried it, but I think it won’t work if hardcoding the IP is not working.

I’d be very grateful if anyone with some experience could spot any evident configuration error I might have commited. At the same time, I’d like to know if it is possible to deploy such a set up, in which no reverse proxy is involved. Then, should I read more about networking or is this a possible bug related to this tip?

[quote=“JaredReisinger, post:16, topic:281, full:true”]In the inspect details, the “drone_default” shows:

{"IPAM": { "Options": null }}

… but “foo” has:

{"IPAM": { "Options": {} }}

[/quote]

Suggested by @bradrydzewski, I added DRONE_NETWORK=tmpci_default to the drone-server: environment: part of the docker-compose.yml file. The proof of concept is working seamlessly now.

For completeness, the following configuration uses two subnets: NET_CI (for drone-server, drone-agent and gogs) and NET_BUILD (for gogs and build containers):

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:latest
    restart: always
    ports: [ "127.0.0.1:80:8000" ]
    volumes: [ "./data_drone:/var/lib/drone" ]
    environment:
      - DRONE_OPEN=true
      - DRONE_HOST=${DRONE_HOST}
      - 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}
APP_NAME = app-gogs
RUN_USER = git
RUN_MODE = prod

[database]
DB_TYPE  = sqlite3
HOST     = 127.0.0.1:3306
NAME     = gogs
USER     = root
PASSWD   =
SSL_MODE = disable
PATH     = data/gogs.db

[repository]
ROOT = /data/git/gogs-repositories

[server]
DOMAIN           = http://gogs-srv:3000
HTTP_PORT        = 3000
ROOT_URL         = http://gogs-srv:3000/
DISABLE_SSH      = false
SSH_PORT         = 22
START_SSH_SERVER = false
OFFLINE_MODE     = false

[mailer]
ENABLED = false

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL     = false
DISABLE_REGISTRATION   = true
ENABLE_CAPTCHA         = false
REQUIRE_SIGNIN_VIEW    = false

[picture]
DISABLE_GRAVATAR        = true
ENABLE_FEDERATED_AVATAR = false

[session]
PROVIDER = file

[log]
MODE      = file
LEVEL     = Info
ROOT_PATH = /app/gogs/log

[security]
INSTALL_LOCK = true
SECRET_KEY   = <secret>

This is the start procedure:

# docker network create ${NET_CI}
# docker network create ${NET_BUILD}
# docker-compose up
# docker network connect ${NET_BUILD} gogs-srv

An this the cleaning procedure:

# docker-compose rm
# docker network prune