How to Set Up CI/CD Pipeline with TeamCity and Kotlin DSL

Manual deploys and slow builds delay releases and consume developers' time. We set up CI/CD pipelines on TeamCity using Kotlin DSL and templates, automating the entire process from build to deploy. Our team delivers the project turnkey—from audit and server installation to documentation and ongoing support—ensuring stable and fast delivery of changes.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1342
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1304
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1047
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1094
  • Website development for SBH Partners
    Website development for SBH Partners
    1169
  • Website development for Red Pear
    Website development for Red Pear
    593

Complete Guide: CI/CD Pipeline with TeamCity and Kotlin DSL

Imagine: a Node.js online store with three environments (dev, staging, production). Each build from scratch, dependencies pulled from npm without cache, tests run sequentially. Deployment took 40 minutes, and rollback meant manually uploading an archive via SSH. After an audit, we configured TeamCity: parallel steps, node_modules caching, automated tests in containers. Build time dropped to 8 minutes — 5x faster. Developers stopped waiting, and releases became daily. This time savings directly lowers TCO and accelerates feature delivery to production. Our team with 10 years of experience will set up CI/CD turnkey: from server installation to documentation. The setup cost starts at $2,000 for a basic pipeline, with potential savings of $4,000 per month in developer time — that's $48,000 per year.

Typical Technical Challenges

N+1 queries in tests — TeamCity collects coverage reports and finds bottlenecks at the CI stage. Dirty environments — each build on a clean Docker agent, conflicts eliminated. Slow builds — parallel steps and dependency caching (npm cache, Maven local) reduce time by up to 70%. For a typical Node.js project, a cached build takes 2–3 minutes instead of 10. Mean time to recovery drops to 15 minutes thanks to automatic rollbacks. A TeamCity CI/CD setup is 2x faster than Jenkins for parallel builds.

Pipeline Setup: Kotlin DSL and Steps

We use Kotlin DSL — configuration as code, versioned in Git and subject to code review. According to JetBrains, Kotlin DSL provides type safety and IDE autocompletion for build configurations. TeamCity supports complex pipelines with parallel steps. Below is a typical pipeline for a Node.js application:

// .teamcity/settings.kts
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.*
import jetbrains.buildServer.configs.kotlin.triggers.*

version = "latest"

project {
    buildType(Build)
    buildType(Test)
    buildType(Deploy)
    buildTypesOrder = arrayListOf(Build, Test, Deploy)
}

object Build : BuildType({
    name = "Build"
    vcs {
        root(DslContext.settingsRoot)
    }
    steps {
        nodeJS {
            shellScript = "npm ci && npm run build"
        }
    }
    artifactRules = "dist/** => dist.zip"
})

object Test : BuildType({
    name = "Test"
    dependencies {
        snapshot(Build) {}
    }
    steps {
        script {
            scriptContent = """
                npm ci
                npm test -- --coverage --ci
            """.trimIndent()
        }
    }
    failureConditions {
        testFailure = true
        errorMessage = true
    }
})

object Deploy : BuildType({
    name = "Deploy to Production"
    type = Type.DEPLOYMENT
    dependencies {
        snapshot(Test) {}
        artifacts(Build) {
            artifactRules = "dist.zip => ."
        }
    }
    params {
        param("deploy.env", "production")
    }
    steps {
        script {
            scriptContent = """
                unzip dist.zip -d /var/www/app/
                sudo systemctl reload nginx
            """.trimIndent()
        }
    }
    triggers {
        vcs {
            branchFilter = "+:refs/heads/main"
        }
    }
})

Deployment via SSH

For PHP projects (Laravel, Symfony), we added an SSH step:

sshExec {
    commands = """
        cd /var/www/app
        git pull origin main
        composer install --no-dev --optimize-autoloader
        php artisan migrate --force
        php artisan config:cache
        php artisan route:cache
        php artisan view:cache
        sudo systemctl reload php8.3-fpm
    """.trimIndent() // targetUrl and credentials are configured via TeamCity parameters
}

