@studiometa/forge-cli 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,6 +121,7 @@ forge config delete # Delete all stored config
121
121
  ```bash
122
122
  forge servers list # List all servers
123
123
  forge servers get <id> # Get server details
124
+ forge servers public-key <id> # Print the public key of the forge user, for the git host
124
125
  forge servers reboot <id> # Reboot a server
125
126
  forge servers create --name <name> --ip-address <ip> [--php-version php84 --database mariadb1011]
126
127
  # Create a server (Custom VPS by default)
@@ -155,8 +156,10 @@ forge sites apply --file site.json # Make the site match the file
155
156
  },
156
157
  "database": { "name": "example", "user": "example" },
157
158
  "env": { "APP_ENV": "production" },
159
+ "nginx": "nginx.conf",
158
160
  "workers": [{ "command": "php artisan queue:work database --queue=default", "processes": 4 }],
159
- "schedule": [{ "command": "php artisan schedule:run", "frequency": "minutely" }]
161
+ "schedule": [{ "command": "php artisan schedule:run", "frequency": "minutely" }],
162
+ "loadBalancer": { "server": "lb-1", "port": 80 }
160
163
  }
161
164
  ```
162
165
 
@@ -165,10 +168,44 @@ forge sites apply --file site.json # Make the site match the file
165
168
  | `server`, `domain` | Find the server and the site by exact name (never a partial match, with or without `--exact`). `server` can also be an ID |
166
169
  | `type`, `php`, `webDirectory`, `repository` | Create the site when it is missing (`type` is then required) and wait until Forge installs it. On an existing site, update `php`, `webDirectory` and the branch |
167
170
  | `aliases` | Add the missing aliases. Never remove one |
168
- | `database` | Create the database and the user when they are missing. A new user gets a random password, written only into the site `.env` (`DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`) |
171
+ | `database` | Create the database and the user when they are missing. A new user gets a random password, written only into the site `.env` (`DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`, see below) |
169
172
  | `env` | Add the missing keys to the site `.env`. A key with another value on Forge is reported, never overwritten |
173
+ | `nginx` | Nginx file, relative to the site file, with Forge template variables. Rendered for the site and written when it differs from Forge (see below) |
170
174
  | `workers` | Forge background processes of the site. Create the missing ones, delete the ones of the site that the file does not declare. The directory defaults to the site root |
171
175
  | `schedule` | Forge scheduled jobs of the site (`minutely`, `hourly`, `nightly`, `weekly`, `monthly`, `reboot`, or `custom` with `cron`). A relative `artisan` becomes the absolute path of the site |
176
+ | `loadBalancer` | Set the nodes of the site on the load balancer to `server` only, on `port` (default `80`), with round robin and weight 1. The site of the load balancer must exist (see below) |
177
+
178
+ For an application that does not read the Laravel names, `database.env` maps the database name, the user and the password to other `.env` keys. Each key is optional and defaults to the Laravel name. Other values, such as the host, go in `env`:
179
+
180
+ ```json
181
+ {
182
+ "database": {
183
+ "name": "example",
184
+ "user": "example",
185
+ "env": { "name": "DB_NAME", "user": "DB_USER", "password": "DB_PASSWD" }
186
+ },
187
+ "env": { "DB_SERVER": "127.0.0.1" }
188
+ }
189
+ ```
190
+
191
+ `nginx` points to an Nginx file that uses the variables of [Forge Nginx templates](https://forge.laravel.com/docs/servers/nginx-templates). `apply` renders the file locally with the values of the site, so one file works on any server, without a template on the server:
192
+
193
+ | Variable | Value |
194
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
195
+ | `{{SITE}}`, `{{SITE_ID}}`, `{{USER}}` | Site name (`www.example.com`), site ID (`456`), site user (`forge`) |
196
+ | `{{DOMAINS}}` | Site name and aliases, separated by spaces |
197
+ | `{{ROOT_PATH}}`, `{{PATH}}`, `{{DIRECTORY}}` | Site root, web directory (`/home/forge/www.example.com/public`) and its relative path (`/public`) |
198
+ | `{{PROXY_PASS}}` | PHP-FPM socket, e.g. `unix:/var/run/php/php8.3-fpm.sock` (`php8.3-fpm-<user>.sock` for an isolated site) |
199
+ | `{{PORT}}`, `{{PORT_V6}}` | `80` and `[::]:80` (with `default_server` for the site named `default`) |
200
+ | `{{SERVER_PUBLIC_IP}}`, `{{SERVER_PRIVATE_IP}}` | IP addresses of the server (empty when there is no private IP) |
201
+
202
+ Spaces inside the braces are allowed (`{{ SITE_ID }}`). An unknown variable is an error (exit `3`). On a new site, `apply` writes the file after Forge installs the site. On an existing site, the plan shows the diff from Forge to the rendered file (CRLF and the final newline do not count), and `apply` writes it. When `apply` also changes the site or its aliases, it reads the site again and renders the file with the new values. Forge returns the full `server` block on old servers and only its content on recent ones: write the file in the same form as `forge nginx get` prints it.
203
+
204
+ Forge clones the repository when it creates the site, with the key of the `forge` user of the server. Add this key to the git host (for example as a deploy key) before `apply` creates the site:
205
+
206
+ ```bash
207
+ forge servers public-key web-1 > server.pub # The key only; --format json gives { "public_key": "..." }
208
+ ```
172
209
 
173
210
  A worker or a scheduled job matches the file when its command, directory, processes (or frequency) and user are the same. Commands are compared after normalization: quotes (`'database'` and `database`), repeated spaces and a relative `artisan` (`php artisan` and `php /home/forge/www.example.com/artisan`) do not count as differences. Forge cannot update a worker: a changed worker is created again, then the old one is deleted.
174
211
 
@@ -181,6 +218,8 @@ A worker or a scheduled job matches the file when its command, directory, proces
181
218
  - Without the `workers` key, no worker is read or deleted. With `"workers": []`, all the workers of the site are deleted. The same applies to `schedule`.
182
219
  - The site, its aliases, its database and its `.env` keys are never deleted.
183
220
 
221
+ `loadBalancer` sends the traffic of the load balancer to the server of the file. The site of the load balancer is the one named `domain` or one of the `aliases`. When no site matches, `--check` and `apply` exit `3` before any change. When two sites match, they exit `3` too. The Forge API cannot create a site on a load balancer: create it in Forge (New site on the load balancer), with its certificate. To move a site to another server, change `server`: `apply` creates the site there, then moves the node, with no DNS change. It does not delete the site on the old server.
222
+
184
223
  With `--check`, `apply` prints the plan and changes nothing. It exits `0` when Forge matches the file, `1` when it differs, and another code on an error (`3` for an invalid file). Every deletion shows its ID and full command. The plan gives `.env` key names only, never values, and shows a generated password as `<generated>`. With `--format json`, it prints `{ "inSync": false, "changes": [...], "warnings": [...] }`.
185
224
 
186
225
  Run `--check` in merge request pipelines and `apply` on the main branch: