TeamCity is currently one of the best build servers out there. It works exclusively on-premises and that means it requires it’s own machine to run on. That is great for companies and individuals that want to have full control of their resources and JetBrains has made the installation as easy as possible.

We are going to assume that you’ve already installed TeamCity on your machine and one build agent on a different machine (best practice). If you haven’t yet you can download TeamCity and start working with it immediately since it is free for 3 build agents and 100 build configurations (enough for a medium-sized startup).

If you followed the installation wizard, your TeamCity is now running on a port 80 of the localhost and you’ve created an administrator account.

But since we don’t want our build server running on HTTP, we are going to create a sub-domain and bind a certificate to it. After that, we are going to redirect all traffic to HTTPS.

So, we are going to:

Let’s start.

What is Let’s Encrypt

To quote its website, Let’s Encrypt is a free, automated, and open Certificate Authority. Certificates were and even now are sold by Certificate Authorities. Let’s Encrypt has been founded to stop that practice and to help create more secure and open internet for everyone for free.

If you are not sure if they are secure, take a look at their sponsors’ page and take note of the companies that support them. That should give you a clear picture if you should use Let’s Encrypt.

Recently they’ve announced support for wildcard certificates. That was a major step forward since now you can create a certificate for your domain like this: https://*.your-domain.com which will secure all subdomains on that domain.

We encourage you to use Let’s Encrypt since certificates should not and need not be paid for.

But enough of that, let’s get to the meat of the article.

Creating a Subdomain for the Machine

One of the prerequisites for the creation of the certificate is that you connected a domain/subdomain to the machine TeamCity Server is installed on. The other is that you need to open both port 80 and 443 on the machine to be able to access TeamCity on HTTP and HTTPS respectively.

This step is easy, but you must have a domain and access to the DNS management panel.

Once you do, you just need to create A record pointing to the machine.

For example, you can make a subdomain like this:

TypeNameValueTTL
Atc.your-domain.com55.66.77.188Automatic

That’s it, easy enough, now you can access your TeamCity server by typing http://tc.your-domain.com. But if you try to get to the HTTPS version of it, you won’t be able to. Once you have, it might take up to 48h to propagate, depending on the registrar, so make sure to create it in advance. We are using CloudFlare, where it usually happens really fast.

Now that we prepared our subdomain, let’s make it secure and create a certificate.

Selecting a Let’s Encrypt Client

Since this article is about configuring TeamCity on a Windows machine, we are going to select a client appropriate for that. A useful list of the certification clients can be found on the Let’s Encrypt clients page.

For the purposes of this post, we are going to use Posh-ACME which is a PowerShell module and very easy to use and install. It doesn’t require any file downloads and all the work is done through the PowerShell console.

Another advantage of using Posh-ACME is that it’s not reliant on the existence of IIS or any website like some other clients are.

Now that we’ve decided which client we want to use, let’s see how to create a certificate with it.

Creating a Let’s Encrypt Certificate for Our Subdomain

To begin with, let’s set our PowerShell’s policy to RemoteSigned:

After that we need to install Posh-ACME to be able to start creating certs:

After a few moments, Posh-ACME is installed, and we can proceed to the main event.

To create a new certificate we need to type:

Of course, you need to change site1.example.com with your own domain or subdomain. Also, try not to use [email protected] as a contact email 🙂 We guarantee you won’t get a renewal notice like that.

If you want to create a certificate like this you can, but you’ll get a warning and you’ll need to add a new TXT record as an acme challenge:

posh acme new certificate

As you can see, the warning is about missing DnsPluign.

Configuring the DnsPlugin

Now, what you can do is proceed to add the TXT record to the DNS records of your domain registrar, or you can set the appropriate plugin and let Posh-ACME do that for you automatically. We recommend the second way, because it’s easier and because it’s built-in, so why not utilize it.

There is a list of supported DNS providers that Posh-ACME supports in the current release. It’s doesn’t support every provider out there and thus the manual method for adding challenges as we’ve already seen.

Say for example that we use a CloudFlare provider. We would need to go to the “Usage guide” for CloudFlare and follow the instructions on how to add the DnsPlugin for it.

And it’s basically these two commands:

Once again, change the site1.example.com and the contact email to your own.

As for the CFParams, every provider has its own way to provide them. For Cloudflare, you can find CFAuthKey right at the bottom of the profile page:

cloudflare api key

You’ll be prompted to enter the password to your account to view the key.

Once you get the key, set the CFAuthKey field, and of course, set the CFAuthEmail field to your CloudFlare account email.

Now we can run these two commands and wait for the wizard to finish.

After the process has finished, you can find your certificates by typing:

This command will list the certificate files location. Usually, they are found at C:\Users\<Username>\AppData\Local\Posh-ACME\acme-v02.api.letsencrypt.org

Configuring the TeamCity Server

So, now we have a certificate. But how do we configure TeamCity to use that certificate?

There are two things we have to do.

First, we need to navigate to C:\TeamCity\conf (or any other TeamCity location you’ve selected during installation) and configure web.xml first:

After that, we need to edit server.xml too:

So, we’re adding redirection port to our existing connector, and then creating a new connector for the port 443 which is used for HTTPS.

Make sure to include redirectPort in the Connector for port 80.

In the Certificate element, we need to set the certificateKeyFile, the certificateFile, and the certificateChainFile attributes to the cert.key, cert.cer, and chain.cer files respectively.

The example from the snippet above is just an approximate location of the certificates.

OK, that’s that.

Checking out the Certificate

Now restart the TeamCity server service and try it out!

HTTP traffic should be redirected to the HTTPS, and the HTTPS should show a valid Let’s Encrypt certificate.

That’s it, navigate to your TeamCity domain and check if the certificate has been configured.

You should see something like this:

certificate teamcity

Now, let’s set up automatic certificate renewal so we don’t worry about our certificate expiring in 3 months.

Certificate Renewal

Unfortunately, the certificate renewal process isn’t automatic with Posh-ACME. But it isn’t hard to set it up either.

There are a few commands that you can use to renew your certificate:

With these, you can renew all the certificates on one account or even across accounts. Set-Renewal is useful if you’ve used DnsPlugin while creating a certificate.

Now that you know which commands are used for certificate renewal, you can just make a scheduled task in the Task Scheduler to run a PowerShell script containing this command on a monthly basis to renew them.

Conclusion

That was a short guide on how to set up a secure connection for your own TeamCity server.

The process is simple and straight-forward once you know what needs to be done.

So what we have learned in this article:

  • A bit about Let’s Encrypt
  • How to set up a subdomain for our server
  • How to create a certificate for our subdomain
  • Properly configure TeamCity server to acknowledge that certificate

Hope this article will help you easily deal with this problem the next time you encounter it.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published CI/CD content we encourage you to subscribe to our blog.