Skip to main content

Build Your First App

This walkthrough takes you from an empty repository to a working greyhound deployment. It starts with the smallest useful config, then adds the pieces most teams need next: a build, ingress, and secret-backed environment variables.

If you want the bare minimum example only, see the Hello World example. This page is the better starting point if you want to understand how a real app usually comes together.

What You Need First

Before you start, make sure your repository is ready for greyhound:

  • Your repository contains a .greyhound/config.yaml file.
  • The greyhound GitHub app has access to the repository.
  • You know how your team creates environments, usually by adding the deploy label to a pull request.

For a fuller setup checklist, see Prerequisites.

Step 1: Start with a Minimal App

Create .greyhound/config.yaml in the root of your repository:

name: hello-greyhound
services:
- name: web
image: nginx:1.27-alpine
ports:
- containerPort: 80
rules:
- service: web
hostnames:
- hello-${env.name}.${cluster.dnsDomain}

This does three things:

  • Declares a single service named web.
  • Runs that service from a public image.
  • Exposes the service through an ingress rule so the environment gets a URL.

Once the config is in your branch, create a pull request environment by following Create Environment. After greyhound finishes provisioning, you should get a hostname like hello-pr-123.example.internal.

Step 2: Build Your Own Image

Most apps do not run directly from a public image. They build an application image from source, then deploy that image in one or more services.

Here is a common next step:

name: sample-app
builds:
- name: app
dockerfile: Dockerfile
context: .

services:
- name: app
image_from_build: app
ports:
- containerPort: 8080
name: http
replicas: 1

rules:
- service: app
hostnames:
- app-${env.name}.${cluster.dnsDomain}

Key points:

  • Use builds when greyhound should produce the container image from the repository source.
  • Use image_from_build in a service to consume that built image.
  • Give ports a name when practical, especially if a service may expose more than one port.
  • replicas defaults to 1, so you can omit it until you need more than the default.

For the schema details behind these fields, see Builds, Services, and Rules.

Step 3: Add Runtime Configuration

Real applications usually need environment variables. Non-sensitive values can be placed directly in the config:

services:
- name: app
image_from_build: app
env:
- name: NUXT_PUBLIC_IS_DATA_MOCKED
value: 'true'
- name: NUXT_PUBLIC_GITHUB_ORG
value: Underdog-Inc
ports:
- containerPort: 8080
name: http

Use literal value entries for configuration you are comfortable committing to the repository. Greyhound expects these values to be strings.

Step 4: Pull Secrets from AWS

When the application needs sensitive values, reference synced Kubernetes secrets instead of committing the values directly.

services:
- name: app
image_from_build: app
env:
- name: NUXT_PUBLIC_IS_DATA_MOCKED
value: 'false'
- name: NUXT_GITHUB_TOKEN
valueFrom:
secretKeyRef:
key: key
name: sample-app-github-pat
- name: NUXT_SESSION_PASSWORD
valueFrom:
secretKeyRef:
key: key
name: sample-app-session
secrets:
- secretName: sample-app-github-pat
objectName: greyhound/sample-app-github-pat
secretObjectProviderType: secretsmanager
type: Opaque
- secretName: sample-app-session
objectName: greyhound/sample-app-session
secretObjectProviderType: ssmparameter
type: Opaque

Key points:

  • objectName is the name of the secret or parameter in AWS.
  • secretName is the Kubernetes secret name your container references.
  • Use secretsmanager for AWS Secrets Manager and ssmparameter for AWS Systems Manager Parameter Store.
  • Keep each synced Kubernetes secretName unique unless workloads are intentionally sharing the exact same secret object.

For more background, see Secrets and Parameters and Secrets.

Step 5: Iterate from the Environment

After the first deployment works, the usual loop is:

  1. Update .greyhound/config.yaml.
  2. Push a new commit to the pull request branch.
  3. Let greyhound rebuild and redeploy the environment.
  4. Inspect logs, pods, services, and ingress if something fails.

The CLI reference covers the common inspection commands, starting with Inspect Environment and Inspect Logs.

Where to Go Next