{"id":21097551,"url":"https://github.com/fluidattacks/makes-example","last_synced_at":"2026-03-08T01:06:23.954Z","repository":{"id":38935989,"uuid":"498910326","full_name":"fluidattacks/makes-example","owner":"fluidattacks","description":"Basic example of Makes usage","archived":false,"fork":false,"pushed_at":"2024-02-01T17:13:09.000Z","size":139,"stargazers_count":20,"open_issues_count":4,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-16T16:49:09.218Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fluidattacks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-01T21:59:07.000Z","updated_at":"2024-10-03T01:55:27.000Z","dependencies_parsed_at":"2024-11-20T13:45:36.050Z","dependency_job_id":null,"html_url":"https://github.com/fluidattacks/makes-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fluidattacks/makes-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluidattacks%2Fmakes-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluidattacks%2Fmakes-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluidattacks%2Fmakes-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluidattacks%2Fmakes-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluidattacks","download_url":"https://codeload.github.com/fluidattacks/makes-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluidattacks%2Fmakes-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30240357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:58:18.660Z","status":"ssl_error","status_checked_at":"2026-03-08T00:55:48.608Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T22:48:40.992Z","updated_at":"2026-03-08T01:06:23.934Z","avatar_url":"https://github.com/fluidattacks.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦄 Makes Example\n\nThis is the official hands-on example for [Makes][makes].\n\n## Why\n\nAs a framework designed\nto simplify the development\nof secure and high-quality applications,\n[Makes][makes] comprises a wide range of functionalities\nthat may nonetheless overwhelm\nthose who are just starting\nto learn how to use it.\n\nThat is why we created an example\nthat focuses on using the most basic\nyet powerful builtins\n[Makes][makes] has to offer.\n\nThis example simulates a\nreal application with\nseveral deployments a day.\n\nWe will show how [Makes][makes] is:\n\n### Secure\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n\nOn Makes,\ndirect and indirect dependencies\nfor both applications and CI/CD pipelines\nare cryptographically signed,\ngranting an immutable software supply chain.\n\n### Easy\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n\nMakes can be installed with just one command\nand has dozens of generic CI/CD builtins.\n\n### Fast\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-fast-blueviolet.svg\" alt=\"fast\"\u003e](#fast)\n\nMakes supports a distributed\nand completely granular cache.\n\n### Portable\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n\nMakes runs on Docker, VMs,\nand any Linux-based OS.\nSuch a feature greatly simplifies\nthe task of running applications\nand CI/CD jobs\non both local (developer machines)\nand remote (dev, staging, prod) environments.\n\n### Extensible\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nMakes can be extended\nto work with any technology.\n\n## How\n\nWe will achieve this by implementing\n\n1. the [FastAPI example](https://fastapi.tiangolo.com/#example);\n1. an isolated, cryptographically-signed environment\n   for running our API;\n1. development and production environments\n   for our API using [Stackhero][stackhero]\n   and [Docker Compose][docker_compose];\n1. general-purpose linters and formatters\n   to ensure code quality and security;\n1. a distributed cache\n   for high build performance, and\n1. a CI/CD workflow using [GitHub Actions][github_actions]\n   for orchestrating all the previous items.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n# Contents\n\n- [Prerequisites](#prerequisites)\n  - [Concepts](#concepts)\n  - [Software](#software)\n- [Backbone: Nix and Nixpkgs](#backbone-nix-and-nixpkgs)\n- [Running any Makes job](#running-any-makes-job)\n- [Running Makes on containers](#running-makes-on-containers)\n- [The makes.nix file](#the-makesnix-file)\n  - [Example builtin](#example-builtin)\n  - [Working with a Nixpkgs version](#working-with-a-nixpkgs-version)\n  - [Using imports](#using-imports)\n  - [Configuring the cache](#configuring-the-cache)\n- [The example API](#the-example-api)\n  - [API Source Code](#api-source-code)\n  - [API Environment](#api-environment)\n  - [API makes.nix](#api-makesnix)\n  - [API main.nix](#api-mainnix)\n  - [API Deployments](#api-deployments)\n- [References](#references)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# Prerequisites\n\n## Concepts\n\nHaving a **basic** understanding of the following concepts\nwill probably make this example much easier to grasp:\n\n- Continuous integration and delivery\n- Containers\n- Application dependencies\n- Shell scripting\n- Linters and formatters\n\nBelow, we give a **very brief** introduction to\n\n1. [Nix][nix] and\n1. [Nixpkgs][nixpkgs]\n\nas they are foundational components of [Makes][makes].\n\n## Software\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n\nYou just need to either have\n[Makes](https://github.com/fluidattacks/makes#getting-started)\nor\n[Docker][docker]\ninstalled on your system.\n\n# Backbone: Nix and Nixpkgs\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n[\u003cimg src=\"https://img.shields.io/badge/attr-fast-blueviolet.svg\" alt=\"fast\"\u003e](#fast)\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n\n[Makes][makes] relies on some core technology in order to work.\n\n[Nix][nix] is a package manager\nthat treats packages in a purely functional manner.\nThat is,\npackages are built by functions\nthat do not have secondary effects.\nThey never change once built.\nNix can be installed on any Linux-based OS.\n\nMakes relies on Nix\nto build reproducible and immutable workflows\nand environments. It also takes advantage of its\ngranular cache obtained by having isolated packages.\n\n[Nixpkgs][nixpkgs]\n\"is a collection of over 80,000 software packages\nthat can be installed with the Nix package manager.\"\nThe main advantage of [Nixpkgs][nixpkgs]\nover other package repositories\nis that packages are reproducible\nand pinned to an exact commit version.\nCompiled binaries for such packages\nare also accessible through `cache.nixos.org`.\n\nMakes uses Nixpkgs\nfor provisioning OS dependencies.\n\n# Running any Makes job\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n\nMakes has the ability\nto fetch any repository that supports it,\nso you won't have to clone this example\nunless you want to modify it.\n\nLocally:\n\n```bash\nm github:fluidattacks/makes-example@main\n```\n\nUsing [Docker][docker]:\n\n```bash\ndocker run ghcr.io/fluidattacks/makes/amd64:latest m github:fluidattacks/makes-example@main\n```\n\n# Running Makes on containers\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nAs mentioned before,\n[Makes][makes] also has a [Docker][docker] container.\nWe can take advantage of this\non [CI/CD providers](https://github.com/fluidattacks/makes#configuring-cicd),\n[Kubernetes][kubernetes],\n[Nomad][nomad],\n[Stackhero][stackhero],\nand basically anything that runs containers.\n\nIn this example,\nwe have a development\nand a production pipeline\nusing [GitHub Actions][github_actions].\nBoth of them can be found under `.github/workflows`.\n\nLet's take a look at this job in `.github/workflows/dev.yml`:\n\n```yaml\nformatNix:\n  runs-on: ubuntu-latest\n  steps:\n    - uses: actions/checkout@f095bcc56b7c2baf48f3ac70d6d6782f4f553222\n    - uses: docker://ghcr.io/fluidattacks/makes/amd64:latest\n      name: /formatNix\n      with:\n        args: sh -c \"chown -R root:root /github/workspace \u0026\u0026 m . /formatNix\"\n```\n\nBy looking at this portion of code\nwe can see that we use the [Makes][makes] container to run the\n`m . /formatNix` command.\n\nThanks to this feature\nyou can make your entire ecosystem reproducible\non any remote environment\nthat supports containers.\n\n# The makes.nix file\n\nYou will find this file in the root of the repository.\nAccording to the [documentation](https://makes.fluidattacks.com/),\nin this file you can specify any [builtin](https://makes.fluidattacks.com/api/builtins/)\nsupported by [Makes][makes]\nand configure it to run on your project.\n\n## Example builtin\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n\nLet's review one of the builtins used:\n\n```nix\n{\n  lintBash = {\n    enable = true;\n    targets = [\"/\"];\n  };\n}\n```\n\nThe [lintBash](https://makes.fluidattacks.com/api/builtins/lint/#lintbash) builtin\nlints all `bash` files\nwithin the specified path `/`.\n\nLet's try running it!\n\n```bash\n$ m github:fluidattacks/makes-example@main /lintBash\n\n                               🦄 Makes\n                             v22.11-linux\n\n────────── Fetching github:fluidattacks/makes-example@main ───────────\n\nInitialized empty Git repository in /tmp/makes-a7nxrsao/.git/\nCached from /home/nixos/.makes/cache/sources/github-fluidattacks-makes-example-main\nremote: Enumerating objects: 33, done.\nremote: Counting objects: 100% (33/33), done.\nremote: Compressing objects: 100% (28/28), done.\nremote: Total 33 (delta 1), reused 0 (delta 0), pack-reused 0\nUnpacking objects: 100% (33/33), 54.52 KiB | 9.09 MiB/s, done.\nFrom /home/nixos/.makes/cache/sources/github-fluidattacks-makes-example-main\n * [new branch]      main       -\u003e main\nSwitched to branch 'main'\n\n─────────────────── Building project configuration ───────────────────\n\n/nix/store/1z12m8gfyp0wsc9wx9b01vxfci9872hp-config.json\n\n───────────────────────── Building /lintBash ─────────────────────────\n\n/nix/store/6nkq7ykmn6l177zri1hh9wdng1q0468x-lint-bash\n───────────────────────────── Provenance ─────────────────────────────\nAttestation: /home/nixos/.makes/provenance-lintBash.json\nSHA-256: 427e69ed2e200ec82cd9bf33fa015d4afa40480020db1cd6a6ea47b91b996147\n\n──────────────────────────── 🤙 Success! ─────────────────────────────\n```\n\nIt temporarily clones the provided repository\nand then executes `/lintBash` within it,\ngranting compliance with good practices\nin all `bash` files.\n\n## Working with a Nixpkgs version\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n\nWe can also specify\nwhat version of [Nixpkgs][nixpkgs] we want to use\nby using [fetchNixpkgs](https://makes.fluidattacks.com/api/extensions/fetchers/#fetchnixpkgs).\n\n```nix\n{\n  inputs = {\n    nixpkgs = fetchNixpkgs {\n      rev = \"f88fc7a04249cf230377dd11e04bf125d45e9abe\";\n      sha256 = \"1dkwcsgwyi76s1dqbrxll83a232h9ljwn4cps88w9fam68rf8qv3\";\n    };\n  };\n}\n```\n\nWe can later reference\nthis version of Nixpkgs\nto install any package we want.\n\n## Using imports\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nAnother important builtin is:\n\n```nix\n{\n  imports = [\n    ./api/makes.nix\n  ];\n}\n```\n\nThe `imports` builtin serves a very simple purpose,\nwhich is being able to specify other `makes.nix` files\nfor [Makes][makes] to import them.\n\nAny supported builtin\ncan be configured by either\nadding it to the main `makes.nix` file\nor to an imported one.\n\n## Configuring the cache\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-fast-blueviolet.svg\" alt=\"fast\"\u003e](#fast)\n\nA decentralized [cache](https://makes.fluidattacks.com/api/builtins/performance/#cache)\nfor speeding up builds\nthat relies on [Cachix][cachix]\ncan be configured as follows:\n\n```nix\n{\n  cache = {\n    readNixos = true;\n    extra = {\n      makes = {\n        enable = true;\n        pubKey = \"makes.cachix.org-1:zO7UjWLTRR8Vfzkgsu1PESjmb6ymy1e4OE9YfMmCQR4=\";\n        token = \"CACHIX_AUTH_TOKEN\";\n        type = \"cachix\";\n        url = \"https://makes.cachix.org\";\n        write = true;\n      };\n    };\n  };\n}\n```\n\nThis allows anyone running [Makes][makes]\nto pull already-built [Nix derivations](https://nixos.org/manual/nix/stable/expressions/derivations.html)\nso they don't have to build the same thing twice.\nAll derivations are cryptographically signed,\nwhich helps avoid cache tampering.\n\nIn case you did not know,\n[Cachix][cachix] offers a [free tier for open-source projects](https://www.cachix.org/pricing)!\n\n# The example API\n\nIn the `api` directory\nyou will find several relevant paths.\nSuch paths represent\nthe core components required\nto make the API work.\n\n## API Source Code\n\nThe path `api/src`\ncontains the source code\nfor the example API.\n\n## API Environment\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n[\u003cimg src=\"https://img.shields.io/badge/attr-fast-blueviolet.svg\" alt=\"fast\"\u003e](#fast)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nUnder the path `api/env`,\nyou will find the implementation\nof an isolated environment\nfor all the dependencies\nrequired by the API to work.\n\n- `pyproject.toml` will orchestrate the API\n  and the dependencies required by it.\n- `poetry.lock` is a lockfile\n  with the entire dependency tree\n  required by the API.\n  Each dependency is cryptographically signed\n  and points to the exact URL\n  of the expected package.\n  You can use [makePythonLock](https://makes.fluidattacks.com/api/builtins/utilities/#makepythonlock)\n  to generate a lockfile for [makePythonEnvironment](https://makes.fluidattacks.com/api/extensions/python/#makepythonenvironment).\n- `main.nix` is the core file\n  for implementing [custom workflows](https://makes.fluidattacks.com/api/extensions/).\n  For this specific example,\n  it implements the [makePythonEnvironment](https://makes.fluidattacks.com/api/extensions/python/#makepythonenvironment)\n  builtin that creates a Python Virtual environment using [poetry2nix](https://github.com/nix-community/poetry2nix/tree/74921da7e0cc8918adc2e9989bd3e9c127b25ff6).\n  This environment will be used later on by the API.\n\n  Try running `m github:fluidattacks/makes-example@main /api/env`.\n  This will build the API environment.\n  If you run the job again,\n  it will use a cached environment\n  from the previous build.\n  Try changing the `name` input in `main.nix`\n  and running the job again.\n  As one of the inputs changed,\n  the previous cache is no longer valid\n  and a new version of the environment will be built.\n\n## API makes.nix\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nThis `makes.nix` file contains several linters\nthat run on the API source code.\n\nAn interesting job is this one:\n\n```nix\n{\n  lintPython = {\n    modules = {\n      api = {\n        searchPaths.source = [outputs.\"/api/env\"];\n        src = \"/api/src\";\n      };\n    };\n  };\n}\n```\n\nNotice that it uses `searchPaths.source`\nfor loading the API environment\npreviously described.\nThe linter needs this environment to\nrun some checks like static type checking.\n\n## API main.nix\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-secure-brightgreen.svg\" alt=\"secure\"\u003e](#secure)\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nThis is where a lot of the magic happens.\n\n```nix\n{\n  inputs,\n  makeScript,\n  outputs,\n  projectPath,\n  ...\n}:\nmakeScript {\n  replace = {\n    __argApiSrc__ = projectPath \"/api/src\";\n  };\n  name = \"api\";\n  searchPaths.source = [outputs.\"/api/env\"];\n  entrypoint = ./entrypoint.sh;\n}\n```\n\nThis file uses [makeScript](https://makes.fluidattacks.com/api/extensions/fundamentals/#makescript)\nto serve the API.\nHere is a detailed description of every parameter\n\n- `replace` allows the creation of placeholders\n  that can later be replaced\n  in the executed script.\n  It uses [projectPath](https://makes.fluidattacks.com/api/extensions/fundamentals/#projectpath),\n  a builtin that allows creating\n  an immutable version of a path\n  within a repository.\n  By doing this,\n  we will be able to reference\n  the API source code\n  in a semi-isolated environment.\n- `name` just allows specifying\n  the name of the job.\n- `searchPaths` implements the [makeSearchPaths](https://makes.fluidattacks.com/api/extensions/fundamentals/#makesearchpaths)\n  builtin.\n  It allows us to provide\n  all required dependencies\n  to our isolated environment.\n  For the API to run properly,\n  we will source the [API environment](#api-environment).\n- `entrypoint` is the shell script\n  that will be executed in the job.\n  It basically switches to the API source code directory\n  and runs a webserver for the API.\n\nLet's run it!\n\n```bash\n$ m github:fluidattacks/makes-example@main /api\n\n                                    🦄 Makes\n                                  v22.11-linux\n\n─────────────── Fetching github:fluidattacks/makes-example@main ────────────────\n\nInitialized empty Git repository in /tmp/makes-tz6mczs4/.git/\nCached from /home/dsalazar/.makes/cache/sources/github-fluidattacks-makes-example-main\nremote: Enumerating objects: 26, done.\nremote: Counting objects: 100% (26/26), done.\nremote: Compressing objects: 100% (22/22), done.\nremote: Total 26 (delta 1), reused 0 (delta 0), pack-reused 0\nUnpacking objects: 100% (26/26), 9.05 KiB | 2.26 MiB/s, done.\nFrom /home/dsalazar/.makes/cache/sources/github-fluidattacks-makes-example-main\n * [new branch]      main       -\u003e main\nSwitched to branch 'main'\n\n──────────────────────── Building project configuration ────────────────────────\n\n/nix/store/2mnjjd4gkzrbyr7g97yl19n2y4zv0hi3-config.json\n\n──────────────────────────────── Building /api ─────────────────────────────────\n\n/nix/store/sbi0rf8x3a5p9kyxhv8s0q2sxxmg8fsv-api\n\n─────────────────────────────────── Running ────────────────────────────────────\n\n/nix/store/aim1v9k173mrnsi8qdngj0q42miladdg-src /home/dsalazar/fluidattacks/makes-example\nINFO:     Will watch for changes in these directories: ['/nix/store/aim1v9k173mrnsi8qdngj0q42miladdg-src']\nINFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO:     Started reloader process [58876] using statreload\nINFO:     Started server process [58878]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\nThat's it!\n\nNow you can get\na running environment of the example API\nwith just one command, anywhere.\nThe entire environment exists within [Nix][nix],\ngranting full portability and ensuring that\nno dependencies are directly installed on your system.\nThe entire dependency tree is fully pinned and\ncryptographically signed.\nIf a component changes,\n[Makes][makes] will rebuild\nfrom there downwards,\nreusing all caches that remain unchanged\nand making sure all signatures are correct.\n\n## API Deployments\n\n[\u003cimg src=\"https://img.shields.io/badge/attr-easy-orange.svg\" alt=\"easy\"\u003e](#easy)\n[\u003cimg src=\"https://img.shields.io/badge/attr-portable-violet.svg\" alt=\"portable\"\u003e](#portable)\n[\u003cimg src=\"https://img.shields.io/badge/attr-extensible-blue.svg\" alt=\"extensible\"\u003e](#extensible)\n\nIn the `api/deploy` path\nwe will find the job\nfor deploying the API.\n\nThe job takes one of these two parameters\n\n- `dev` will deploy the API to\n  `https://makes.fluidattacks.com/${GITHUB_HEAD_REF}`.\n- `prod` will deploy the API to\n  `https://makes.fluidattacks.com/`.\n\nIt requires these external variables to be exported\n\n- `STACKHERO_SERVICE_ID` (required),\n  for authenticating to [Stackhero][stackhero].\n- `STACKHERO_PASSWORD` (required),\n  for authenticating to Stackhero.\n- `GITHUB_HEAD_REF` (required for `dev`),\n  for setting the URL path.\n\nIts relevant files are these:\n\n- `compose.yaml` is the [Docker Compose][docker_compose] file\n  used for deploying\n  an instance of the API.\n  Many of its parameters\n  contain placeholders\n  that will be replaced\n  by the job\n  during execution time.\n- `entrypoint.sh` contains the script for the deploy job.\n  It basically logs in to Stackhero,\n  replaces all required placeholders in `compose.yaml`\n  and deploys a new version of the API.\n- `main.nix` provides another\n  [makeScript](https://github.com/fluidattacks/makes#makescript) job\n  like the ones reviewed above.\n\nLet's give it a try!\n\n```bash\n$ export STACKHERO_SERVICE_ID=XXXXXXXXXXX\n$ export STACKHERO_PASSWORD=XXXXXXXXXXX\n$ m github:fluidattacks/makes-example@main /api/deploy prod\n\n                                    🦄 Makes\n                                  v22.11-linux\n\n─────────────── Fetching github:fluidattacks/makes-example@main ────────────────\n\nInitialized empty Git repository in /tmp/makes-_molt5o0/.git/\nFrom github:fluidattacks/makes-example@main\nremote: Enumerating objects: 31, done.\nremote: Counting objects: 100% (31/31), done.\nremote: Compressing objects: 100% (27/27), done.\nremote: Total 31 (delta 1), reused 20 (delta 0), pack-reused 0\nUnpacking objects: 100% (31/31), 14.88 KiB | 476.00 KiB/s, done.\nFrom https://github.com/fluidattacks/makes-example\n * [new branch]      main       -\u003e main\nSwitched to branch 'main'\n\n──────────────────────── Building project configuration ────────────────────────\n\n/nix/store/5rdc529zr6rx9n2g56npbnif3z4xb6c7-config.json\n\n───────────────────────────── Building /api/deploy ─────────────────────────────\n\nthese 2 derivations will be built:\n  /nix/store/q0bhl11zsikf2a381lp9hmgg4wffpna6-make-template-for-api-deploy.drv\n  /nix/store/pchwjz1z7qw7d8z6nvpvi3j109k8gch9-api-deploy.drv\nbuilding '/nix/store/q0bhl11zsikf2a381lp9hmgg4wffpna6-make-template-for-api-deploy.drv'...\nbuilding '/nix/store/pchwjz1z7qw7d8z6nvpvi3j109k8gch9-api-deploy.drv'...\n[INFO] Copying files\n/nix/store/v5nj2z092pm0xwhn30k5x3llfqkr78wq-api-deploy\n\n─────────────────────────────────── Running ────────────────────────────────────\n\n/nix/store/dby4nqrn19p065gh7vfyi7w0cmg328sx-deploy /home/dsalazar/fluidattacks/makes-example\n/tmp/tmp.xSaQBmovKs /nix/store/dby4nqrn19p065gh7vfyi7w0cmg328sx-deploy /home/dsalazar/fluidattacks/makes-example\n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n100 10240  100 10240    0     0   8258      0  0:00:01  0:00:01 --:--:--  8264\n/nix/store/dby4nqrn19p065gh7vfyi7w0cmg328sx-deploy /home/dsalazar/fluidattacks/makes-example\nKilling makes-example-main ... done\nRemoving makes-example-main ... done\nNetwork app is external, skipping\nCreating makes-example-main ... done\n\n───────────────────────────────── 🍀 Success! ──────────────────────────────────\n```\n\nAfter a few minutes,\nwhen we go to https://makes.fluidattacks.com/docs,\nwe get the following:\n\n![Production environment](/static/deploy.png \"Production environment\")\n\nDeployment jobs for both development and production\nare supported using [GitHub Actions][github_actions].\nEvery time a developer opens a pull request,\na development environment for the API is created.\nSimilarly, once that pull request is merged,\na new version of the API is deployed to production.\n\n# References\n\n- [cachix]: https://www.cachix.org/\n  [Cachix][cachix]\n- [docker]: https://www.docker.com/\n  [Docker][docker]\n- [docker_compose]: https://docs.docker.com/compose/\n  [Docker Compose][docker_compose]\n- [fastapi]: https://fastapi.tiangolo.com/\n  [FastAPI][fastapi]\n- [github_actions]: https://docs.github.com/en/actions/\n  [GitHub Actions][github_actions]\n- [kubernetes]: https://kubernetes.io/\n  [Kubernetes][kubernetes]\n- [makes]: https://github.com/fluidattacks/makes/\n  [Makes][makes]\n- [nix]: https://nixos.org/\n  [Nix][nix]\n- [nixpkgs]: https://github.com/NixOS/nixpkgs/\n  [Nixpkgs][nixpkgs]\n- [nomad]: https://www.nomadproject.io/\n  [Nomad][nomad]\n- [stackhero]: https://www.stackhero.io/en/\n  [Stackhero][stackhero]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluidattacks%2Fmakes-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluidattacks%2Fmakes-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluidattacks%2Fmakes-example/lists"}