> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instapods.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP

> PHP preset with nginx, PHP-FPM, and Composer. Versions 8.2, 8.3 (default), and 8.4 available.

The PHP preset provides a full PHP development environment with nginx, PHP-FPM, and Composer pre-installed.

## Available Versions

| Version | Status |
| - | - |
| **PHP 8.2** | Supported |
| **PHP 8.3** | Default |
| **PHP 8.4** | Latest |

Select a version when creating your pod. If not specified, PHP 8.3 is used.

```bash theme={null}
instapods pods create my-app -p php --version 8.4
```

## What's Included

| Component | Version | Details |
| - | - | - |
| **nginx** | Latest (Ubuntu 24.04) | Web server, proxies to PHP-FPM |
| **PHP-FPM** | 8.2, 8.3, or 8.4 (your choice) | FastCGI process manager |
| **Composer** | Latest | PHP dependency manager (global) |
| **git** | Latest | Version control |
| **SSH** | OpenSSH | Access via dedicated port |

**Pre-installed PHP extensions**: mbstring, xml, curl, mysql, pgsql, redis, zip, gd, intl, opcache.

Need one that isn't listed? Install it yourself over SSH — `sudo apt-get install -y php8.3-<ext> && sudo systemctl restart php8.3-fpm`.

Pre-installed utilities: curl, wget, vim, htop, unzip.

## Directory Structure

```
/home/instapod/app/
├── public/
│   └── index.php       # Web-accessible entry point
├── composer.json        # (your project)
└── vendor/              # (after composer install)
```

* **App Root**: `/home/instapod/app`
* **Public Root**: `/home/instapod/app` until a `public/index.php` exists, then `/home/instapod/app/public`
* **Port**: 80 (nginx)
* **PHP-FPM socket**: `/run/php/php8.3-fpm.sock`

<Warning>
  **A fresh pod serves the project root, not `public/`.** That's so a single-file `index.php`
  works with no setup. The web root moves down to `/home/instapod/app/public` the next time the
  pod reloads *after* a `public/index.php` is present - which is what a Laravel or Symfony deploy
  produces. Until that switch happens, everything beside your entry point - `composer.json`,
  `vendor/`, an uploaded `.sql` dump - is served on your public URL.

  So put your framework's entry point in `public/` and [reload](#reload-services), and keep
  secrets out of the app root either way. Dot-files (`/.env`, `/.git/`) are always refused with a
  `403` (see
  [`.env` is not reachable from the web](/guides/environment-variables#env-is-not-reachable-from-the-web)),
  but nothing else is filtered for you.
</Warning>

## Deploying Your App

### Upload Files

```bash theme={null}
instapods files sync my-php-app --local ./my-laravel-project

# Or use the deploy command
instapods deploy my-php-app --local ./my-laravel-project
```

### Install Dependencies

```bash theme={null}
instapods exec my-php-app -- composer install --no-dev
```

### Reload Services

After deploying or updating your code:

```bash theme={null}
instapods pods reload my-php-app
```

This restarts both PHP-FPM and nginx.

## Routing

The nginx config includes `try_files $uri $uri/ /index.php?$query_string`, which means all requests that don't match a file are forwarded to `index.php`. This works out of the box for:

* **Laravel** — all routes handled by `public/index.php`
* **Custom routers** — write your own front controller in `public/index.php`

## File Permissions

PHP-FPM runs as the `www-data` user. Files uploaded via the CLI or IDE are owned by `root`. If your PHP app needs to **write** to data directories (file uploads, JSON storage, cache), you must fix permissions:

```bash theme={null}
instapods exec my-php-app -- chown -R www-data:www-data /home/instapod/app/data
```

For Laravel, also set writable permissions on `storage` and `bootstrap/cache`:

```bash theme={null}
instapods exec my-php-app -- chown -R www-data:www-data /home/instapod/app/storage /home/instapod/app/bootstrap/cache
```

## Adding a Database

PHP apps commonly need a database. Install one with:

```bash theme={null}
# MySQL
instapods services add my-php-app -s mysql -w
instapods services creds my-php-app -s mysql

# PostgreSQL
instapods services add my-php-app -s postgresql -w
```

<Note>
  Database services require the Build plan or higher.
</Note>

## Use Cases

* Laravel applications
* Custom PHP APIs and REST services
* Content management systems
* PHP microservices


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.