Build /

Build code from a Git repository

Northflank offers different methods for building code from a Git repository:

  • You can manually or automatically build commits on specified branches or pull requests from a linked Git repository using a build service
  • You can build and deploy commits on a branch on a linked Git repository with continuous integration and delivery in a combined service
  • You can build commits on a branch on a linked Git repository manually or on a regular schedule using a job

Enabling CI will allow you to automatically build code when a new commit is pushed to a linked branch from your repository, or specific branches and/or pull requests. Built code can then be continuously deployed and added to a pipeline to create complex workflows.

You'll need an account on a Git provider that is linked to Northflank to get started.

Build from a repository

To build and run code from one branch on a repository you can use:

  • a combined service
  • a build service linked to a deployment service
  • a cron or manual job

Create a new service or job, select the Git provider that contains the repository you want to build from, then select the branch.

Once created your service will build an image for every new commit to the branches or pull requests it is monitoring, as long as CI is enabled.

You can change the linked repository and branch for a service in build options.

Manually trigger a build

You can manually trigger a build by navigating to the branch or pull request to build from and selecting a commit to build.

You can find the list of branches and pull requests in the build service menu, or by clicking the build button in the build service header.

Northflank will begin building your commit, which may take several minutes. You can monitor the progress from the builds page and click through to view the logs for the build.

Build specific branches or pull requests

You can use a build service to build and run code from specific branches and/or pull requests by specifying build rules when creating a build service. You can edit the build rules of an existing build service on the build options page.

A build service will not build any branches or pull requests without specified build rules. By default, a build service will build from all pull requests (*) and the main branch.

Example build rules:

