# Difference Between /build, /deployments, and /scripts in the Go Project Layout

> Understand the Go Project Layout: Learn the distinct roles of /build for distributable artifacts, /deployments for infrastructure-as-code, and /scripts for automation tools. Optimize your Go projects.

- Repository: [golang-standards/project-layout](https://github.com/golang-standards/project-layout)
- Tags: deep-dive
- Published: 2026-03-06

---

**TLDR:** In the golang-standards/project-layout repository, `/build` contains CI configurations and packaging scripts that create distributable artifacts, `/deployments` holds infrastructure-as-code templates that run those artifacts in production, and `/scripts` stores general-purpose automation tools used by developers and CI pipelines alike.

The golang-standards/project-layout defines a widely-adopted blueprint for organizing production-grade Go services. Understanding the difference between the `/build`, `/deployments`, and `/scripts` directories ensures you place CI configurations, infrastructure definitions, and utility scripts in their correct locations, keeping your repository maintainable and your delivery pipelines reproducible.

## /build: Packaging and Continuous Integration

The `/build` directory stores everything required to **package** the application and configure **Continuous Integration (CI)** pipelines. According to the official [/build/README.md](https://github.com/golang-standards/project-layout/blob/master/build/README.md), this directory focuses on producing distributable artifacts rather than running the application in production.

### Typical Contents

- **`/build/package/`** – Dockerfiles, deb/rpm specifications, and other OS packaging manifests
- **`/build/ci/`** – CI service configurations for Travis CI, CircleCI, Drone, or GitHub Actions

### When to Use /build

Place files here when you need to create a container image, binary package, or configure automated build pipelines. The scripts and configurations in this directory are tightly coupled to the artifact creation process.

```dockerfile

# build/package/Dockerfile

FROM golang:1.22 as builder
WORKDIR /src
COPY . .
RUN go build -o /app/myapp ./cmd/myapp

FROM debian:stable-slim
COPY --from=builder /app/myapp /usr/local/bin/myapp
ENTRYPOINT ["/usr/local/bin/myapp"]

```

*This Dockerfile resides in `/build/package` because it defines how the build artifact is constructed, not how it is deployed.*

## /deployments: Infrastructure and Runtime Deployment

The `/deployments` directory contains **Infrastructure-as-Code (IaC)** templates and orchestration descriptors that define how built artifacts run in target environments. The [/deployments/README.md](https://github.com/golang-standards/project-layout/blob/master/deployments/README.md) specifies this folder is for runtime configuration, describing clusters, VMs, and containers.

### Typical Contents

- **[`docker-compose.yml`](https://github.com/golang-standards/project-layout/blob/main/docker-compose.yml)** for local orchestration
- **Helm charts** and Kubernetes manifests
- **Terraform**, BOSH, or Ansible playbooks

### When to Use /deployments

Use this directory when describing production or staging environments. These files reference the artifacts produced by `/build` but do not create them.

```yaml

# deployments/k8s/helm/values.yaml

image:
  repository: myorg/myapp
  tag: "{{ .Values.image.tag }}"

```

*The Helm chart lives under `/deployments` and references an image tag produced during the build phase, maintaining a clear separation between building and running the application.*

## /scripts: Project-Level Automation

The `/scripts` directory houses miscellaneous helper scripts that keep your top-level `Makefile` minimal and perform tasks unrelated to packaging or deployment. As documented in [/scripts/README.md](https://github.com/golang-standards/project-layout/blob/master/scripts/README.md), these tools handle linting, code generation, and local installation.

### Typical Contents

- Bash, Go, or Python scripts for `go fmt`, `staticcheck`, or code generation
- Utilities invoked by the root `Makefile` (e.g., `make lint` → [`scripts/lint.sh`](https://github.com/golang-standards/project-layout/blob/main/scripts/lint.sh))

### When to Use /scripts

Place any repeatable developer-centric operation here that does not belong to packaging or deployment workflows. These scripts are often shared between local development and CI pipelines.

```makefile

# Makefile (root)

.PHONY: lint test

lint:
	@./scripts/lint.sh

test:
	@./scripts/test.sh

```

*The root `Makefile` delegates to `/scripts` to avoid complex logic in the project root while ensuring consistent behavior across developer workstations and CI runners.*

## How the Three Directories Work Together

These directories represent distinct phases of the software delivery lifecycle:

1. **Build Phase** – CI services read configurations from `/build/ci` and invoke scripts from `/scripts` to lint and test code. The pipeline then produces artifacts using `/build/package` (e.g., Docker images).

2. **Deploy Phase** – The produced artifacts are deployed using definitions from `/deployments`, such as Helm charts that pull the container image built in the previous step.

3. **Developer Automation** – Engineers run the same `/scripts` locally via `make` commands, ensuring identical behavior between development workstations and CI runners.

```yaml

# .github/workflows/ci.yml (located under /build/ci)

name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Lint
        run: ./scripts/lint.sh
      - name: Build Package
        run: docker build -f build/package/Dockerfile -t myapp:latest .

```

*This CI configuration demonstrates the relationship: it lives in `/build/ci`, invokes `/scripts` for quality checks, and uses `/build/package` for artifact creation.*

## Summary

- **`/build`** stores CI configurations and packaging scripts for creating distributable artifacts (Dockerfiles, deb/rpm specs) as defined in [/build/README.md](https://github.com/golang-standards/project-layout/blob/master/build/README.md)
- **`/deployments`** holds infrastructure-as-code and orchestration files for running applications (Helm charts, Terraform, Kubernetes manifests) according to [/deployments/README.md](https://github.com/golang-standards/project-layout/blob/master/deployments/README.md)
- **`/scripts`** contains general-purpose automation tools used by both developers and CI pipelines (linting, code generation, utility scripts) per [/scripts/README.md](https://github.com/golang-standards/project-layout/blob/master/scripts/README.md)
- The root `Makefile` delegates to `/scripts` to keep top-level project files minimal and maintainable

## Frequently Asked Questions

### Can I put Dockerfiles in /deployments instead of /build?

No. According to the golang-standards/project-layout convention, Dockerfiles belong in `/build/package` because they define how to construct the artifact. Place deployment-specific Docker Compose files or Kubernetes manifests that *run* the image in `/deployments`, but keep the image build definition in `/build`.

### Should CI configuration files go in the repository root or /build/ci?

Place them in `/build/ci`. While some CI services require configuration files in specific root locations (such as `.github/workflows`), service-specific configs for Travis CI, CircleCI, or Drone should reside in `/build/ci` to keep the repository root clean and clearly separate build automation from source code.

### Can /scripts contain deployment automation?

Avoid placing deployment-specific scripts in `/scripts`. If a script is tightly coupled to deploying infrastructure (e.g., applying Terraform or running Helm upgrades), it belongs in `/deployments`. Reserve `/scripts` for general-purpose tooling that could run in any context, such as code formatting or running tests.

### How does the root Makefile interact with these directories?

The root `Makefile` acts as a thin wrapper that calls scripts from `/scripts`. This design keeps the Makefile minimal and portable while allowing complex logic to live in version-controlled shell scripts rather than Make syntax. Both developers and CI pipelines invoke these same scripts, ensuring consistency across environments.