To get the most out of ephemeral developer environments, it is important to let Gitpod know how to build your project. We can achieve this by defining
tasks in the
.gitpod.yml configuration file.
Note: In your local developer environment, you likely set up your project only once. If you work in a team, you probably have written instructions on how to get started. With Gitpod, you automate these manual steps so that a new environment can be set up repeatedly by Gitpod.
Tasks are shell scripts that run on top of the Docker image you configure (learn more about custom Docker images).
With Gitpod, you have the following three types of tasks:
before: Use this for tasks that need to run before
command. For example, customize the terminal or install global project dependencies.
init: Use this for heavy-lifting tasks such as downloading dependencies or compiling source code.
command: Use this to start your database or development server.
The order in which these tasks execute depends on whether you have Prebuilds configured for your project and which startup scenario applies. Let’s look at the details.
In this startup scenario, you can see how Prebuilds impact the execution order of tasks:
init task is where you want to do the heavy lifting, things like:
- Download & install dependencies
- Compile your source code
- Run your test suite
- Any other long-running, terminating processes necessary to prepare your project
As displayed in the diagram above, we highly recommend you enable Prebuilds for your project. In that case, Gitpod executes the
before and most importantly,
init tasks automatically for each new commit to your project.
By the time you start a new workspace, all that’s left to do is execute the
before (optional) and
command tasks. The latter most often starts a database and/or development server.
Let Gitpod run the time-consuming
inittasks continuously behind the scene so you and anyone who opens your project on Gitpod doesn’t have to wait.
When you restart a workspace, Gitpod already executed the
init task (see above) either as part of a Prebuild or when you started the workspace for the first time.
As part of a workspace restart, Gitpod executes the
When you start a snapshot, Gitpod already executed the
init task (see above) either as part of a Prebuild or when you or a team member started the snapshot’s initial workspace for the first time.
As part of starting a snapshot, Gitpod executes the
You can configure where terminals open using the
openMode properties below.
Please note that this information is used if no previous terminals in the layout exist.
Snapshots will first try to reuse existing terminals in the layout, before opening new ones.
tasks: - name: Static Server command: python3 -m http.server 8080 - name: DB Server command: sh ./scripts/start-db.sh openMode: split-right
You can configure how the terminal should be opened relative to the previous task.
||Opens in the same tab group right after the previous tab|
||Opens in the same tab group left before the previous tab|
||Splits and adds the terminal to the right|
||Splits and adds the terminal to the left|
||Deprecated. Splits and adds the terminal to the top|
||Deprecated. Splits and adds the terminal to the bottom|
The examples below are common use cases you can get inspired by and adjust for your project’s needs.
inittasks need to terminate while
commandcan run indefinitely (i.e. until cancelled with Ctrl + C). This is because
initmay run as part of a prebuild and if these tasks do not terminate, the prebuild will eventually fail with a timeout.
Each task contains a single
npm command. The
init task terminates once the dependencies are installed while the
command task starts a development server and does not terminate.
tasks: - name: Dev Server init: npm install command: npm run dev
To run multiple commands for a given task, you can use the
| notation where each line below (make sure you indent correctly) runs in sequence once the previous command terminates.
In the following example, the
init task installs dependencies and configures a database. Then, the
command task starts the dev server(s).
Note: In case of multiple terminals, there is no guarantee on the order in which tasks execute. The only guarantee you have is that
commandexecute in that sequence per terminal.
tasks: - name: Dependencies & Database init: | npm install npm run configure-database command: npm run dev
Note: This doesn’t stop execution on errors. If
npm installin the example above fails, the
npm run configure-databasewill still run. See how to exit after failure below for a workaround.
When working with multiple terminals, you may have a situation where terminal 1 runs build scripts and terminal 2 and 3 require that these scripts complete first. This can be achieved with
gp sync-await and
tasks: - name: Rails init: > bundle install && yarn install --check-files && rails db:setup && gp sync-done bundle # 'bundle' is an arbitrary name command: rails server - name: Webpack init: gp sync-await bundle # wait for the above 'init' to finish command: bin/webpack-dev-server - name: Redis init: gp sync-await bundle command: redis-server - name: Sidekiq init: gp sync-await bundle command: sidekiq
Let’s say you have a web app dev server that takes a moment to start up to listen on port 3000. Once it’s up and running, you want to run end-to-end tests against
You can achieve this with two terminals and the
gp ports await CLI command.
tasks: - name: Dev Server init: npm install command: npm run dev - name: e2e Tests command: | gp ports await 3000 npm run test
If you wish to halt an entire task with for an error within the task script, then you could do the following:
tasks: - init: | ( set -e # Tells bash to immediately exit on failure off a command bundle install yarn install --frozen-lockfile bundle exec rake bundle exec nanoc compile )
Gitpod starts all your
tasks inside separate
$SHELL) shells. Gitpod can only assert the exit status of the shell process of a task. Normally
bash or other shells don’t halt on a failure of a command unless you explicitly ask it to.
bash only inherits the last exit status of a script run with it before it’s own
exit. Hence Gitpod can’t determine if all of your commands inside the
init task succeeded. To have that effect, you can put
set -e; on top of task shell-commands and wrap your whole task-script with
() to configure that particular task shell to halt and immediately exit with an error code for a failure of any command. This can be specially helpful for prebuilds (i.e
We’d love to hear from you if you have specific questions or ideas for additional examples. Please click the following link to open a pre-configured GitHub issue: Ask for a new Start Task example.