diff --git a/sources/platform/actors/development/actor_definition/docker.md b/sources/platform/actors/development/actor_definition/docker.md
index b22a717567..29e0902b80 100644
--- a/sources/platform/actors/development/actor_definition/docker.md
+++ b/sources/platform/actors/development/actor_definition/docker.md
@@ -21,6 +21,87 @@ All Apify Docker images are pre-cached on Apify servers to speed up Actor builds
:::
+### Available tags
+
+To see all available tags for an image, visit Docker Hub:
+
+- [View actor-node-playwright-chrome tags](https://hub.docker.com/r/apify/actor-node-playwright-chrome/tags)
+- [View actor-node-playwright tags](https://hub.docker.com/r/apify/actor-node-playwright/tags)
+- [View actor-node-puppeteer-chrome tags](https://hub.docker.com/r/apify/actor-node-puppeteer-chrome/tags)
+- [View actor-python-playwright tags](https://hub.docker.com/r/apify/actor-python-playwright/tags)
+
+You can also query available tags programmatically:
+
+```bash
+curl -s "https://registry.hub.docker.com/v2/repositories/apify/actor-node-playwright-chrome/tags?page_size=50" | jq '.results[].name'
+```
+
+## Custom Dockerfile
+
+Apify uses Docker to build and run Actors. If you create an Actor from a template, it already contains an optimized `Dockerfile` for the given use case.
+
+To use a custom `Dockerfile`, you can either:
+
+- Reference it from the `dockerfile` field in `.actor/actor.json`,
+- Store it in `.actor/Dockerfile` or `Dockerfile` in the root directory (searched in this order of preference).
+
+If no `Dockerfile` is provided, the system uses the following default:
+
+```dockerfile
+FROM apify/actor-node:24
+
+COPY --chown=myuser:myuser package*.json ./
+
+RUN npm --quiet set progress=false \
+ && npm install --only=prod --no-optional \
+ && echo "Installed NPM packages:" \
+ && (npm list --only=prod --no-optional --all || true) \
+ && echo "Node.js version:" \
+ && node --version \
+ && echo "NPM version:" \
+ && npm --version
+
+COPY --chown=myuser:myuser . ./
+```
+
+For more information about `Dockerfile` syntax and commands, see the [Dockerfile reference](https://docs.docker.com/reference/dockerfile/).
+
+:::note Custom base images
+
+While `apify/actor-node` is a base Docker image provided by Apify, you can use other Docker images as the base for your Actors.
+However, using the Apify images has some performance advantages, as they are pre-caches on Apify servers.
+
+:::
+
+By default, Apify base Docker images with the Apify SDK and Crawlee start your Node.js application the same way as `npm start`, i.e, by running the command specified in `package.json` under `scripts` - `start`. The default `package.json` is similar to:
+
+```json
+{
+ "description": "Anonymous Actor on the Apify platform",
+ "version": "0.0.1",
+ "license": "UNLICENSED",
+ "main": "main.js",
+ "scripts": {
+ "start": "node main.js"
+ },
+ "dependencies": {
+ "apify": "^3.0.0",
+ "crawlee": "^3.0.0"
+ },
+ "repository": {}
+}
+```
+
+This means the system expects the source code to be in `main.js` by default. If you want to override this behavior, use a custom `package.json` and/or `Dockerfile`.
+
+:::tip Optimization tips
+
+You can check out various optimization tips for Dockerfile in the [Performance](../performance.md) documentation.
+
+:::
+
+## Node.js images
+
### Node.js base images
These images come with Node.js (versions `22`, `24`, or `26`). The `latest` tag corresponds to the latest LTS version of Node.js.
@@ -45,22 +126,7 @@ FROM apify/actor-node-playwright-chrome:24-1.60.0-slim
See the [Docker image guide](/sdk/js/docs/guides/docker-images) for more details.
-### Python base images
-
-These images come with Python (version `3.10`, `3.11`, `3.12`, `3.13`, or `3.14`) and the [Apify SDK for Python](/sdk/python) preinstalled. The `latest` tag corresponds to the latest Python 3 version supported by the Apify SDK.
-
-| Image | Description |
-| ----- | ----------- |
-| [`actor-python`](https://hub.docker.com/r/apify/actor-python) | Slim Debian image with only the Apify SDK for Python. Does not include headless browsers. |
-| [`actor-python-playwright`](https://hub.docker.com/r/apify/actor-python-playwright) | Debian image with [`playwright`](https://github.com/microsoft/playwright) and all its browsers. |
-| [`actor-python-playwright-camoufox`](https://hub.docker.com/r/apify/actor-python-playwright-camoufox) | Debian image with [Camoufox](https://camoufox.com/), a Firefox fork hardened against bot detection, and the [`playwright`](https://github.com/microsoft/playwright) library. |
-| [`actor-python-selenium`](https://hub.docker.com/r/apify/actor-python-selenium) | Debian image with [`selenium`](https://github.com/seleniumhq/selenium), Google Chrome, and [ChromeDriver](https://developer.chrome.com/docs/chromedriver/). |
-
-## Image tag naming convention
-
-Docker image tags follow a consistent naming pattern that allows you to pin specific versions:
-
-### Node.js images
+### Node.js tag format
For Node.js images, the tag format is:
@@ -78,33 +144,11 @@ Examples:
| `22-1.52.0-slim` | Same as `22-1.52.0`, but without preinstalled `apify`, `crawlee` and `typescript` |
| `latest` | Latest LTS Node.js version |
-### Python images
+### Version pinning for reproducible builds
-For Python images, the tag format is:
-
-- `{python-version}` - A Python version only (e.g., `3.12`, `3.13`, `3.14`)
-- `{python-version}-{library-version}` - A Python version with pinned Playwright/Selenium version
+For production Actors, pin both the Node.js version and the browser automation library version in your Dockerfile. This ensures reproducible builds and prevents unexpected behavior when new versions are released.
-### Available tags
-
-To see all available tags for an image, visit Docker Hub:
-
-- [View actor-node-playwright-chrome tags](https://hub.docker.com/r/apify/actor-node-playwright-chrome/tags)
-- [View actor-node-playwright tags](https://hub.docker.com/r/apify/actor-node-playwright/tags)
-- [View actor-node-puppeteer-chrome tags](https://hub.docker.com/r/apify/actor-node-puppeteer-chrome/tags)
-- [View actor-python-playwright tags](https://hub.docker.com/r/apify/actor-python-playwright/tags)
-
-You can also query available tags programmatically:
-
-```bash
-curl -s "https://registry.hub.docker.com/v2/repositories/apify/actor-node-playwright-chrome/tags?page_size=50" | jq '.results[].name'
-```
-
-## Version pinning for reproducible builds
-
-For production Actors, pin both the Node.js/Python version and the browser automation library version in your Dockerfile. This ensures reproducible builds and prevents unexpected behavior when new versions are released.
-
-### Recommended approach
+#### Recommended approach
In your `Dockerfile`, use a fully pinned tag:
@@ -135,7 +179,7 @@ When the Playwright/Puppeteer version in your `package.json` differs from what's
:::
-### Use `*` as version (alternative approach)
+#### Use `*` as version (alternative approach)
You may encounter older documentation or templates using `*` as the Playwright/Puppeteer version:
@@ -153,7 +197,7 @@ The asterisk (`*`) tells npm to use whatever version is already installed, which
1. Predictability - You know exactly which version you're running
1. Debugging - Version-specific issues are easier to track down
-## Node.js package managers
+### Node.js package managers
All Node.js images ship with npm and have [Corepack](https://github.com/nodejs/corepack) enabled, so you can use yarn or pnpm as well. Neither is preinstalled: add a [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) field to your `package.json` and Corepack downloads and uses the exact version you pin.
@@ -181,71 +225,7 @@ ENV YARN_NODE_LINKER=pnp
:::
-## Custom Dockerfile
-
-Apify uses Docker to build and run Actors. If you create an Actor from a template, it already contains an optimized `Dockerfile` for the given use case.
-
-To use a custom `Dockerfile`, you can either:
-
-- Reference it from the `dockerfile` field in `.actor/actor.json`,
-- Store it in `.actor/Dockerfile` or `Dockerfile` in the root directory (searched in this order of preference).
-
-If no `Dockerfile` is provided, the system uses the following default:
-
-```dockerfile
-FROM apify/actor-node:24
-
-COPY --chown=myuser:myuser package*.json ./
-
-RUN npm --quiet set progress=false \
- && npm install --only=prod --no-optional \
- && echo "Installed NPM packages:" \
- && (npm list --only=prod --no-optional --all || true) \
- && echo "Node.js version:" \
- && node --version \
- && echo "NPM version:" \
- && npm --version
-
-COPY --chown=myuser:myuser . ./
-```
-
-For more information about `Dockerfile` syntax and commands, see the [Dockerfile reference](https://docs.docker.com/reference/dockerfile/).
-
-:::note Custom base images
-
-While `apify/actor-node` is a base Docker image provided by Apify, you can use other Docker images as the base for your Actors.
-However, using the Apify images has some performance advantages, as they are pre-caches on Apify servers.
-
-:::
-
-By default, Apify base Docker images with the Apify SDK and Crawlee start your Node.js application the same way as `npm start`, i.e, by running the command specified in `package.json` under `scripts` - `start`. The default `package.json` is similar to:
-
-```json
-{
- "description": "Anonymous Actor on the Apify platform",
- "version": "0.0.1",
- "license": "UNLICENSED",
- "main": "main.js",
- "scripts": {
- "start": "node main.js"
- },
- "dependencies": {
- "apify": "^3.0.0",
- "crawlee": "^3.0.0"
- },
- "repository": {}
-}
-```
-
-This means the system expects the source code to be in `main.js` by default. If you want to override this behavior, use a custom `package.json` and/or `Dockerfile`.
-
-:::tip Optimization tips
-
-You can check out various optimization tips for Dockerfile in the [Performance](../performance.md) documentation.
-
-:::
-
-## Build TypeScript Actors
+### Build TypeScript Actors
TypeScript Actors compile to JavaScript at build time through a `tsc` build step. Installing only production dependencies (`npm install --omit=dev`, or the older `--only=prod`) strips the `typescript` package, so the build fails with `tsc: not found`. Three fixes:
@@ -287,6 +267,28 @@ TypeScript Actors compile to JavaScript at build time through a `tsc` build step
}
```
+## Python images
+
+### Python base images
+
+These images come with Python (version `3.10`, `3.11`, `3.12`, `3.13`, or `3.14`) and the [Apify SDK for Python](/sdk/python) preinstalled. The `latest` tag corresponds to the latest Python 3 version supported by the Apify SDK.
+
+| Image | Description |
+| ----- | ----------- |
+| [`actor-python`](https://hub.docker.com/r/apify/actor-python) | Slim Debian image with only the Apify SDK for Python. Does not include headless browsers. |
+| [`actor-python-playwright`](https://hub.docker.com/r/apify/actor-python-playwright) | Debian image with [`playwright`](https://github.com/microsoft/playwright) and all its browsers. |
+| [`actor-python-playwright-camoufox`](https://hub.docker.com/r/apify/actor-python-playwright-camoufox) | Debian image with [Camoufox](https://camoufox.com/), a Firefox fork hardened against bot detection, and the [`playwright`](https://github.com/microsoft/playwright) library. |
+| [`actor-python-selenium`](https://hub.docker.com/r/apify/actor-python-selenium) | Debian image with [`selenium`](https://github.com/seleniumhq/selenium), Google Chrome, and [ChromeDriver](https://developer.chrome.com/docs/chromedriver/). |
+
+### Python tag format
+
+For Python images, the tag format is:
+
+- `{python-version}` - A Python version only (e.g., `3.12`, `3.13`, `3.14`)
+- `{python-version}-{library-version}` - A Python version with pinned Playwright/Selenium version
+
+For production Actors, pin both versions (e.g. `3.13-1.52.0`) so builds stay reproducible.
+
## Update older Dockerfiles
All Apify base Docker images now use a non-root user to enhance security. This change requires updates to existing Actor `Dockerfile`s that use the `apify/actor-node`, `apify/actor-python`, `apify/actor-python-playwright`, or `apify/actor-python-selenium` images. This section provides guidance on resolving common issues that may arise during this migration.