Skip to content
Latchkey

How to Run a Postgres Service in a Jenkins Pipeline

Jenkins runs sidecar services with the Docker Pipeline plugin's docker.image().withRun, which starts and links a container around your steps.

Use the Docker Pipeline plugin's sidecar pattern: withRun starts a container, gives you its handle, and tears it down when the block exits.

Postgres sidecar

Start Postgres, wait for it, run tests against it, then it is automatically removed.

Jenkinsfile
pipeline {
  agent any
  stages {
    stage('Test') {
      steps {
        script {
          docker.image('postgres:16').withRun(
            '-e POSTGRES_PASSWORD=postgres -p 5432:5432'
          ) { c ->
            sh 'until pg_isready -h localhost -p 5432; do sleep 1; done'
            withEnv(['DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres']) {
              sh 'npm ci && npm test'
            }
          }
        }
      }
    }
  }
}

Gotchas

  • Requires the Docker Pipeline plugin and a Docker daemon on the agent.
  • Wait for the DB to accept connections (pg_isready loop) before connecting - withRun returns as soon as the container starts.
  • If your build runs inside a container, link via the inner network alias instead of localhost.

Verify it actually works

Validate the pipeline definition against the running controller before committing. Jenkins parses declarative pipelines strictly, and a syntax error surfaces as a failed build rather than a clear parse message.

Terminal
# validate a Jenkinsfile against the live controller
curl -X POST -F "jenkinsfile=<Jenkinsfile" \
  https://your-jenkins/pipeline-model-converter/validate

# replay a build with modified script to test a change without committing
# Build page -> Replay -> edit -> Run

Agent and workspace assumptions that break in CI

  • An agent label that matches no online agent leaves the build queued indefinitely rather than failing.
  • Workspaces are reused between builds by default, so stale files from a previous run can mask or cause failures. Use cleanWs() or a fresh workspace when correctness matters.
  • Tools resolved from the controller PATH are not necessarily on the agent PATH. Declare them in a tools block or install them in the pipeline.
  • Credentials bound with withCredentials are masked in logs but still visible to any process you launch; avoid passing them as command-line arguments.

Frequently asked questions

How do I run a Postgres Service in a Jenkins Pipeline?
Use the Docker Pipeline plugin's sidecar pattern: withRun starts a container, gives you its handle, and tears it down when the block exits.
Postgres sidecar?
Start Postgres, wait for it, run tests against it, then it is automatically removed.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card