Skip to main content

Dockerfile

Learn about the available Docker images you can use as a base for your Apify Actors. Choose the right base image based on your Actor's requirements and the programming language you're using.


When developing an Actor on the Apify platform, you can choose from a variety of pre-built Docker images to serve as the base for your Actor. These base images come with pre-installed dependencies and tools, making it easier to set up your development environment and ensuring consistent behavior across different environments.

Base Docker images

Apify provides several Docker images that can serve as base images for Actors. All images come in two versions:

  • latest - This version represents the stable and production-ready release of the base image.
  • beta - This version is intended for testing new features. Use at your own risk.
Pre-cached Docker images

All Apify Docker images are pre-cached on Apify servers to speed up Actor builds and runs. The source code for generating these images is available in the apify-actor-docker repository.

Node.js base images

These images come with Node.js (versions 20, 22, or 24) the Apify SDK for JavaScript, and Crawlee preinstalled. The latest tag corresponds to the latest LTS version of Node.js.

ImageDescription
actor-nodeSlim Alpine Linux image with only essential tools. Does not include headless browsers.
actor-node-puppeteer-chromeDebian image with Chromium, Google Chrome, and the puppeteer library.
actor-node-playwright-chromeDebian image with Chromium, Google Chrome, and the playwright library.
actor-node-playwright-firefoxDebian image with Firefox and the playwright library .
actor-node-playwright-webkitUbuntu image with WebKit and the playwright library.
actor-node-playwrightUbuntu image with playwright and all its browsers (Chromium, Google Chrome, Firefox, WebKit).

See the Docker image guide for more details.

Python base images

These images come with Python (version 3.9, 3.10, 3.11, 3.12, or 3.13) and the Apify SDK for Python preinstalled. The latest tag corresponds to the latest Python 3 version supported by the Apify SDK.

ImageDescription
actor-pythonSlim Debian image with only the Apify SDK for Python. Does not include headless browsers.
actor-python-playwrightDebian image with playwright and all its browsers.
actor-python-seleniumDebian image with selenium, Google Chrome, and ChromeDriver.

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:

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.

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:

{
"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.

Optimization tips

You can check out various optimization tips for Dockerfile in our Performance documentation.

Updating older Dockerfiles

All Apify base Docker images now use a non-root user to enhance security. This change requires updates to existing Actor Dockerfiles 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.

If you encounter an issue that is not listed here, or need more guidance on how to update your Dockerfile, please open an issue in the apify-actor-docker GitHub repository.

Action required

As of August 25, 2025 the base Docker images display a deprecation warning that links you here. This warning will be removed start of February 2026, so you should update your Dockerfiles to ensure forward compatibility.

User and working directory

To improve security, the affected images no longer run as the root user. Instead, they use a dedicated non-root user, myuser, and a consistent working directory at /home/myuser. This configuration is now the standard for all Apify base Docker images.

Common issues

Crawlee templates automatically installing git in Python images

If you've built your Actor using a Crawlee template, you might have the following line in your Dockerfile:

RUN apt update && apt install -yq git && rm -rf /var/lib/apt/lists/*

You can safely remove this line, as the git package is now installed in the base image.

uv package manager fails to install dependencies

If you are using the uv package manager, you might have the following line in your Dockerfile:

ENV UV_PROJECT_ENVIRONMENT="/usr/local"

With the move to a non-root user, this variable will cause uv to throw a permission error. You can safely remove this line, or, if you need it set to a custom path, adjust it to point to a location in the /home/myuser directory.

Copying files with the correct permissions

When using the COPY instruction to copy your files to the container, you should append the --chown=myuser:myuser flag to the command to ensure the myuser user owns the files.

Here are a few common examples:

COPY --chown=myuser:myuser requirements.txt ./

COPY --chown=myuser:myuser . ./
warning

If your Dockerfile contains a RUN instruction similar to the following one, you should remove it:

RUN chown -R myuser:myuser /home/myuser

Instead, add the --chown flag to the COPY instruction:

COPY --chown=myuser:myuser . ./

Running chown across multiple files needlessly slows down the build process. Using the flag on COPY is much more efficient.

An apify user is being added by a template

If your Dockerfile has instructions similar to the following, they were likely added by an older template:

# Create and run as a non-root user.
RUN adduser -h /home/apify -D apify && \
chown -R apify:apify ./
USER apify

You should remove these lines, as the new user is now myuser. Don't forget to update your COPY instructions to use the --chown flag with the myuser user.

COPY --chown=myuser:myuser . ./

Installing dependencies that require root access

The root user is still available in the Docker images. If you must run steps that require root access (like installing system packages with apt or apk), you can temporarily switch to the root user.

FROM apify/actor-node:24

# Switch to root temporarily to install dependencies
USER root

RUN apt update \
&& apt install -y <dependencies here>

# Switch back to the non-root user
USER myuser

# ... your other instructions

If your Actor needs to run as root for a specific reason, you can add the USER root instruction after FROM. However, for a majority of Actors, this is not necessary.