Skip to main content

Command Palette

Search for a command to run...

Creating development containers with devpack-for-spring

Updated
4 min read
Creating development containers with devpack-for-spring

In a previous post, I demonstrated the creation of build-containers that may be used to build a specific application in an air-gapped environment, or in continuous integration pipelines for a faster execution, that is a result of copying all the pre-fetched dependencies into the build-container image.

The same build-container images may be used as development containers with Visual Studio Code, using the Microsoft Dev Containers extension. Installing this extension is a prerequisite for this exercise:

A good way to set up your development environment is through the devpack-for-spring setup command used in the previous blog-post. For this exercise, you need to install docker using APT. If you are using devpack-for-spring setup, please select docker.io. If you are manually setting up the environment, please run:

sudo apt update && sudo apt install docker.io
💡
The Docker snap does not work with Microsoft Dev Containers. See this reported issue.

Creating a Dev Container for a Gradle application

Let us now try creating a build-container for a sample Gradle application and then use it as a dev container.

Step 1: Clone a sample Gradle project

git clone https://github.com/pushkarnk/helidon-hello && cd helidon-hello

Step 2: Create an input rockcraft.yaml

This is a critical step. A build container produced by the Rockcraft plugins is a chiseled container image. It cannot be used as-is with the Dev Container extension. For example, chiseled containers remove the root user. And Dev Containers need to run a vscode-server which needs root permissions for installation.

This is identified as an issue and a future rockcraft version should not need you to implement this workaround step.

As a workaround, we supply an input rockcraft.yaml and depend on the merge feature of Rockcraft plugins. The resulting YAML is a merger of the input and the default rockcraft.yaml generated by the Rockcraft plugins. Create a file named input-rockcraft.yaml in the project directory, with the following contents:

name: build-helidon-dev
base: ubuntu@24.04

environment:
  JAVA_HOME: /usr/lib/jvm/java-21-openjdk-${CRAFT_ARCH_BUILD_FOR}

parts:
  openjdk:
    plugin: nil
    stage-packages:
    - openjdk-21-jdk-headless
    source: .
    after:
    - dependencies
    override-build: |
      craftctl default

  dependencies:
    plugin: nil
    override-build: |
      craftctl default
💡
Using ubuntu@24.04 as the base is another critical requirement.

Step 3: Update the build.gradle

Configure the rockcraft plugin and configure the input rockcraft yaml created in the previous step.

plugins {
    id 'java'
    id 'application'
    id 'io.github.rockcrafters.rockcraft' version '1.2.1'
}

buildRockcraft {
    rockcraftYaml = "input-rockcraft.yaml"
}

Step 4: Create the build container

Using devpack-for-spring we create a build container image for the sample application. This step also copies it as a docker image to the local docker daemon.

devpack-for-spring plugin rockcraft push-build-rock

The docker image must be listed by docker image ls

$ docker image ls
REPOSITORY                                                                                  TAG              IMAGE ID       CREATED          SIZE
build-helidon-hello-dev                                                                     1.0.0            2a69adb0aa35   5 weeks ago      557MB
build-helidon-hello-dev                                                                     latest           2a69adb0aa35   5 weeks ago      557MB

Step 5: Create the devcontainer.json file

Create a hidden file named .devcontainer.json in the project. The image key should have the name of the build container image.

{
    "image": "build-helidon-hello-dev:latest",
    "containerUser": "ubuntu"
}

Step 6: Rebuild and reopen in container

In VS Code, press CTRL+SHIFT+P and enter Dev Containers: Rebuild and Reopen in Container in the search bar:

This should open the project within the container.

Step 7: Iterate

The extension returns a prompt into the container. You can now make changes to the project in VS Code and run gradle build within the container. The application running inside the container must be reachable through the host.

Please refer to this quick demo video, for a visual reiteration of the above steps.

Conclusion

Development containers offer the luxury of the developing and testing the applications in an environment that is very close to that in which they would be eventually deployed.

Rockcraft build container images, if not chiseled, may be used as development containers in VS Code along with the Dev Containers extension. Even if we continue to keep them chiseled, adding the root user might help make the experience more seamless. This should be addressed in a future version of the Rockcraft plugins and the devpack-for-spring.

More from this blog

Java for Ubuntu

14 posts