Projects
The first step to using Garden is to create a project. You can use the garden create project
helper command, or manually create a project.garden.yml
file in the root directory of your project:
We suggest naming it project.garden.yml
for clarity, but you can also use garden.yml
or any filename ending with .garden.yml
.
The helper command has the benefit of including all the possible fields you can configure, and their documentation, so you can quickly scan through the available options and uncomment as needed.
How it Works
The top-level project.garden.yml
file is where project-wide configuration takes place. This includes environment configurations and project variables. Most importantly, it's where you declare and configure the providers you want to use for your project (see below).
Garden treats the directory containing the project configuration as the project's top-level directory. Garden commands that run in subdirectories of the project root are assumed to apply to that project, and commands above/outside a project root will fail—similarly to how Git uses the location of the repo's .git
directory as the repo's root directory.
Environments and namespaces
Every Garden command is run against one of the environments defined in the project-level configuration file. You can specify the environment with the --env
flag or by setting a defaultEnvironment
. Alternatively, Garden defaults to the first environment defined in your configuration.
An environment can be partitioned using namespaces. A common use-case is to split a shared development or testing environment by namespace, between e.g. users or different branches of code.
Namespaces are similar in nature to Kubernetes but do not directly map to Kubernetes namespaces unless you explicitly configure them to do so. By default, the kubernetes
and local-kubernetes
providers set the Kubernetes namespace to <project name>-<Garden namespace>
. You can override this by setting the namespace
field in the respective provider configuration (more on that below), for example namespace: ${environment.namespace}
.
Here's a fairly typical list of environments:
A few things to notice here. Starting with the two development environments, we have a local one for those preferring to e.g. use a local Kubernetes cluster, and a shared dev
environment. For the latter we set the defaultNamespace
to the current username (plus a prefix), to implicitly split it up by different users.
Another option there would be to set defaultNamespace: null
and require users to explicitly set a namespace at runtime. You do this by specifying --env=<namespace>.<env>
at the command line, e.g. --env=hellothisisme.dev
.
For the other environments we leave defaultNamespace
set to the default, which is simply default
. So when you run Garden with --env=staging
, that automatically expands to --env=default.staging
.
The staging
and prod
environments have an additional flag set, the production
flag. This flag changes some default behavior and turns on protection for certain Garden commands that might be destructive, e.g. garden deploy
, requiring you to explicitly confirm that you want to execute them. See more details on that in the reference.
The current environment and namespace are frequently used in template strings. ${environment.name}
resolves to the environment name (in the above example, local
, dev
, staging
or prod
), ${environment.namespace}
resolves to the namespace, and ${environment.fullName}
resolves to the two combined with a DNS-style notation, e.g. my-namespace.dev
.
Providers
A project consists of one or more modules that each has a specific type
, for example container
or kubernetes
. (We talk about adding modules in the next guide.) Providers implement some of the behaviour of these module types.
Consider a project with the following three environments:
Our choice of providers and their configuration dictates how the module in the example above is handled:
If we run
garden build my-module --env empty
, thebuild
handler for thecontainer
module type (which is configured automatically) will do the build, essentially callingdocker build
behind the scenes. Runninggarden deploy
will fail because no provider is configured to handle the deployment.If we run
garden build my-module --env local
, thelocal-kubernetes
provider will "step in". It will still build the module via Docker but it will also push the image to the local Kubernetes cluster. Runninggarden deploy
will deploy the project to a local Kubernetes cluster such as Minikube or Docker Desktop.If we run
garden build my-module --env remote
, thekubernetes
provider will take over. It basically does the same thing as thebuild
handler for thelocal-kubernetes
provider, but requires some extra configuration. Runninggarden deploy
will deploy the project to the remote cluster.
Some of the most commonly used providers are the local Kubernetes provider and the remote Kubernetes provider.
Here's the full list of supported providers.
Project outputs
You can define project outputs using the outputs
key in your project configuration that you can resolve and retrieve using the garden get outputs
command. This is handy when you need to extract some values generated by Garden for further scripting, either in a custom script or within workflows.
For example, here's how you can output the image name and tag created from a container
module build:
You can then retrieve this value by running e.g. garden get outputs -o json
and parsing the output with jq
.
Examples
Variables
Variables defined in the project config are accessible in template strings for all the project's module configurations. To illustrate, here's the project configuration from the variables example project:
... and the configuration for a module in the same project:
Further Reading
Next Steps
Continue on to the next guide for an introduction to adding modules, the building blocks of any Garden project.
Last updated