0
votes

My TeamCity server seems to be using a broken URL for its built-in NuGet feed.

enter image description here

I'm running it in a docker container using the official JetBrains image. I'm not behind a reverse proxy. I have configured the "server URL" setting.

I can use the feed in Visual Studio using the full URL (unauthenticated guest access) and it all works great. It's adding packages from build artifacts, Visual Studio can pull them.

It's just that the TeamCity property that is supposed to contain the feed URL is broken, as shown in the screen shot. So my builds are failing like this:

/usr/share/dotnet/sdk/3.1.302/NuGet.targets(128,5): error : Unable to load the service index for source http://teamcity:8111/guestAuth/app/nuget/feed/TigraOss/TigraOSS/v3/index.json.

Those are internally generated and not something I've edited, so I'm a bit confuzzled. Any ideas on how to fix this? (I've tried restarting the server, obviously).

Update

I think this might be due to the fact that everything is running in docker containers. A bit later in the parameters screen (off the bottom of the screen shot above) is another line:

teamcity.serverUrl http://teamcity:8111

I think this is coming from my docker-compose.yml file:

  agent:
    image: jetbrains/teamcity-agent
    container_name: teamcity-agent
    restart: unless-stopped
    privileged: true
    user: "root"
    environment:
      - SERVER_URL=http://teamcity:8111
      - AGENT_NAME=ubuntu-ovh-vps-tigra
      - DOCKER_IN_DOCKER=start
    volumes:
      - agentconfig:/data/teamcity_agent/conf
      - agentwork:/opt/buildagent/work
      - agentsystem:/opt/buildagent/system
      - agent1_volumes:/var/lib/docker

I tried changing the SERVER_URL value in my docker-compose.yml file and restarting the agent container, but it looks like once the agent config file is created, the value is sticky and I need to go in and hand-edit that.

Now I have the agent using the full FQDN of the server, so we'll see if that works.

1
If you look at a previous build and the parameters, does the serverl URL match what you set in settings? Are those values on the right being generated from a plugin?Jeff Gruenbaum
The screen shot was taken from looking at the results of a build and looking in the 'Parameters' tab, so those are the actual results used for the build. A bit further down, there's this line: > teamcity.serverUrl teamcity:8111 Looks like a smoking gun to me. I wonder if this is because the agent is running inside a docker container? 'teamcity' is the name of the server docker service. You might have put me onto something there.Tim Long

1 Answers

1
votes

I think this is caused by my complicated docker-in-docker build. I am running TeamCity server and the linux build agent in docker containers built with docker-compose. Here's my docker-compose.yml file with secrets removed:

version: '3'

services:
  db:
    image: mariadb
    container_name: teamcity-db
    restart: unless-stopped
    env_file: .env
    volumes: 
      - mariadb:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password

  teamcity:
    depends_on: 
      - db
    image: jetbrains/teamcity-server
    container_name: teamcity
    restart: unless-stopped
    environment:
      - TEAMCITY_SERVER_MEM_OPTS="-Xmx750m"
    volumes: 
      - datadir:/data/teamcity_server/datadir
      - logs:/opt/teamcity/logs
    ports:
      - "8111:8111"

  agent:
    image: jetbrains/teamcity-agent
    container_name: teamcity-agent
    restart: unless-stopped
    privileged: true
    user: "root"
    environment:
      SERVER_URL: http://fully.qualified.name:8111
      AGENT_NAME: my-agent-name
      DOCKER_IN_DOCKER: start
    volumes:
      - agentconfig:/data/teamcity_agent/conf
      - agentwork:/opt/buildagent/work
      - agentsystem:/opt/buildagent/system
      - agent1_volumes:/var/lib/docker

volumes:
  mariadb:
  datadir:
  logs:
  agentconfig:
  agentwork:
  agentsystem:
  agent1_volumes:

networks:
  default:

When I first created everything, I had the SERVER_URL variable set to `http://teamcity:8111". This works because Docker maps the host name to the service name, which is also 'teamcity' so that host is resolvable within the docker composition.

The problem comes when doing a build step inside yet another container. I am building .NET Core and the .NET SDK is not installed on the machine, so I have to run the build using the .NET Core SDK container.

The agent passes in the URL of the NuGet feeed, which is pointing to the docker service name, and the build container can't "see" that host name. I'm not sure why not. I tried passing in --network teamcity_default as a command line argument to docker run, but it says that network doesn't exist.

I found two ways to get things to work.

  1. Edit the build step to use the FQDN of the nuget feed, and don't use the teamcity built-in parameter %teamcity.nuget.feed.guestAuth.feed-id.v3%. I don't like this solution much because it sets me up for a breakage in the future.
  2. Find the docker volume where the teamcity agent config is stored. In my case, it was /var/lib/docker/volumes/teamcity_agentconfig/_data. Edit the buildAgent.properties file and set serverUrl=http\://fully.qualified.name\:8111. Then docker-compose restart agent. Then you can safely use %teamcity.nuget.feed.guestAuth.feed-id.v3% in containerized builds.

I haven't tested this, but I think you may be able to avoid all this in the first place by using a fully-qualified server name in the docker-compose.yml file. However you have to do this right from the start, because the moment you run docker-compose up the agent config filesystem is created and becomes permanent.