Wiring an LLM into a Laravel app is less work than most people expect. The [openai-php/laravel](https://github.com/openai-php/laravel) package gives you a typed client and a facade, so calling the chat endpoint is a single method call. Here's a clean setup, from installing the client to streaming responses and keeping your key safe. ## Install the client Pull in the package with Composer: ```bash…
AI crawlers now make up a real slice of traffic. Some scrape pages in bulk to train models, others fetch a single page in real time because someone asked an assistant about it. Either way, you can see exactly who's visiting — they announce themselves in the `User-Agent` header. Here's how to track them. ## Know the user agents The major AI companies publish and respect their crawler names. The…
## About the 429 error `429 Too Many Requests` is the OpenAI API telling you it's refusing a request because you've gone over a limit. It's the AI-API equivalent of any other HTTP rate-limit response — the request was well-formed, the server just won't process it right now. There are two very different causes hiding behind the same status code, and fixing the wrong one wastes time. ## Why do I see…
Sending every prompt to a hosted API is the easy path, but it has two costs: your data leaves your network, and the per-token bill grows with usage. Self-hosting flips both. The model runs on hardware you control, nothing leaves your perimeter, and your spend is a fixed monthly server cost instead of a meter that never stops. Here's how to do it properly. ## Size the machine The single most…
DeepSeek releases its models as open weights, which means you can download DeepSeek-R1 and run it entirely on your own hardware. No account, no API key, no per-token bill, and your prompts never leave the machine. The easiest way to do it is with [Ollama](/run-a-local-llm-with-ollama), which handles the download and serves the model over HTTP. ## Install Ollama If you don't already have it,…
[Ollama](https://ollama.com) packages an open large language model, its weights, and a small HTTP server into a single command. You download a model once and run it entirely on your own hardware, which means no API keys, no rate limits, and no data leaving your machine. It's the fastest path from "I want to try an LLM" to a working prompt. ## Install Ollama On Linux the one-line installer sets up…
[Cloudflare](/providers/cloudflare) is a service that sits in front of your website. Instead of visitors connecting straight to your server, their requests go to Cloudflare first, and Cloudflare decides what to serve from its own global network and what to forward to you. That one change — putting a smart layer between the internet and your origin server — is what makes everything else it offers…
"Just get a server and put your site on it" hides a surprising amount of work. A fresh Ubuntu box is a blank machine: no web server, no PHP, no database, no certificate, no firewall, no backups. Turning it into something you'd trust with real traffic is a sequence of steps, each with its own pitfalls. This is the whole map, in order, so you can see what hosting your own site actually involves —…
You can't fix what you can't see. After you've [set up a server](/how-to-host-your-own-website) and put a site live, these free tools grade the things that matter — TLS, security headers, performance, and markup — and tell you exactly what to improve. Run them at launch, then again whenever you make a significant change. ## SSL and TLS ### SSL Labs Server Test The gold standard for inspecting your…
Not every site upgrades on the same schedule. One app needs PHP 8.4, an older one is stuck on 8.2, and they both live on the same server. The good news: PHP-FPM runs a separate service and socket per version, so you can install as many as you like and route each site to the right one. ## Install the versions you need With the [ondrej/php PPA](/how-to-install-php) added, install each version's FPM…
A trusted SSL certificate is no longer optional — without one every visitor gets a [your connection is not private](/your-connection-is-not-private) warning, and browsers refuse to load the page. [Certbot](https://certbot.eff.org) is the official client for [Let's Encrypt](https://letsencrypt.org), which hands out free certificates that every browser trusts. The catch is that those certificates…
[Nginx](https://nginx.org) is the piece that listens on ports 80 and 443, terminates TLS, serves your static files, and passes everything else to [PHP-FPM](/how-to-install-php) or your application. It's fast, lightweight, and runs the majority of the busy sites on the web. Here's how to get it running on a fresh Ubuntu server. ## Install Nginx The quickest route is the package in Ubuntu's own…
Even a PHP application usually needs Node.js — to compile CSS, bundle JavaScript with Vite or webpack, and run the asset build step during [deployment](/zero-downtime-php-deployments). The cleanest way to install it is [nvm](https://github.com/nvm-sh/nvm), the Node Version Manager, which keeps Node in your home directory so different projects can run different versions without `sudo`. ## Install…
Launching a website is the moment a dozen small details suddenly matter all at once. This checklist walks through what to verify before you flip the switch, grouped so you can work through it top to bottom. Most items link to a full guide if you need the how. ## Server and access - [ ] Server provisioned with [Nginx](/how-to-install-nginx), [PHP](/how-to-install-php), and a…
Strictly speaking, you don't *need* Cloudflare. Plenty of sites run fine without it. But for a free service it delivers an unusual amount, and there are situations where it turns a hard problem into a non-issue. Here's an honest look at why you'd want it — and when you might not. If you're new to what it actually is, start with [what is Cloudflare](/what-is-cloudflare). ## The case for using it…
Ubuntu ships MySQL in its repositories, but it's often an older release. To run a current, supported MySQL, install it from MySQL's own apt repository. Here's the full path from a fresh server to a database your application can connect to. ## Add the official MySQL repository Import MySQL's signing key and add the repository for the current LTS release: ```bash sudo apt-get install -y dirmngr…
A [Let's Encrypt](https://letsencrypt.org) certificate is valid for 90 days. That short lifetime is deliberate — it forces automation, so a forgotten certificate can never linger and become a problem. The flip side is that renewal is not optional: if it isn't automatic, your site eventually goes dark with a [your connection is not private](/your-connection-is-not-private) warning. Here's how to…
Ubuntu's default repositories are usually a PHP version or two behind, and they don't always carry every extension you'll need. The standard fix is Ondřej Surý's PPA, which packages every current PHP release for Ubuntu and keeps them up to date. Here's how to install PHP properly for a web server. ## Add the PHP repository Add the PPA that almost every production PHP server uses: ```bash sudo…
After you [install PHP](/how-to-install-php), it works — but the defaults in `php.ini` are conservative placeholders, not production values. A handful of settings make the difference between a site that runs smoothly and one that throws cryptic errors under load. Here are the ones worth knowing. ## Find your php.ini There's a separate `php.ini` per version and per SAPI (CLI vs FPM). Ask PHP where…
## About the error The browser shows `ERR_TOO_MANY_REDIRECTS` (Chrome) or "The page isn't redirecting properly" (Firefox). It means a URL redirected to another URL that redirected back, forming a loop. After a handful of hops the browser stops to avoid looping forever. ## Why do I see this error The overwhelmingly common cause is an **HTTP ↔ HTTPS loop**, and the most common trigger of that is…
## About the error Chrome shows `NET::ERR_CERT_AUTHORITY_INVALID` behind a "Your connection is not private" warning. The browser received a certificate it can't trace back to a Certificate Authority it trusts, so it refuses to proceed. ## Why do I see this error - A **[self-signed certificate](/generate-self-signed-certificate-openssl)** (common in local dev and on staging). - A **missing…
## Why you need to know your Ubuntu version Before I install a package, follow a tutorial, or open a support ticket, I want to know exactly which Ubuntu release I'm on. The version decides which package versions are available, which docs apply, and whether a release is still getting security updates. Here are the commands I reach for. ## The quickest answer: lsb_release My go-to is `lsb_release`,…
## Why is the page expired? Laravel uses Cross-Site Request Forgery (CSRF) as a protection mechanism, that protects your app from external HTTP requests to your application. Requests from the outside cannot always be trusted, because they can try to mingle with the data and sessions of your users. CSRF works by generating a unique and randomly generated token that only your application knows and…
## Why you'd want this Linux schedules CPU time using a **nice value** between `-20` (highest priority) and `19` (lowest). By default processes start at `0`. If your server is dedicated to queue processing or you're handling time-sensitive, CPU-intensive jobs, lowering the nice value gives workers a bigger slice of CPU time. On a shared server running web traffic alongside workers, you'd leave it…
## About error 403 A `403 Forbidden` is returned when nginx successfully locates the request but is not allowed to serve it. Unlike a 404, the resource exists, nginx just won't hand it over. ## Why do I see this error The usual causes, in rough order of likelihood: - File or directory permissions the nginx worker user can't read or traverse. - The URL points at a directory with no index file and…
OPcache is one of the biggest speedups available to a PHP app, and it costs you almost nothing to turn on. Every time PHP runs a script it normally reads the file, parses it, and compiles it to bytecode before executing. OPcache stores that compiled bytecode in shared memory, so subsequent requests skip the parse-and-compile step entirely. On a typical Laravel or WordPress app that alone can cut…
Caching is the cheapest performance win you have after indexing. The Laravel cache wraps file, database, Redis, and memcached behind a single `Cache` facade, so you write the same code regardless of where the data lives. This guide covers the drivers, the day-to-day API, cache tags, and how application caching differs from data caching. ## What the Laravel cache is for Laravel caching stores the…
## Talking to APIs from the terminal When I'm building or debugging an API, `curl` is the first tool I reach for. It lets me fire requests straight from the terminal without opening a browser or a GUI client. Here's how I use it day to day. For the full reference, see my [complete curl guide](/curl-command-complete-guide). ## GET requests A GET request is the default, so you only need the URL:…
## Stashing your changes `git stash` takes your modified tracked files, saves them away, and gives you a clean working directory: ```bash git stash ``` By default it does **not** include untracked files. Add `-u` to stash those too: ```bash git stash -u ``` Give a stash a label so you can recognise it later: ```bash git stash push -m "half-finished login form" ``` ## pop vs apply Both bring your…
## About the error Starting a server fails with one of these: ```bash bind() to 0.0.0.0:80 failed (98: Address already in use) # nginx Error: listen EADDRINUSE: address already in use :::3000 # Node [ERROR] Can't start server: Bind on TCP/IP port: Address already in use # MySQL ``` Only one process can listen on a given port at a time. The bind fails because something already holds it. ## Why do I…
## What npm install does `npm install` is the everyday command for adding and updating dependencies: ```bash npm install npm install lodash # add a package ``` It reads `package.json`, resolves versions, installs them, and **writes** the result to `package-lock.json`. (npm ships with Node itself, see [how to install Node.js](/how-to-install-nodejs) if it's missing on a server.) If a dependency…
## What a CSR contains A Certificate Signing Request bundles the details of the certificate you want — your domain name and organisation info — and your **public** key, all signed by your **private** key. The CA uses it to issue a certificate. The private key it's generated alongside stays with you and is never sent to the CA. ## Generate a private key and CSR This single command creates a new…
## Delete a local branch Use `-d` (lowercase) to delete a branch that has already been merged. Git refuses if the branch has unmerged commits, which protects you from losing work: ```bash git branch -d feature-login ``` If you are sure you want to discard the branch even though it is not merged, force it with `-D`: ```bash git branch -D feature-login ``` You cannot delete the branch you are…
## About the error In the browser console you see something like: ```bash Access to fetch at 'https://api.example.com/users' from origin 'https://app.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ``` CORS (Cross-Origin Resource Sharing) is a browser security mechanism. When your frontend on one origin calls an API on…
## About the error The full message is: ```bash RuntimeException: No application encryption key has been specified. ``` Laravel uses the `APP_KEY` to encrypt cookies, sessions and anything you pass through the `Crypt` facade. Without it, the framework refuses to boot rather than fall back to no encryption. ## Why do I see this error The `APP_KEY` value in your `.env` is empty or missing. This…
## About the error You'll hit one of these: ```bash ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes ERROR 2006 (HY000): MySQL server has gone away ``` When a client or the server receives a single packet larger than `max_allowed_packet`, it rejects it and drops the connection, which often surfaces as the misleading "server has gone away" message. ## Why do I see this error…
When a query gets slow, the cause is almost always a missing index. Indexing is the highest-impact thing you can do for database performance, yet it stays a little mysterious. This guide explains what an index is, how it speeds up reads, and how to add and verify indexes in MySQL. ## What is a database index An index is a separate, sorted data structure that lets the database find rows without…
## About the error The message reads: ```bash curl: (60) SSL certificate problem: unable to get local issuer certificate ``` curl connected over TLS but couldn't build a trust chain from the server's certificate up to a root certificate it knows. To verify a certificate, curl needs the issuing CA certificates available locally. If it can't find them, it errors out rather than trusting blindly. ##…
## Why the command line is worth it If you write code or touch a server, the terminal is unavoidable, and honestly that's a good thing. It's faster than clicking, it's scriptable, and it's the same on your laptop and on a remote box. This is the set of commands I'd hand a new developer to get comfortable. Everything here works on Ubuntu and macOS alike. ## Knowing where you are and moving around…
## How SSH keys work An SSH key comes as a **pair**: a private key and a public key. They are generated together and are mathematically linked. - The **private key** stays on your computer and is never shared. Treat it like a password. - The **public key** is copied to any server or service you want to access. When you connect, the server uses your public key to issue a challenge that only the…
## About the error The page returns a 500 and the nginx error log shows: ```bash rewrite or internal redirection cycle while internally redirecting to "/index.php" ``` nginx tried to resolve a request, that resolution pointed at another location, which pointed back, and so on. After 10 internal redirects nginx assumes a loop and aborts with a 500. ## Why do I see this error The classic cause is a…
## Start your services Run from the directory containing your `compose.yaml` (or `docker-compose.yml`): ```bash docker compose up ``` This creates and starts every service defined in the file, and streams their logs to your terminal. Press `Ctrl+C` to stop them. ## Run in the background Most of the time you want the stack running detached, so your terminal is free: ```bash docker compose up -d ```…
## Searching inside files with grep While [find](/find-files-linux-command) locates files by their name or metadata, `grep` searches what's *inside* them. It scans for lines matching a pattern and prints them. The basic form is `grep 'pattern' file`: ```bash grep 'database' config/app.php ``` ## Search recursively To search every file under a directory, add `-r` (recursive). This is the one I use…
## About the error The visitor sees `ERR_SSL_PROTOCOL_ERROR` or "SSL handshake failed", and nginx logs an SSL error. The handshake is the negotiation that happens before any data is exchanged, if it fails, the page never loads over HTTPS. ## Why do I see this error In production, almost always one of these: - **Expired certificate**, the single most common cause. - **Missing intermediate…
## About the error Unlike most errors, this one is quiet. The upload just doesn't arrive, `$_FILES` is empty, or you see `UPLOAD_ERR_INI_SIZE` in the file's `error` key. PHP discarded the file before your code ever ran. This is distinct from, but often confused with, the [413 Request Entity Too Large](/413-request-entity-too-large) error. That one is nginx rejecting the request before it reaches…
## About the error ```bash Predis\Connection\ConnectionException: Connection refused [tcp://127.0.0.1:6379] ``` (Or the phpredis equivalent.) Laravel tried to open a connection to Redis and nothing accepted it at that address. This is different from an authentication or wrong-database error, the connection never got established at all. ## Why do I see this error - Redis isn't running. -…
## About the error Running `php artisan migrate` on a fresh install against older MySQL throws: ```bash SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes ``` It almost always fails on the `users` table when creating a unique index on the email or another `VARCHAR(255)` column. ## Why do I see this error Laravel defaults to the `utf8mb4`…
## What curl is `curl` is the Swiss Army knife for talking to anything over a URL from your terminal. HTTP, HTTPS, FTP, and more. I reach for it constantly: testing an API, downloading a file, checking what headers a server returns, debugging a redirect. It's installed by default on macOS and almost every Linux distro. This guide is the reference I wish I'd had when I started. ## The basic GET…
## About error 504 A `504 Gateway Timeout` is returned when nginx, acting as a reverse proxy, successfully connects to the upstream server but does not receive a complete response within the configured timeout window. This is the key difference with a [502 Bad Gateway](/502-bad-gateway-nginx): with a 502 the backend gave a bad or no connection, with a 504 the connection was fine but the response…
## About the error Chrome shows a full-page "Your connection is not private" warning with a code such as `NET::ERR_CERT_*`. The browser couldn't validate the site's SSL certificate, so it blocks access to protect the visitor. If it's your own site, it means visitors are being turned away, so it's worth fixing fast. ## Why do I see this error The specific code under the warning tells you which…