Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 110 additions & 108 deletions sources/platform/actors/development/actor_definition/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. <br/>
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.
Expand All @@ -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:

Expand All @@ -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:

Expand Down Expand Up @@ -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:

Expand All @@ -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.

Expand Down Expand Up @@ -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. <br/>
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:

Expand Down Expand Up @@ -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.
Expand Down
Loading