Per-project Nginx config
By default, Valet generates the Nginx server block of every site for you. When a project needs something different — custom location rules, a front controller other than Valet's server.php, extra headers, bigger upload limits, WebSocket proxying — you can publish the config into the project, edit it, and activate it. From then on Valet renders your config for that site.
The config lives inside the project, at:
<project>/nginx/<site>.<tld>.conf
for example ~/sites/myapp/nginx/myapp.test.conf. It uses Valet placeholders instead of hard-coded paths, so you can commit it and it works on any machine running Valet Linux+.
Quick start
cd ~/sites/myapp # a parked or linked site
valet nginx:publish # writes nginx/myapp.test.conf from Valet's default config
# edit nginx/myapp.test.conf
valet nginx # validates and activates it
Changed the file again? Run valet nginx again to apply the changes. Want Valet's default back?
valet nginx:reset
Commands
| Command | Description |
|---|---|
valet nginx:publish [site] [--force] |
Publish Valet's default Nginx config of the site into <project>/nginx/<site>.<tld>.conf. |
valet nginx [site] |
Activate (or re-apply) the project config of the site. |
valet nginx:reset [site] |
Deactivate the project config and restore Valet's default config. The project file is kept. |
All commands accept the site name, with or without the TLD (myapp or myapp.test). When omitted, the site of the current directory is used. The site must be served by Valet (parked or linked).
valet nginx:publish
Copies the Valet stub that matches the current state of the site:
| Site state | Published stub |
|---|---|
| Plain HTTP | site.valet.conf |
Secured (valet secure) |
secure.valet.conf |
Isolated (valet isolate) |
isolated.valet.conf |
| Secured and isolated | secure.isolated.valet.conf |
Tip
Secure and/or isolate the site before publishing, so the published file already contains the TLS and PHP-FPM blocks you need.
If the file already exists, Valet refuses to overwrite it. Use --force to replace it with a fresh copy.
valet nginx
- Renders the project file, replacing the placeholders with the values of your machine.
- Writes the result to Valet's site config (
~/.config/valet/Nginx/<site>.<tld>). - Validates the whole Nginx configuration with
nginx -t. - Restarts Nginx.
If nginx -t fails, the change is rolled back: the previous site config is restored, the site is not marked as customized and the Nginx error is printed, so a typo never takes your sites down.
valet nginx:reset
Removes the customization and regenerates Valet's default config for the site, keeping the current state (secured and/or isolated). The file inside the project is not deleted, so you can activate it again later with valet nginx.
Placeholders
Use these placeholders in the project file; Valet replaces them every time it renders the config:
| Placeholder | Value |
|---|---|
VALET_SITE |
Site domain, e.g. myapp.test |
VALET_PROJECT_PATH |
Project root |
VALET_HOME_PATH |
~/.config/valet |
VALET_SERVER_PATH |
Valet's server.php (the front controller that runs Valet drivers) |
VALET_STATIC_PREFIX |
Internal prefix Valet uses to serve static files |
VALET_CERT / VALET_KEY |
TLS certificate and key of the site (the site must be secured) |
VALET_FPM_SOCKET_FILE |
PHP-FPM socket — of the isolated version when the site is isolated, otherwise of the global version |
VALET_ISOLATED_PHP_VERSION |
PHP version used by the site |
VALET_HTTP_PORT / VALET_HTTPS_PORT |
Configured HTTP and HTTPS ports (valet port) |
VALET_REDIRECT_PORT |
:port when the HTTPS port is not 443, otherwise empty — used in HTTP → HTTPS redirects |
Warning
A file that uses VALET_CERT or VALET_KEY requires the site to be secured. If it is not, valet nginx fails with "uses TLS certificates, but the site is not secured. Run valet secure first."
Your config survives Valet commands
Once activated, the project config is re-rendered automatically whenever Valet regenerates the site config:
| Command | What happens to the custom config |
|---|---|
valet secure / valet unsecure |
Re-rendered with the new certificate state |
valet isolate / valet unisolate |
Re-rendered with the new PHP-FPM socket and version |
valet port |
Re-rendered with the new ports (secured sites) |
valet domain |
See Changing the domain |
For any other change that affects the placeholders — valet port on a non-secured site, valet use on a non-isolated site, or after valet install — run valet nginx again to re-render the config with the current values.
If a re-render fails (for example, you ran valet unsecure on a site whose file uses VALET_CERT), the Valet command still succeeds: Valet keeps its default config for the site and prints a warning. Fix the file (or secure the site again) and run valet nginx.
Note
The generated file in ~/.config/valet/Nginx starts with a # Generated from … header. Do not edit it directly — it is overwritten on the next render. Always edit the file inside the project and run valet nginx.
Changing the domain
The project file name includes the TLD (myapp.test.conf). The activation itself survives valet domain, but after changing the domain Valet looks for a file with the new TLD. Rename it and re-apply:
valet domain local
mv nginx/myapp.test.conf nginx/myapp.local.conf
valet nginx
Keep the file free of hard-coded domains — use VALET_SITE — so renaming is all it takes.
Examples
Serving the project front controller directly
Serve the project's index.php directly instead of going through Valet's server.php and drivers (replace root, location / and location ~ \.php$ in the published file):
root VALET_PROJECT_PATH;
index index.php;
location / {
try_files $uri $uri/ /index.php?route=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass "unix:VALET_FPM_SOCKET_FILE";
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Larger uploads
Inside the server block:
client_max_body_size 512M;
Proxying a WebSocket server
location /app {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Versioning the config
Commit the nginx/ directory. Teammates using Valet Linux+ only need to run:
valet link # or keep the project inside a parked directory
valet secure # if the file uses VALET_CERT / VALET_KEY
valet nginx
Troubleshooting
| Message | Cause | Fix |
|---|---|---|
[…] already exists. Use --force to overwrite it. |
nginx:publish found an existing project file |
Edit the existing file, or publish again with --force |
No project config found at […]. Run valet nginx:publish first. |
valet nginx did not find nginx/<site>.<tld>.conf |
Publish it, or check the file name (it includes the TLD) |
The […] site could not be found in Valet's site list. |
The directory is not parked or linked | Run valet link or valet park |
Nginx config test failed, changes were rolled back: … |
The file has an Nginx syntax or semantic error | Fix the error shown and run valet nginx again |
… uses TLS certificates, but the site is not secured. |
The file uses VALET_CERT/VALET_KEY on an HTTP site |
Run valet secure, then valet nginx |