Docker Build in TeamCity

Containerization unifies the environment and eliminates "it works on my machine" errors.

steps {
  dockerCommand {
    commandType = build {
      source = file {
        path = "Dockerfile"
      }
      namesAndTags = "myapp:%build.counter%"
      commandArgs = "--no-cache"
    }
  }
  dockerCommand {
    commandType = push {
      namesAndTags = "myapp:%build.counter%"
    }
  }
}

Parameters and Templates

Multi-environment projects (staging, production) are configured via templates. One template — three environments, minimal code.

template("DeployTemplate") {
    params {
        param("env.name", "")
        param("env.url", "")
        param("ssh.host", "")
    }
    steps {
        script {
            scriptContent = "deploy.sh %env.name% %env.url%"
        }
    }
}

object DeployStaging : BuildType({
    templates(DeployTemplate)
    params {
        param("env.name", "staging")
        param("env.url", "https://staging.example.com")
        param("ssh.host", "staging.server.com")
    }
})

Why TeamCity Beats Jenkins?

TeamCity is faster with parallel builds — by a factor of 2, thanks to its built-in artifact storage and smart scheduler. Kotlin DSL offers type safety and IDE autocompletion, while Jenkins Pipeline uses Groovy with dynamic typing, often leading to runtime errors. Native templates and environment parameters in TeamCity simplify scaling to dozens of projects. For clarity:

Criteria TeamCity Jenkins
Configuration Kotlin DSL (static typing) Groovy (dynamic)
Parallel builds Built-in scheduler, 2x faster Requires tuning
Environment templates Native parameters and templates Via libraries
Artifacts Built-in storage Plugin

Order TeamCity setup and get a ready pipeline with documentation in 5–7 days. The TeamCity CI/CD setup process is straightforward and can save your team 30–40 hours per month.

How to Set Up TeamCity CI/CD in 5 Steps

  1. Install TeamCity server and agents — Use Docker or bare metal. Mount volumes for data and logs.
  2. Configure VCS roots — Connect to Git repository and set up VCS triggers.
  3. Define build configurations — Write Kotlin DSL scripts for build, test, and deploy steps.
  4. Set up environment templates — Create parameterized templates for dev, staging, and production.
  5. Enable notifications and documentation — Configure Slack/email alerts and document the pipeline.

Deployment for multiple environments is configured using templates with parameters. Each environment is a separate build type linked to the template. VCS triggers on main run automatic deployment to staging; production only via manual UI trigger. This prevents accidental production deployments.

Common CI/CD Setup Mistakes
  • Ignoring artifactRules — artifacts don't reach the next build, deployment breaks
  • Lack of agent isolation — library conflicts cause unpredictable test failures
  • Hardcoded credentials — keys in code, security leak. Use TeamCity parameters and password storage
  • Too long pipelines — all steps in one build, no parallelization. Split into Build -> Test -> Deploy
  • No notifications — team learns of build failure hours later

Which Projects Require CI/CD Automation?

Any project where releases happen more than once a month and deployment is manual. Especially if the team has more than two developers. TeamCity pays for itself by reducing build time and eliminating human errors. Our clients — from fintech startups to enterprise portals — save 10 to 40 hours per month on deployment operations.

What's Included in the Work

  • Audit of current build and deployment process (1 day)
  • Installation of TeamCity server and agents (Docker or bare metal) — 1 day
  • VCS triggers, build, test, and artifact configuration
  • Environment templates (dev/staging/production)
  • Build status notifications (Slack, email)
  • Pipeline testing and bug fixing
  • Documentation and training for your team
  • One-month warranty after delivery

Timelines and Cost

Cost is calculated individually after project analysis. Estimated timelines:

Component Time
Installation and basic configuration 1 day
Kotlin DSL and templates 1–2 days
Integration with VCS and tests 1 day
Deployment to environments 1–2 days
Notifications and documentation 1 day

Contact us for a consultation on TeamCity setup for your project. We'll help automate deployment without headaches.