Skip to content

docker.inside() fails when environment variables contain newlines (e.g., GitLab MR Checklist) #739

@oshri1997

Description

@oshri1997

Jenkins and plugins versions report

Summary

The docker.inside() function in the Docker Pipeline Plugin fails to execute when an environment variable contains multiline text or special characters (such as ', ", , and $) that interfere with shell command evaluation. This is a critical issue for teams using the **GitLab Plugin**, as it automatically populates the GITLAB_QA_DESCRIPTIONenvironment variable with the Merge Request description. Since these descriptions frequently contain **Markdown checklists** or multiple lines, it consistently breaks thedocker.inside` block.

Environment

Note: This instance is in an air-gapped environment. Core versions retrieved manually:

  • Jenkins Version: 2.528.3
  • Docker Pipeline Plugin Version: 634.vedc7242b_eda_7
  • Agent Type: Linux Machine with Docker installed (Local/Static Agent)

Steps to Reproduce

  1. In a Jenkins Pipeline, ensure an environment variable contains a multiline string (simulating a GitLab MR description).
  2. Call docker.image().inside().
  3. The plugin generates a docker run command using -e flags. Because the newlines are not escaped or handled, the shell interprets the newline as the end of the command, leading to a crash before the container even starts.

Example Jenkinsfile

// This example demonstrates how a multiline GitLab MR Checklist 
// breaks the docker.inside function by corrupting the shell command.

node {
    stage('Reproduce Bug') {
        // Simulating the variable automatically populated by the GitLab Plugin
        withEnv(["GITLAB_QA_DESCRIPTION=## QA Checklist:\n- [ ] Unit tests passed\n- [ ] Documentation updated"]) {
            
            // This call will crash because 'inside' injects GITLAB_QA_DESCRIPTION 
            // directly into the 'docker run' shell command via the -e flag.
            docker.image('alpine').inside("--entrypoint=''") {
                sh 'echo "This point is never reached"'
            }
        }
    }
}

### What Operating System are you using (both controller, and any agents involved in the problem)?

### Environment
Note: This instance is in an air-gapped environment. Core versions retrieved manually:
- **Jenkins Version:** 2.528.3
- **Docker Pipeline Plugin Version:** 634.vedc7242b_eda_7
- **Agent Type:** Linux Machine with Docker installed (Local/Static Agent)

### Reproduction steps

1. Define a multiline environment variable in a Jenkins Pipeline (simulating a GitLab MR description/checklist).
2. Call `docker.image().inside()`.
3. Observe the failure as the plugin attempts to inject the variable via `-e` in a shell command.

Example Jenkinsfile:
```groovy
node {
    stage('Reproduce Bug') {
        // Simulating the GITLAB_QA_DESCRIPTION variable populated by GitLab Plugin
        withEnv(["GITLAB_QA_DESCRIPTION=## Checklist:\n- [ ] Task 1\n- [ ] Task 2"]) {
            docker.image('alpine').inside("--entrypoint=''") {
                sh 'echo "This will fail"'
            }
        }
    }
}

### Expected Results

The `docker.inside()` function should properly escape or wrap environment variables containing newlines (using an environment file or proper shell escaping) so that the generated `docker run` command remains valid.

### Actual Results

The generated shell command is corrupted because the newline is interpreted by the shell as the end of the 'docker run' command. This results in the following lines of the variable being executed as separate, non-existent shell commands, leading to "command not found" and a failed build.

### Anything else?

_No response_

### Are you interested in contributing a fix?

_No response_

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions