Valet Linux+

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

bash
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?

bash
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

  1. Renders the project file, replacing the placeholders with the values of your machine.
  2. Writes the result to Valet's site config (~/.config/valet/Nginx/<site>.<tld>).
  3. Validates the whole Nginx configuration with nginx -t.
  4. 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:

bash
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):

nginx
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:

nginx
client_max_body_size 512M;

Proxying a WebSocket server

nginx
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:

bash
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