Skip to content

Bundling: cannot set target from Dockerfile #20143

@Townsheriff

Description

@Townsheriff

Describe the feature

Having an option to pass target for the docker build command.

Docket build help output:

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --add-host list           Add a custom host-to-IP mapping (host:ip)
      --build-arg list          Set build-time variables
      --cache-from strings      Images to consider as cache sources
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --iidfile string          Write the image ID to the file
      --isolation string        Container isolation technology
      --label list              Set metadata for an image
      --network string          Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                Do not use cache when building the image
  -o, --output stringArray      Output destination (format: type=local,dest=path)
      --platform string         Set platform if server is multi-platform capable
      --progress string         Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --secret stringArray      Secret file to expose to the build (only if BuildKit enabled): id=mysecret,src=/local/secret
      --ssh stringArray         SSH agent socket or keys to expose to the build (only if BuildKit enabled) (format: default|<id>[=<socket>|<key>[,<key>]])
  -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.

Use Case

I have multiple targets in the dockerfile which are using "from" instruction from previous targets, as well I have a target which only mounts a directory and starts webpack. I do this for the docker-compose, so I can run all my services/apps with one command.

Example:

FROM node:14 as iframe-assets-build

WORKDIR /iframe-assets

# Caching node modules
COPY iframe-assets/package*.json .
RUN npm ci

# Build the actual project
COPY iframe-assets .
RUN npm run build

# USED FOR LOCAL DEVELOPMENT IN DOCKER
FROM node:14 as iframe-assets-local

WORKDIR /iframe-assets

EXPOSE 9000

ENTRYPOINT [ "npm", "run", "start" ]

Proposed Solution

Allow passing target for the dockerfile to the options.

/**
 * Docker build options
 */
export interface DockerBuildOptions {
 // A NEW OPTION HERE
  /**
   * Build args
   *
   * @default - no build args
   */
  readonly buildArgs?: { [key: string]: string };

  /**
   * Name of the Dockerfile, must relative to the docker build path.
   *
   * @default `Dockerfile`
   */
  readonly file?: string;

  /**
   * Set platform if server is multi-platform capable. _Requires Docker Engine API v1.38+_.
   *
   * Example value: `linux/amd64`
   *
   * @default - no platform specified
   */
  readonly platform?: string;
}

  public static fromBuild(path: string, options: DockerBuildOptions = {}) {
    const buildArgs = options.buildArgs || {};

    if (options.file && isAbsolute(options.file)) {
      throw new Error(`"file" must be relative to the docker build directory. Got ${options.file}`);
    }

    // Image tag derived from path and build options
    const input = JSON.stringify({ path, ...options });
    const tagHash = crypto.createHash('sha256').update(input).digest('hex');
    const tag = `cdk-${tagHash}`;

    const dockerArgs: string[] = [
      'build', '-t', tag,
      ...(options.file ? ['-f', join(path, options.file)] : []),
      ...(options.platform ? ['--platform', options.platform] : []), 
	  // AND NEW OPTION HERE
      ...flatten(Object.entries(buildArgs).map(([k, v]) => ['--build-arg', `${k}=${v}`])),
      path,
    ];

    dockerExec(dockerArgs);

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

^2.6.0

Environment details (OS name and version, etc.)

MacOS

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions