daytonaio / daytona

The Open Source Dev Environment Manager.
https://daytona.io
Apache License 2.0
7.05k stars 754 forks source link

Workspace Templates and Project Configuration #362

Open vedranjukic opened 3 months ago

vedranjukic commented 3 months ago

Is your feature request related to a problem? Please describe. Daytona does not have a mechanism to define reusable Workspace and Project configurations.

Describe the solution you'd like Adding Workspace Templates and Project Configurations the user would be able to create complex workspaces quickly from the predefined templates.

Each Project is related to the single git repository. Project Configuration should allow defining the custom base image used for the compute instance provisioned for the project, Project specific environment variables, custom image build instructions (Devcontainer, custom script), image build frequency (prebuilds) etc.

Workspace is comprised of one or more Projects. Workspace Template should allow easy Project composition.

These configurations are not an alternative to Dev container, Nix etc. and are not planned to be included in the project repository. They are Daytona specific and are created and managed by the user in the Daytona application. However they should be easy to share between users.

The scope if this Feature request is to draft the both the Project Configuration schema and Workspace Template schema.

vedranjukic commented 3 months ago

Project configuration could be defined as a json file with a schema that would allow defining project specifics such as project source location (git repo or even local or remote fs location), environment variables, project image build configuration, prebuilds settings.

Example of possible project configuration schema:

{
    //  required
    "schema": "1.0",
    //  required
    "name": "my-project",
    //  optional
    "meta": {
        //  optional
        "author": "John",
        //  optional
        "version": "1.0",
        //  optional
        "description": "This is my project",
    },
    "source": {
        //  required
        //  The URL of the git repository
        "url": "https://github.com/octocat/Hello-World",
        //  optional
        "revision": "main"
    },
    //  optional - ignored if "build" section is defined 
    //  The container image to use for the project
    "image": "docker.io/library/my-project:latest",
    //  optional
    //  The build context for the project
    "build": {
        //  optional  
        "commands": [
            //  optional
            "nix-build hello-docker.nix"
        ],
        //  optional
        //  Whether to publish the image
        "publish": true,
        //  optional
        //  
        "prebuilds": [
            {
                //  required
                "branch": "main",
                //  required
                //  The registry to push the prebuilt image to. Must be defined in the Daytona configuration
                "registry": "ghcr",
                //  optional
                //  Number of commits that are skipped between prebuilds
                "interval": "10",
                //  optional
                //  Executes prebuilds only if the commit message matches the regex
                "triggerFlag": "/some-regexp/",
                //  optional
                //  The number of prebuilds to keep
                "retention": "3"
            }
        ]
    },
    //  optional
    //  The minimum resources required for the project
    "requests": {
        //  optional
        "memory": "1Gi",
        //  optional
        "cpu": "0.5",
        //  optional
        "storage": "1Gi"
    },
    "environment": {
        //  optional
        "variables": {
            //  optional
            "ENV_VAR": "value"
        },
        //  optional
        "secrets": {
            //  optional
            "SECRET": "value"
        }
    }
}

The project can then be referenced in the workspace templates.

Example of possible workspace template schema:

{
    //  required
    "schema": "1.0",
    //  required
    "name": "my-workspace",
    //  optional
    "meta": {
        //  optional
        "author": "John",
        //  optional
        "version": "1.0",
        //  optional
        "description": "This is my project",
    },
    //  required
    "projects": [
        {
            //  required
            "name": "my-project"
        },
        {
            //  required
            "name": "my-other-project",
            //  optional
            "alias": "project-2",
            //  optional
            //  instructs provider to provision compute instance for the project
            //  with specified resource limits
            "size": {
                //  optional
                "memory": "1Gi",
                //  optional
                "cpu": "0.5",
                //  optional
                "storage": "1Gi"
            },
            //  optional
            //  sets or overrides environment variables
            "environment": {
                //  optional
                "variables": {
                    //  optional
                    "ENV_VAR": "value"
                },
                //  optional
                "secrets": {
                    //  optional
                    "SECRET": "value"
                }
            }
        }
    ]
}
Tpuljak commented 3 months ago

Since prebuilds, essentially require containers, there are considerations to be made for providers that are not "container-based" by nature.

Let's take the Digital Ocean (DO) provider as an example. The intention of the DO provider is to allow users to work inside Droplets. This means that the responsibility of the DO provider should be:

  1. Create a Droplet that will serve as a workspace to the user
  2. Lift up containers inside the droplet that will serve as projects to the user. The user can then use daytona ssh/code to start working inside the project.

To allow the DO provider to lift container inside the droplet, it needs to download the Daytona binary and run the Daytona Agent that connects to the server. This will enable the provider to forward the docker daemon sock that it can connect to to manage containers inside the droplet.

A rough sketch of that would be: Image

The same concept would be applied to similar providers such as an AWS EC2 provider.

vedranjukic commented 1 week ago

747 needs to be resolved first.