coder / envbuilder

Build development environments from a Dockerfile on Docker, Kubernetes, and OpenShift. Enable developers to modify their development environment quickly.
Apache License 2.0
111 stars 24 forks source link

Add Support for DevFile Spec 2+ #113

Open michaelbrewer opened 3 months ago

michaelbrewer commented 3 months ago

What is devfiles?

"You can use devfiles to automate and simplify your development process by adopting the existing devfiles that are available in the public community registry or by authoring your own devfiles to record custom instructions to configure and run your build environment as a YAML-formatted text file." - See https://devfile.io/docs/2.2.2/what-is-a-devfile

Benefits of devfile

Much like the devcontainer spec, devfile spec has a number of features.

Devfiles include the following features:

Devfiles have the following benefits:

Main benefits from these that differ from devcontainer are:

AI Generated differents

The devfile spec is a vendor-neutral definition for cloud-native dev workspaces, whereas the devcontainer spec is a Docker extension that aims to simplify local development.

Some examples

Java Spring Boot

schemaVersion: 2.1.0
metadata:
  name: java-springboot
  displayName: Spring Boot®
  description: Java application using Spring Boot® and OpenJDK 11
  icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/spring.svg
  tags:
    - Java
    - Spring
  projectType: springboot
  language: Java
  version: 1.3.0
  globalMemoryLimit: 2674Mi
starterProjects:
  - name: springbootproject
    git:
      remotes:
        origin: "https://github.com/odo-devfiles/springboot-ex.git"
components:
  - name: tools
    container:
      image: registry.access.redhat.com/ubi9/openjdk-17:1.17-1.1705573248
      command: ["tail", "-f", "/dev/null"]
      memoryLimit: 768Mi
      mountSources: true
      endpoints:
        - name: http-springboot
          targetPort: 8080
        - exposure: none
          name: debug
          targetPort: 5858
      volumeMounts:
        - name: m2
          path: /home/user/.m2
      env:
        - name: DEBUG_PORT
          value: "5858"
  - name: m2
    volume:
      size: 3Gi
commands:
  - id: build
    exec:
      component: tools
      workingDir: ${PROJECT_SOURCE}
      commandLine: "mvn clean -Dmaven.repo.local=/home/user/.m2/repository package -Dmaven.test.skip=true"
      group:
        kind: build
        isDefault: true
  - id: run
    exec:
      component: tools
      workingDir: ${PROJECT_SOURCE}
      commandLine: "mvn -Dmaven.repo.local=/home/user/.m2/repository spring-boot:run"
      group:
        kind: run
        isDefault: true
  - id: debug
    exec:
      component: tools
      workingDir: ${PROJECT_SOURCE}
      commandLine: "java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=${DEBUG_PORT},suspend=n -jar target/*.jar"
      group:
        kind: debug
        isDefault: true

NextJS project

schemaVersion: 2.1.0
metadata:
  name: nodejs-nextjs
  displayName: Next.js
  description: "Next.js gives you the best developer experience with all the features you need for production:
    hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more.
    No config needed."
  icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/next-js.svg
  tags:
    - Node.js
    - Next.js
  projectType: Next.js
  language: TypeScript
  provider: Red Hat
  version: 1.0.3
starterProjects:
  - name: nodejs-nextjs-starter
    git:
      checkoutFrom:
        revision: main
      remotes:
        origin: https://github.com/devfile-samples/devfile-stack-nodejs-nextjs.git
components:
  - container:
      endpoints:
        - name: http-nextjs
          targetPort: 3000
      image: registry.access.redhat.com/ubi8/nodejs-16:1-153
      command: ['tail', '-f', '/dev/null']
      memoryLimit: 1024Mi
    name: runtime
commands:
  - exec:
      commandLine: npm install
      component: runtime
      group:
        isDefault: true
        kind: build
      workingDir: ${PROJECT_SOURCE}
    id: install
  - exec:
      commandLine: npm run dev
      component: runtime
      group:
        isDefault: true
        kind: run
      hotReloadCapable: true
      workingDir: ${PROJECT_SOURCE}
    id: run

DotNet project

schemaVersion: 2.2.0
metadata:
  name: dotnet-basic
  displayName: Basic .NET
  version: 1.1.1
  icon: https://github.com/dotnet/brand/raw/main/logo/dotnet-logo.png
  provider: Red Hat
  supportUrl: https://github.com/devfile-samples/devfile-support#support-information
  language: .NET
  projectType: dotnet
  tags:
    - .NET
  attributes:
    alpha.dockerimage-port: 8081
starterProjects:
  - name: s2i-example
    git:
      checkoutFrom:
        remote: origin
        revision: dotnet-6.0
      remotes:
        origin: https://github.com/redhat-developer/s2i-dotnetcore-ex
    subDir: app
components:
  - name: dotnet
    container:
      image: registry.access.redhat.com/ubi8/dotnet-60:6.0
      command: ['tail', '-f', '/dev/null']
      mountSources: true
      env:
        - name: CONFIGURATION
          value: Debug
        - name: STARTUP_PROJECT
          value: app.csproj
        - name: ASPNETCORE_ENVIRONMENT
          value: Development
      endpoints:
        - name: http-8080
          targetPort: 8080
  - name: image-build
    image:
      imageName: 'dotnet-image:latest'
      dockerfile:
        uri: docker/Dockerfile
        buildContext: .
        rootRequired: false
  - name: kubernetes-deploy
    attributes:
      deployment/replicas: 1
      deployment/cpuRequest: 10m
      deployment/memoryRequest: 100Mi
      deployment/container-port: 8081
    kubernetes:
      uri: kubernetes/deployment.yaml
      endpoints:
        - name: http-8081
          targetPort: 8081
          path: /
          secure: true
  - name: kubernetes-service
    attributes:
      deployment/replicas: 1
      deployment/cpuRequest: 10m
      deployment/memoryRequest: 100Mi
      deployment/container-port: 8081
    kubernetes:
      uri: kubernetes/service.yaml
commands:
  - id: build
    exec:
      workingDir: ${PROJECT_SOURCE}
      commandLine: kill $(pidof dotnet); dotnet build -c $CONFIGURATION $STARTUP_PROJECT /p:UseSharedCompilation=false
      component: dotnet
      group:
        isDefault: true
        kind: build
  - id: run
    exec:
      workingDir: ${PROJECT_SOURCE}
      commandLine: dotnet run -c $CONFIGURATION --no-build --project $STARTUP_PROJECT --no-launch-profile
      component: dotnet
      group:
        isDefault: true
        kind: run
  - id: build-image
    apply:
      component: image-build
  - id: deploy-deployment
    apply:
      component: kubernetes-deploy
  - id: deploy-service
    apply:
      component: kubernetes-service
  - id: deploy
    composite:
      commands:
        - build-image
        - deploy-deployment
        - deploy-service
      group:
        isDefault: true
        kind: deploy
kylecarbs commented 3 months ago

I think we could do this quite easily if demand is there.

The devcontainer dir already abstracts that part of the project well.

michaelbrewer commented 3 months ago

One of the features i like is built in support for project templates starterProjects

marrotte commented 4 weeks ago

+1