*Builds every branch or pull request
mainBuilds the branch or pull request called main
feature/*Builds every branch or pull request starting with release/
feature/testBuilds only the branch or pull request feature/test

Build a specific repository directory

If you have a single repository with multiple services, or your repository is structured so that your build context or Dockerfile (if using one) are not in the root, you can specify their locations when creating or editing your services.

You can specify the set of files to be used in the Docker build process by referring to a specific subdirectory relative to the root of your repository. To build all files from the root, use / as the build context or refer to a subdirectory such as /directory or /directory/subdirectory.

Learn more about contexts .

You can specify the location of the Dockerfile relative to the root of the repository. For example root: /Dockerfile, or in a subdirectory: /directory/subdirectory/Dockerfile.

Learn more about the Dockerfile .

Ignore files and paths

You can specify files or paths in your directory for Northflank to ignore to avoid triggering unnecessary builds.

Path ignore settings are found under advanced build settings in build options. They can be added when creating a build or combined service, and updated in existing services.

If one or more path ignore rules are provided, a build will only start automatically if a commit is pushed to the repository that does not match one of the rules provided.

A path ignore rule could be set to ignore changes made to README.md or other documentation files. If building a service from a monorepo, path ignore rules could be set to ignore changes to folders other than a specific folder.

The path ignore rules use the same format as a .gitignore file.

Specify build arguments

Available on combined and build services.

Build arguments (ARG) can be set to be passed to the Docker container at build-time. These can be set for individual builds on the build arguments page or set as project secrets to be applied to all or specific builds in a project.

Although unlikely, some Buildpacks may override your build arguments.

If using a Dockerfile, build arguments will be passed to the Dockerfile on build via the --build-arg flag. They do not persist in the built image and are set as key-value pairs. Variables must be declared in the Dockerfile with ARG before being accessed. For example, a variable set as "packages" : "npm-cache" can be accessed in the Dockerfile by declaring the ARG:

ARG packages
# or initialise with a default value:
# ARG packages=default_value

RUN echo "Using: ${packages}"

Build arguments can be set as key-value pairs, or as JSON in the following format:

    "key1": "value1",
    "key2": "value2"

An .env file can also be uploaded and edited using the following format:


Build using a Dockerfile

You can build your projects on Northflank by supplying a Dockerfile in your repository.

A custom Dockerfile gives you full control over each step of the build process, including things like build arguments and custom base images. You must specify the location of the Dockerfile in your repository and the build context (root by default).

Select Dockerfile as the build type when creating your service, or change an existing service from the build options page.

See Docker's guide on writing Dockerfiles and the Dockerfile reference for more information.

Build engine

Choose between Kaniko (default) or BuildKit under advanced build settings. You may want to choose another build engine if you experience any issues with reliability.

Optimise your Dockerfile


You should always include a .dockerignore file in your repository, in order to reduce the final image size by excluding everything unnecessary.

For example to ignore the git folder and .env files you would add the following to .dockerignore:


Layer caching

You can create a more efficient Dockerfile that will build faster on subsequent builds by taking advantage of layer caching (currently supported for Kaniko build engine).

For this example, we'll look at the build stage from Northflank's AngularJS template Dockerfile.

The first time the image is built Northflank will run all the build steps in the Dockerfile and write each layer to the image registry. For each subsequent build it checks whether the files for that layer have changed. If there are no changes, the existing layers will be used to complete the build.

In this example the build step COPY package*.json ./ is nearer the start of the Dockerfile as its files are likely to change less frequently. This means it can be cached and used for future builds where the contents of package*.json remain unchanged:

FROM node:lts-alpine as build-stage     # layer unchanged, use cache
WORKDIR /app                            # layer unchanged, use cache
COPY package*.json ./                   # layer unchanged, use cache
RUN npm install                         # layer unchanged, use cache
COPY . .                                # layer changed, run again
RUN npm run build                       # previous layer changed, run again

If you add another dependency to package.json, all layers after it must be rebuilt:

FROM node:lts-alpine as build-stage     # layer unchanged, use cache
WORKDIR /app                            # layer unchanged, use cache
COPY package*.json ./                   # layer changed, run again
RUN npm install                         # previous layer changed, run again
COPY . .                                # previous layer changed, run again
RUN npm run build                       # previous layer changed, run again

Build with Buildpacks

You can build your projects on Northflank using Buildpacks . This does not require you to supply a Dockerfile as a Buildpack will try to automatically determine how to build your project. You must specify the build context (root by default).

Select Buildpack as the build type when creating your service, or change an existing service from the build options page.

You can select from a list of popular Buildpacks under advanced build settings if you require support for other languages. Check the provider's documentation for more information on base images and language versions.

Buildpack stacks on Northflank

BuildpackBase imageSupported languages
heroku/buildpacks:20 Ubuntu 20.04Ruby, Node.js, Clojure, Python, Java, Gradle, JVM, Grails 3.x, Scala, Play 2.x, PHP, Go
heroku/buildpacks:18 Ubuntu 18.04Ruby, Node.js, Python, Java, PHP, Go
gcr.io/buildpacks/builder:v1 Ubuntu 18.04.NET Core, Java, Python, Node.js, Go
cnbs/sample-builder:alpine *Alpine 3.10Java, Kotlin
cnbs/sample-builder:bionic *Ubuntu 18.04Java, Kotlin, Ruby
paketobuildpacks/builder:tiny Ubuntu 18.04Java, Go

*Cloud-native Buildpack samples are not recommended for use in production.

Custom Buildpack group

You can use multiple Buildpacks together to provide support for more complex builds. For example, you might use one Buildpack to install Java, and another Buildpack to use Maven to build your application. The builder will run through all the Buildpacks to identify the correct ones to use in the build.

You can specify Buildpacks in one of the following formats:

URLhttps://<host>/<path>https://buildpack-registry.heroku.com/cnb/heroku/procfileNeeds to resolve to a tar.gz file
Github URLhttps://<host>/<path>https://github.com/heroku/heroku-buildpack-nodejs.gitMay further specify a tag, branch or commit ID using the format https://<host>/<repo>#<tag/branch/commit-id>
Image[docker://][<host>]/<path>[:<tag>]docker://docker.io/heroku/procfile-cnb:latestCan use @digest instead of :<tag>
CNB registry resourceurn:cnb:registry[:<id>[@<version>]]urn:cnb:registry:heroku/procfile

If a string does not include a scheme prefix (ex. docker://) the Buildpack type can be inferred from the format:

  • If it looks like a Docker ref, it will be treated as a docker:// URI
  • If it looks like a Buildpack Registry ID, it will be treated as a urn:cnb:registry URI

© 2022 Northflank Ltd. All rights reserved.