|
| 1 | +# Monorepo with Shared Configurations |
| 2 | + |
| 3 | +!!! info "New in version 2.10" |
| 4 | + |
| 5 | +This guide shows how to structure a monorepo where multiple services share common configurations. |
| 6 | + |
| 7 | +!!! tip |
| 8 | + [Profiles](../profiles.md) provide another powerful way to organize development environments by allowing different variations to activate automatically based on your hostname, username, or manually via CLI flags. They work particularly well with monorepo structures for managing team-specific or environment-specific configurations. |
| 9 | + |
| 10 | +## Project Structure |
| 11 | + |
| 12 | +``` |
| 13 | +my-monorepo/ |
| 14 | +├── devenv/ |
| 15 | +│ └── devenv.nix # Shared configurations |
| 16 | +├── services/ |
| 17 | +│ ├── api/ |
| 18 | +│ │ ├── devenv.yaml |
| 19 | +│ │ └── devenv.nix |
| 20 | +│ └── frontend/ |
| 21 | +│ ├── devenv.yaml |
| 22 | +│ └── devenv.nix |
| 23 | +``` |
| 24 | + |
| 25 | +## Shared Configuration |
| 26 | + |
| 27 | +Create a shared configuration with common settings: |
| 28 | + |
| 29 | +```nix title="devenv/devenv.nix" |
| 30 | +{ pkgs, ... }: { |
| 31 | + packages = [ |
| 32 | + pkgs.curl |
| 33 | + pkgs.jq |
| 34 | + ]; |
| 35 | +
|
| 36 | + services.postgres = { |
| 37 | + enable = true; |
| 38 | + initialDatabases = [ |
| 39 | + { name = "myapp"; } |
| 40 | + ]; |
| 41 | + }; |
| 42 | +
|
| 43 | + pre-commit.hooks = { |
| 44 | + prettier.enable = true; |
| 45 | + nixpkgs-fmt.enable = true; |
| 46 | + }; |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +## Service Configuration |
| 51 | + |
| 52 | +### API Service |
| 53 | + |
| 54 | +Each service imports the shared configuration using an **absolute import path**. Paths starting with `/` are resolved from the repository root (where `.git` is located), allowing services in different directories to reference shared configurations consistently. |
| 55 | + |
| 56 | +```yaml title="services/api/devenv.yaml" |
| 57 | +imports: |
| 58 | + - /devenv |
| 59 | +``` |
| 60 | +
|
| 61 | +```nix title="services/api/devenv.nix" |
| 62 | +{ pkgs, ... }: { |
| 63 | + # Node.js for the API |
| 64 | + languages.javascript = { |
| 65 | + enable = true; |
| 66 | + package = pkgs.nodejs_20; |
| 67 | + }; |
| 68 | + |
| 69 | + # API-specific environment |
| 70 | + env = { |
| 71 | + API_PORT = "3000"; |
| 72 | + SERVICE_NAME = "api"; |
| 73 | + }; |
| 74 | + |
| 75 | + # API scripts |
| 76 | + scripts = { |
| 77 | + dev.exec = "npm run dev"; |
| 78 | + test.exec = "npm test"; |
| 79 | + }; |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +### Frontend Service |
| 84 | + |
| 85 | +```yaml title="services/frontend/devenv.yaml" |
| 86 | +imports: |
| 87 | + - /devenv |
| 88 | +``` |
| 89 | +
|
| 90 | +```nix title="services/frontend/devenv.nix" |
| 91 | +{ pkgs, ... }: { |
| 92 | + languages.javascript = { |
| 93 | + enable = true; |
| 94 | + package = pkgs.nodejs_20; |
| 95 | + }; |
| 96 | + |
| 97 | + # Frontend scripts |
| 98 | + scripts = { |
| 99 | + dev.exec = "npm run dev"; |
| 100 | + build.exec = "npm run build"; |
| 101 | + }; |
| 102 | +} |
| 103 | +``` |
| 104 | + |
| 105 | +## Referencing the Repository Root |
| 106 | + |
| 107 | +When working in a monorepo, you often need to reference paths relative to the repository root. Use `config.git.root` to get the absolute path to the git repository root. |
| 108 | + |
| 109 | +This is particularly useful for running processes from specific directories: |
| 110 | + |
| 111 | +```nix title="services/api/devenv.nix" |
| 112 | +{ pkgs, config, ... }: { |
| 113 | + processes.api.exec = { |
| 114 | + exec = "npm run dev"; |
| 115 | + cwd = "${config.git.root}/services/api"; |
| 116 | + }; |
| 117 | +
|
| 118 | + processes.frontend.exec = { |
| 119 | + exec = "npm run dev"; |
| 120 | + cwd = "${config.git.root}/services/frontend"; |
| 121 | + }; |
| 122 | +} |
| 123 | +``` |
| 124 | + |
| 125 | +This allows you to run multiple service processes from a single devenv shell, regardless of which directory you're in. |
| 126 | + |
| 127 | +## Working with Services |
| 128 | + |
| 129 | +Enter a specific service environment: |
| 130 | + |
| 131 | +```bash |
| 132 | +cd services/api |
| 133 | +devenv shell |
| 134 | +``` |
| 135 | + |
| 136 | +The API service will have access to: |
| 137 | + |
| 138 | +- All packages from `shared/devenv.nix` (git, curl, jq) |
| 139 | +- The PostgreSQL database service |
| 140 | +- Common environment variables (PROJECT_NAME, ENVIRONMENT, DATABASE_URL) |
| 141 | +- Its own specific settings (API_PORT, SERVICE_NAME) |
| 142 | + |
| 143 | +Similarly, the frontend service inherits the shared configuration while maintaining its own specific settings. |
0 commit comments