Skip to content
Merged
100 changes: 52 additions & 48 deletions content/doc/applications/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,62 +34,55 @@

Docker containers can encapsulate any payload, and will run consistently on and between virtually any server. The same container that a developer builds and tests on a laptop will run at scale, in production, on VMs, bare-metal servers, public instances, or combinations of the above.

Clever Cloud allows you to deploy any application running inside a Docker container. This page will explain how to set up your application to run it on our service.
Clever Cloud allows you to deploy any application running inside a Docker container. This page explains how to set up your application to run it on our service.

Check warning on line 37 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L37

[Google.We] Try to avoid using first-person plural like 'our'.
Raw output
{"message": "[Google.We] Try to avoid using first-person plural like 'our'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 37, "column": 149}}}, "severity": "WARNING"}

{{< callout type="info" >}}
Clever Cloud supports many languages, but some users have specific application needs. With Docker, they can create custom stacks without relying on Clever Cloud's specific support.
{{< /callout >}}
> [!NOTE]
> Clever Cloud supports many languages, but some users have specific application needs. With Docker, they can create custom stacks without relying on Clever Cloud's specific support.

{{< callout type="warning" >}}
[FS Buckets](/doc/best-practices/cloud-storage/#what-is-fs-bucket) access, Dockerfile validation, and Docker Compose functionalities are not supported.
{{< /callout >}}
> [!WARNING]
> [FS Buckets](/doc/best-practices/cloud-storage/#what-is-fs-bucket) access, Dockerfile validation, and Docker Compose functionalities are not supported.

Check notice on line 43 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L43

[Google.Contractions] Use 'aren't' instead of 'are not'.
Raw output
{"message": "[Google.Contractions] Use 'aren't' instead of 'are not'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 43, "column": 136}}}, "severity": "INFO"}

### How it works

When you create a Docker application on Clever Cloud, the deployment process involves the following steps:

1. **Install/Login:**
- The system checks for a Dockerfile and an entrypoint.
- It logs into the docker registry that you configured in the Dockerfile, if any, to find the necessary image (**note:** the name of the Docker registry may vary depending on the provider. It's called "container registry" in GitHub, for instance)
2. **Build:**
- The application pulls the specified image and execute commands you specified in Dockerfile.
- **Note:** This step focuses on executing commands in your Dockerfile and doesn't require build instructions if you are using a pre-compiled image.
3. **Run:**
- The application starts in a Docker container and exposes the service on port 8080 by default.
- If you need to expose your application on a different port, you can specify this using the environment variable `CC_DOCKER_EXPOSED_HTTP_PORT`.
1. **Login:** The system checks for a Dockerfile and logs into the Docker registry you configured, if any, to find the necessary image.
2. **Build:** The application pulls the specified image and executes the commands specified in your Dockerfile.
3. **Run:** The application starts in a Docker container and exposes the service on port 8080 by default.

{{% content "set-env-vars" %}}
{{% content "set-env-vars" %}}

## Configure your Docker application

### Mandatory configuration

Be sure that you:

* push on the **master branch**.
* have and commit a file named **Dockerfile** or use the **CC_DOCKERFILE** [environment variable](/doc/reference/reference-environment-variables#docker) if your Dockerfile has a different name, [Here is what it will look like](https://docs.docker.com/develop/develop-images/dockerfile_best-practices "Dockerfile").
* run the application with `CMD` or `ENTRYPOINT` in your Dockerfile.
* listen on HTTP **port 8080** by default (you can set your own port using `CC_DOCKER_EXPOSED_HTTP_PORT=<port>` environment variable).
- Have and commit a file named **Dockerfile**, or use the `CC_DOCKERFILE` [environment variable](/doc/reference/reference-environment-variables#docker) if your Dockerfile has a different name. [Here is what it will look like](https://docs.docker.com/develop/develop-images/dockerfile_best-practices "Dockerfile").

Check warning on line 61 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L61

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 61, "column": 211}}}, "severity": "WARNING"}
- Run the application with `CMD` or `ENTRYPOINT` in your Dockerfile.
- Listen on HTTP **port 8080** by default (you can set your own port using `CC_DOCKER_EXPOSED_HTTP_PORT`).
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of the "push on the master branch" requirement is appropriate as modern Git workflows may use different default branch names (main, etc.). However, ensure that the deployment documentation elsewhere clearly explains which branch is used for deployment, or that the platform automatically detects the default branch.

Suggested change
- Listen on HTTP **port 8080** by default (you can set your own port using `CC_DOCKER_EXPOSED_HTTP_PORT`).
- Listen on HTTP **port 8080** by default (you can set your own port using `CC_DOCKER_EXPOSED_HTTP_PORT`).
- Configure which Git branch triggers deployments in your Clever Cloud application settings. By default, deployments use your repository default branch, for example `main` or `master`.

Copilot uses AI. Check for mistakes.

- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/)

### Dockerfile contents

You can virtually put everything you want in your Dockerfile. The only mandatory (for us) instruction to put in it is:
You can virtually put everything you want in your Dockerfile. The only mandatory instruction is:

```bash
```dockerfile
CMD <command to run>
```

**command to run**: this is the command that starts your application. Your application **must** listen on port 8080. It can be easier for you to put a script in your docker image and call it with the CMD instruction.
**command to run**: this is the command that starts your application. Your application **must** listen on the port defined by `CC_DOCKER_EXPOSED_HTTP_PORT` (default: `8080`). It can be easier for you to put a script in your Docker image and call it with the CMD instruction.

Check notice on line 75 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L75

[Google.Acronyms] Spell out 'CMD', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'CMD', if it's unfamiliar to the audience.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 75, "column": 259}}}, "severity": "INFO"}

### Docker Buildx

We still use `docker build` command for legacy reasons, but you can use `docker buildx` instead, setting `CC_DOCKER_BUILDX` to `true`.
The default build uses `docker build` with BuildKit disabled. To use Docker Buildx instead, set `CC_DOCKER_BUILDX` to `true`. Buildx uses the `--load` flag to make the image available locally.

Check warning on line 79 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L79

[Google.WordList] Use 'turn off' or 'off' instead of 'disabled'.
Raw output
{"message": "[Google.WordList] Use 'turn off' or 'off' instead of 'disabled'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 79, "column": 53}}}, "severity": "WARNING"}

Check failure on line 79 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L79

[Vale.Spelling] Did you really mean 'Buildx'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Buildx'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 79, "column": 77}}}, "severity": "ERROR"}

Check failure on line 79 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L79

[Vale.Spelling] Did you really mean 'Buildx'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Buildx'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 79, "column": 127}}}, "severity": "ERROR"}

### Memory usage during building
### Memory management

If the building step of your app crashes because it uses more memory that it's available, you'll have to split the building and running steps and enable [Dedicated build instance](/doc/administrate/apps-management#edit-application-configuration)
The Docker container runs with a memory limit equal to the instance's available memory, with swap disabled. If the building step of your application crashes due to memory usage, split the building and running steps and enable [Dedicated build instance](/doc/administrate/apps-management#edit-application-configuration):

Check warning on line 83 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L83

[Google.WordList] Use 'turn off' or 'off' instead of 'disabled'.
Raw output
{"message": "[Google.WordList] Use 'turn off' or 'off' instead of 'disabled'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 83, "column": 99}}}, "severity": "WARNING"}

```bash
```dockerfile
# The base image
FROM outlinewiki/outline:version-0.44.0

Expand All @@ -102,48 +95,59 @@

### Login to registry

As Docker Hub limits the number of image pulls and actions without authentication, use you own account to get higher limits. You can also use a private registry where you store your images. This feature launch `docker login` command before the build phase.
As Docker Hub limits the number of image pulls without authentication, use your own account to get higher limits. You can also use a private registry where you store your images. This runs `docker login` before the build phase.

- `CC_DOCKER_LOGIN_USERNAME`: the username to use
- `CC_DOCKER_LOGIN_PASSWORD`: the password for your username
- `CC_DOCKER_LOGIN_SERVER` (optional): the server of your private registry, default is Docker Hub

> [!NOTE]
> The name of the Docker registry may vary depending on the provider (e.g. "container registry" in GitHub). If login fails, the build continues without authentication.

Check failure on line 105 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L105

[Google.Latin] Use 'for example' instead of 'e.g.'.
Raw output
{"message": "[Google.Latin] Use 'for example' instead of 'e.g.'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 105, "column": 71}}}, "severity": "ERROR"}

### Network mode

* `CC_DOCKER_LOGIN_USERNAME`: the username to use to login
* `CC_DOCKER_LOGIN_PASSWORD`: the password of your username
* `CC_DOCKER_LOGIN_SERVER` (optional): the server of your private registry, default is Docker Hub
When using default ports (`CC_DOCKER_EXPOSED_HTTP_PORT=8080` and `CC_DOCKER_EXPOSED_TCP_PORT=4040`), the container runs with `--net host` for direct network access. When custom ports are specified, Docker's port mapping is used instead (`-p 8080:<your_http_port> -p 4040:<your_tcp_port>`).

Check notice on line 109 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L109

[Google.Passive] In general, use active voice instead of passive voice ('are specified').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are specified').", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 109, "column": 184}}}, "severity": "INFO"}

Check failure on line 109 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L109

[Vale.Spelling] Did you really mean 'Docker's'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Docker's'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 109, "column": 199}}}, "severity": "ERROR"}

Check notice on line 109 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L109

[Google.Passive] In general, use active voice instead of passive voice ('is used').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is used').", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 109, "column": 221}}}, "severity": "INFO"}

### TCP support

Clever Cloud enables you to use TCP over Docker applications using the environment variable `CC_DOCKER_EXPOSED_TCP_PORT=<port>`.
Clever Cloud enables you to use TCP over Docker applications using the environment variable `CC_DOCKER_EXPOSED_TCP_PORT` (default: `4040`).

* [Learn more about TCP redirections](/doc/administrate/tcp-redirections)
- [Learn more about TCP redirections](/doc/administrate/tcp-redirections)

### Docker socket access

Some containers require access to the docker socket, to spawn sibling containers for instance.
Some containers require access to the Docker socket, to spawn sibling containers for instance.

{{< callout type="warning" >}}
Giving access to the docker socket breaks all isolation provided by docker. **DO NOT** give socket access to untrusted code.
{{< /callout >}}
> [!WARNING]
> Giving access to the Docker socket breaks all isolation provided by Docker. **DO NOT** give socket access to untrusted code.

Check notice on line 122 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L122

[Google.Contractions] Use 'don't' instead of 'DO NOT'.
Raw output
{"message": "[Google.Contractions] Use 'don't' instead of 'DO NOT'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 122, "column": 81}}}, "severity": "INFO"}

Check notice on line 122 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L122

[Google.Acronyms] Spell out 'NOT', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'NOT', if it's unfamiliar to the audience.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 122, "column": 84}}}, "severity": "INFO"}

Check failure on line 122 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L122

[Vale.Spelling] Did you really mean 'untrusted'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'untrusted'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 122, "column": 112}}}, "severity": "ERROR"}

You can make the docker socket available from inside the container by adding the `CC_MOUNT_DOCKER_SOCKET=true` environment variable. In that case, docker is started in the namespaced mode, and in bridge network mode.
You can make the Docker socket available from inside the container by adding the `CC_MOUNT_DOCKER_SOCKET=true` environment variable. In that case, Docker is started in the namespaced mode (user namespace remapping), and the container uses port mapping instead of host network mode.

Check notice on line 124 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L124

[Google.Passive] In general, use active voice instead of passive voice ('is started').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is started').", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 124, "column": 155}}}, "severity": "INFO"}

Check failure on line 124 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L124

[Vale.Spelling] Did you really mean 'namespaced'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'namespaced'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 124, "column": 173}}}, "severity": "ERROR"}

### Enable IPv6 networking

You can activate the support of IPv6 with a IPv6 subnet in the docker daemon by adding the `CC_DOCKER_FIXED-CIDR-V6=<IP>` environment variable.
You can activate the support of IPv6 with an IPv6 subnet in the Docker daemon by adding the `CC_DOCKER_FIXED_CIDR_V6=<CIDR>` environment variable (e.g. `fd00::/80`).

Check failure on line 128 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L128

[Vale.Spelling] Did you really mean 'subnet'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'subnet'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 128, "column": 51}}}, "severity": "ERROR"}

Check failure on line 128 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L128

[Google.Latin] Use 'for example' instead of 'e.g.'.
Raw output
{"message": "[Google.Latin] Use 'for example' instead of 'e.g.'.", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 128, "column": 148}}}, "severity": "ERROR"}

### Build-time variables

You can use the [ARG](https://docs.docker.com/engine/reference/builder/#arg) instruction to define build-time environment variables.

Every environment variable defined for your application will be passed as a build environment variable using the `--build-arg=<ENV>` parameter during the `docker build` phase.
Every environment variable defined for your application is passed as a build environment variable using the `--build-arg` parameter during the `docker build` phase.

Check notice on line 134 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L134

[Google.Passive] In general, use active voice instead of passive voice ('is passed').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is passed').", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 134, "column": 57}}}, "severity": "INFO"}

### Sample dockerized applications
### Deployment hooks

Docker applications support all [deployment hooks](/doc/develop/build-hooks/). The `CC_PRE_BUILD_HOOK`, `CC_POST_BUILD_HOOK`, and `CC_PRE_RUN_HOOK` run on the host. The `CC_RUN_SUCCEEDED_HOOK` runs inside the container after successful start.

We provide a few examples of dockerized applications on Clever Cloud.
### Docker applications as Clever Tasks

* [Elixir App](https://github.com/CleverCloud/demo-docker-elixir/blob/master/Dockerfile)
* [Seaside / Smalltalk App](https://github.com/CleverCloud/demo-seaside)
* [Rust App](https://github.com/CleverCloud/demo-rust)
Docker containers can run as on-demand workloads on Clever Cloud. Configure an application as Tasks from the `Information` panel in [the Console](https://console.clever-cloud.com) or with [Clever Tools](/doc/cli/applications/#tasks). The container runs, executes its command, and stops.

You might need to use the `CC_DOCKERFILE = <name of your Dockerfile>` variable.
- [Learn more about Clever Tasks](/doc/develop/tasks/)

### Sample dockerized applications

Check failure on line 146 in content/doc/applications/docker.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/docker.md#L146

[Vale.Spelling] Did you really mean 'dockerized'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'dockerized'?", "location": {"path": "content/doc/applications/docker.md", "range": {"start": {"line": 146, "column": 12}}}, "severity": "ERROR"}

- [Elixir App](https://github.com/CleverCloud/demo-docker-elixir/blob/master/Dockerfile)
- [Seaside / Smalltalk App](https://github.com/CleverCloud/demo-seaside)
- [Rust App](https://github.com/CleverCloud/demo-rust)

{{% content "env-injection" %}}

Expand All @@ -153,4 +157,4 @@

{{% content "more-config" %}}

{{% content "url_healthcheck" %}}
{{% content "url_healthcheck" %}}
35 changes: 22 additions & 13 deletions content/doc/applications/frankenphp.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
```bash
clever create --type frankenphp
```
* [Learn more about Clever Tools](/doc/cli/)
* [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step)
- [Learn more about Clever Tools](/doc/cli/)
- [Learn more about Clever Cloud application deployment](/doc/quickstart/#create-an-application-step-by-step)

> [!NOTE] FrankenPHP applications can't be deployed on a pico instance, XS is the default instance type

Expand All @@ -43,19 +43,19 @@

FrankenPHP runtime only requires a working web application, with an `index.php` or `index.html` file. If you need to serve files from a specific directory, set the `CC_WEBROOT` environment variable, relative to the root of your project (default: `/`).

* [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/)
- [Learn more about environment variables on Clever Cloud](/doc/reference/reference-environment-variables/)

### FrankenPHP version and tools

FrankenPHP currently deployed version on Clever Cloud is `1.9.1` based on PHP `8.4.12` and Caddy server `2.10.2`. Virtual machine image includes multiple tools from the PHP ecosystem such as Composer or Symfony CLI.
FrankenPHP currently deployed version on Clever Cloud is `{{< runtime_version frankenphp >}}` based on PHP `{{< runtime_version frankenphp php >}}` and Caddy server `{{< runtime_version frankenphp caddy >}}`. Virtual machine image includes multiple tools from the PHP ecosystem such as Composer or Symfony CLI. The `php` command available in hooks and scripts uses `frankenphp php-cli` under the hood.

- [FrankenPHP PHP info](https://frankenphpinfo.cleverapps.io/)

### Composer native support

If a `composer.json` file is detected at the root of your project, it will be used to install dependencies during building phase with `--no-interaction --no-progress --no-scripts --no-dev` flags. To use your own, set the `CC_PHP_COMPOSER_FLAGS`environment variable.
If a `composer.json` file is detected at the root of your project, it will be used to install dependencies during building phase with `--no-interaction --no-progress --no-scripts --no-dev` flags. To override the base flags (`--no-interaction --no-progress --no-scripts`), set the `CC_PHP_COMPOSER_FLAGS` environment variable.

Check notice on line 56 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L56

[Google.Passive] In general, use active voice instead of passive voice ('is detected').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is detected').", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 56, "column": 27}}}, "severity": "INFO"}

Check warning on line 56 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L56

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 56, "column": 71}}}, "severity": "WARNING"}

Check notice on line 56 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L56

[Google.Passive] In general, use active voice instead of passive voice ('be used').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be used').", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 56, "column": 76}}}, "severity": "INFO"}

To install development dependencies, set the `CC_PHP_DEV_DEPENDENCIES` environment variable to `install`.
To install development dependencies, set the `CC_PHP_DEV_DEPENDENCIES` environment variable to `install`. This removes the `--no-dev` flag independently of `CC_PHP_COMPOSER_FLAGS`.

> [!TIP] Use a local Composer version
> If you put a `composer.phar` file at the root of your project, it will be used to install dependencies.
Expand All @@ -73,23 +73,31 @@
- [Learn more about Materia KV](/doc/addons/materia-kv)
- [Materia KV and FrankenPHP demo](https://github.com/CleverCloud/frankenphp-kv-json-example)

### Worker mode
## Worker mode

With FrankenPHP worker mode, a script of your project is kept in memory to handle incoming requests in a few milliseconds. Define the path to this script, relative to the root of your project, with the `CC_FRANKENPHP_WORKER` environment variable (e.g. `/worker/script.php`). It's supported by design by Laravel Octane and Symfony Runtime projects.
With FrankenPHP worker mode, a script of your project is kept in memory to handle incoming requests in a few milliseconds. Define the path to this script, relative to the root of your project, with the `CC_FRANKENPHP_WORKER` environment variable (e.g. `/public/worker.php`). The worker script must be located within the webroot directory. It's supported by design by Laravel Octane and Symfony Runtime projects.

Check notice on line 78 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L78

[Google.Passive] In general, use active voice instead of passive voice ('is kept').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is kept').", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 78, "column": 55}}}, "severity": "INFO"}

Check failure on line 78 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L78

[Google.Latin] Use 'for example' instead of 'e.g.'.
Raw output
{"message": "[Google.Latin] Use 'for example' instead of 'e.g.'.", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 78, "column": 248}}}, "severity": "ERROR"}

Check notice on line 78 in content/doc/applications/frankenphp.md

View workflow job for this annotation

GitHub Actions / vale

[vale] content/doc/applications/frankenphp.md#L78

[Google.Passive] In general, use active voice instead of passive voice ('be located').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be located').", "location": {"path": "content/doc/applications/frankenphp.md", "range": {"start": {"line": 78, "column": 299}}}, "severity": "INFO"}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The worker script path example changed from "/worker/script.php" to "/public/worker.php" and adds the requirement that "The worker script must be located within the webroot directory." This is a significant behavioral constraint that wasn't explicitly stated before. If this is a new requirement being introduced, it could be a breaking change for existing deployments that have worker scripts outside the webroot. Verify whether this is documenting existing behavior or introducing a new restriction.

Suggested change
With FrankenPHP worker mode, a script of your project is kept in memory to handle incoming requests in a few milliseconds. Define the path to this script, relative to the root of your project, with the `CC_FRANKENPHP_WORKER` environment variable (e.g. `/public/worker.php`). The worker script must be located within the webroot directory. It's supported by design by Laravel Octane and Symfony Runtime projects.
With FrankenPHP worker mode, a script of your project is kept in memory to handle incoming requests in a few milliseconds. Define the path to this script, relative to the webroot directory of your project (for example `public/worker.php`), with the `CC_FRANKENPHP_WORKER` environment variable. It's supported by design by Laravel Octane and Symfony Runtime projects.

Copilot uses AI. Check for mistakes.

* [Learn more about FrankenPHP worker mode](https://frankenphp.dev/docs/worker/#standalone-binary)
* [Learn more about Laravel Octane](https://laravel.com/docs/master/octane#frankenphp)
* [Learn more about Symfony Runtime](https://symfony.com/doc/current/components/runtime.html)
- [Learn more about FrankenPHP worker mode](https://frankenphp.dev/docs/worker/#standalone-binary)
- [Learn more about Laravel Octane](https://laravel.com/docs/master/octane#frankenphp)
- [Learn more about Symfony Runtime](https://symfony.com/doc/current/components/runtime.html)

## Configurable port

By default, FrankenPHP listens on port `8080`. If you want to change it, set the `CC_FRANKENPHP_PORT` environment variable to your desired port. This is useful if you want to run a service in front of FrankenPHP, such as [Redirection.io](/doc/reference/reference-environment-variables/#use-redirectionio-as-a-proxy) for example.

## Custom FrankenPHP run command

Use your own command to run your FrankenPHP application to define flags such as `--debug`, `--mercure` or `--no-compress`. To do so, set the `CC_RUN_COMMAND` environment variable, starting with `frankenphp php-server --listen 0.0.0.0:8080`.
To override the default server behavior, set the `CC_RUN_COMMAND` environment variable. When defined, it completely replaces the default `frankenphp php-server` command. Use it to define flags such as `--debug`, `--mercure` or `--no-compress`:

You can also use this to load [a custom Caddyfile](https://frankenphp.dev/docs/config/#caddyfile-config), starting `CC_RUN_COMMAND` with `frankenphp run --config /path/to/Caddyfile`.
```bash
CC_RUN_COMMAND="frankenphp php-server --listen 0.0.0.0:8080 --debug --mercure"
```

You can also use it to load [a custom Caddyfile](https://frankenphp.dev/docs/config/#caddyfile-config):

```bash
CC_RUN_COMMAND="frankenphp run --config /path/to/Caddyfile"
```

## Use FrankenPHP to execute PHP scripts as Clever Tasks

Expand All @@ -107,3 +115,4 @@
FrankenPHP on Clever Cloud comes with a set included PHP extensions: `amqp`,`apcu`,`ast`,`bcmath`,`brotli`,`bz2`,`calendar`,`ctype`,`curl`,`dba`,`dom`,`exif`,`fileinfo`,`filter`,`ftp`,`gd`,`gmp`,`gettext`,`iconv`,`igbinary`,`imagick`,`intl`,`ldap`,`lz4`,`mbregex`,`mbstring`,`memcache`,`memcached`,`mysqli`,`mysqlnd`,`opcache`,`openssl`,`password-argon2`,`parallel`,`pcntl`,`pdo`,`pdo_mysql`,`pdo_pgsql`,`pdo_sqlite`,`pdo_sqlsrv`,`pgsql`,`phar`,`posix`,`protobuf`,`readline`,`redis`,`session`,`shmop`,`simplexml`,`soap`,`sockets`,`sodium`,`sqlite3`,`ssh2`,`sysvmsg`,`sysvsem`,`sysvshm`,`tidy`,`tokenizer`,`xlswriter`,`xml`,`xmlreader`,`xmlwriter`,`xz`,`zip`,`zlib`,`yaml`,`zstd`

{{% content "url_healthcheck" %}}
{{% content "request-flow" %}}
Loading
Loading