Creating an Extension Buildpack for .NET Apps

This topic explains how to write extension buildpacks for .NET apps.

Prerequisites

  • Linux or MacOS development machine or VM
  • golang v1.10 or later programming language
  • direnv environment variable manager for your shell

Overview

Most .NET Framework apps are pushed with the Hosted Web Core (HWC) buildpack.

The HWC buildpack contains the commonly required .NET dependencies used by .NET apps. This set of HWC buildpack dependencies is a subset entire gamut of possible .NET dependencies and does not contain all the DLLs that every app could need.

An extension buildpack supplies a custom set of .NET dependencies to an app’s container.

You cannot add modules or extensions directly to the HWC buildpack. If the HWC buildpack lacks dependencies your app requires, we recommend that you create an extension buildpack containing the missing dependencies required by your app.

Note: The HWC buildpack contains a number of built-in HWC features, for example, the URL Rewrite and HTTP compression modules. Extensions should only provide additional functionality to your app. For more information about existing HWC features, see Features in HWC Buildpack.

For additional extension buildpack configuration and creation commands see: Creating a Custom Buildpack in the Pivotal Engineering Journal.

Step 1. Initialize an Extension Buildpack

The buildpack-packager provides boilerplate code that you can use to start writing your buildpack.

  1. To install the buildpack-packager CLI tool, run the commands below.

    go get github.com/cloudfoundry/libbuildpack/
    go install github.com/cloudfoundry/libbuildpack/tree/master/packager
    
  2. To create your buildpack boilerplate, run the following command:

    buildpack-packager init --name BUILDPACK-NAME --path=BUILDPACK-DIRECTORY
    

    Where:

    • BUILDPACK-NAME is the name of the buildpack you are creating.
    • BUILDPACK-DIRECTORY is the directory where the boilerplate code will be written. If the directory does not exist, it is created by the buildpack-packager init process.

    For example:

    $ buildpack-packager init --name my-example --path=my-example-buildpack
    

  3. To activate direnv in your buildpack directory, run the following commands:

    cd BUILDPACK-DIRECTORY
    direnv allow
    

    Where: BUILDPACK-DIRECTORY is the directory created by the buildpack-packager command, containing the boilerplate code.

Step 2. Create an Extension Buildpack to Supply Additional DLLs to a .NET Framework App

An extension buildpack provides the dependencies required by your app that are missing in HWC buildpack. The extension buildpack references and supplies needed dependencies to the app’s container when you push the app.

To create an extension buildpack containing additional DLLs, follow the steps below:

  1. Create a list of the dependencies that your published app requires.

  2. Copy the DLLs for the dependencies into a ZIP file.

  3. On the command line, browse to the directory containing the new ZIP file.

  4. To generate a SHA for your ZIP file, run the following command:

    shasum -a256 DLL-ZIP-FILE
    

    Where DLL-ZIP-FILE is the name of your DLL ZIP file.

  5. Upload the ZIP file containing your dependencies to a private web server that is accessible by Cloud Foundry. You can also use an S3 bucket or Azure Storage.

  6. On the command line, browse to the directory created by the buildpack-packager init command above.

  7. Edit the manifest.yml file by adding a dependency section that references the DLL ZIP file as follows:

    dependencies:
    - name: BINARY-NAME 
      uri: http://s3.amazon.com/BUCKET-NAME/DLL-ZIP-FILE 
      version: 0.0.1
      sha256: GENERATED-SHA-256
      cf_stacks: 
      - windows 
    

    Where:

    • BINARY-NAME is the name of your binary application.
    • BUCKET-NAME is your S3 bucket name.
    • DLL-ZIP-FILE is the name of your DLL ZIP file.
    • GENERATED-SHA-256 is the generated SHA.
  8. Ensure the include_files section of the manifest contains bin/supply.exe.

  9. To navigate to the BUILDPACK-DIRECTORY/src/BUILDPACK-NAME/ directory, use either Windows Explorer, or your text editor’s ‘File - Open’ option.

  10. Edit the supply.go script.

  11. Add dependencies to the container’s PATH as follows:

    1. Add a stager.InstallDependency for the dependency and version you have in your manifest.yml file.
    2. Add a stager.AddBinDependency for every DLL file you want your app to be able to access.

    For example:

    dep := libbuildpack.Dependency{Name: "my-binary", Version: "0.0.1"}
    if err := s.Installer.InstallDependency(dep, s.Stager.DepDir()); err != nil {
      return err
    }
    if err := s.Stager.AddBinDependencyLink(filepath.Join(s.Stager.DepDir(), "MyBinary.dll"), "MyBinary.dll"); err != nil {
      return err
    }
    
  12. To configure the build.sh script to cross-compile, edit scripts/build.sh to include the following:

    GOOS=windows go build -ldflags="-s -w" -o bin/supply.exe mysql/supply/cli
    

Step 3. Build the Extension Buildpack

The following steps build a cached extension buildpack artifact.

  1. To build a cached buildpack artifact, run the following command:

    buildpack-packager build -cached -stack STACK-NAME
    

    Where:

    • STACK-NAME is the pre-built operating system that can run apps.

    Note: If the buildpack’s supply.go script contains a mistake, buildpack-packager throws an error. You should not push your app with the new extension buildpack until after all local errors have been corrected. You must push your app to determine whether the new extension buildpack functions as intended.

Step 4. Validate the Extension Buildpack

The following steps push an app with the cached extension buildpack artifact.

  1. Upload the buildpack to a private web server accessible to Cloud Foundry. You can upload the finished buildpack to the same web server as your dependencies. You can also use an S3 bucket or Azure Storage.

  2. To deploy your app with the extension buildpack and determine whether the new buildpack functions as intended, run the following command:

    cf push APP-NAME -s windows -b EXT-BUILDPACK-URL -b hwc_buildpack
    

    Where:

    • APP-NAME is your app’s name.
    • EXT-BUILDPACK-URL is the URL of the uploaded extension buildpack zip file.

    For example:

    $ cf push my-app -s windows2016 -b http://s3.amazon.com/my-bucket/my-example-buildpack.zip -b hwc_buildpack
    

If your extension buildpack does not include the correct dependencies, you will receive an error message.

Step 5. Combine Extension Buildpack with Other Features

If your extension buildpack has executables or scripts that need to be run, you can reference them either in the start command or in profile scripts.

  • For more information about the start command, see command in Deploying with Application Manifests.

  • For more information about profile scripts, see Configure Pre-Runtime Hooks in Deploying an Application.

Create a pull request or raise an issue on the source for this page in GitHub