Deploy with Docker¶
Prerequisites¶
A marimo notebook or app:
app.py
that you want to deployA
requirements.txt
file that contains the dependencies needed for your application to run
Create a Dockerfile¶
Dockerfile
is a text file that contains instructions for building a Docker image. Here’s an example Dockerfile
for a marimo notebook:
# syntax=docker/dockerfile:1.4
# Choose a python version that you know works with your application
FROM python:3.11-slim
# Install uv for fast package management
COPY --from=ghcr.io/astral-sh/uv:0.4.20 /uv /bin/uv
ENV UV_SYSTEM_PYTHON=1
WORKDIR /app
# Copy requirements file
COPY --link requirements.txt .
# Install the requirements using uv
RUN uv pip install -r requirements.txt
# Copy application files
COPY --link app.py .
# Uncomment the following line if you need to copy additional files
# COPY --link . .
EXPOSE 8080
# Create a non-root user and switch to it
RUN useradd -m app_user
USER app_user
CMD [ "marimo", "run", "app.py", "--host", "0.0.0.0", "-p", "8080" ]
Breaking it down¶
FROM
instructs what base image to choose. In our case, we chose Python 3.11 with the “slim” variant. This removes a lot of extra dependencies. You can always add them back as needed.
A slimmer Dockerfile (by bytes) means quick to build, deploy, and start up.
The WORKDIR
sets the current working directory. In most cases, this does not need to be changed.
The COPY
steps will copy all the necessary files into your docker. By adding --link
, we end up creating a new layer that does not get invalidated by previous changes. This can be especially important for expensive install steps that do not depend on each other.
RUN
lets us run shell commands. We can use this to install dependencies via apt-get, pip, or package managers. In our case, we use it to install our requirements.txt with pip.
Our EXPOSE
step tells us which port is exposed to be accessed from outside the Docker container. This will need to match the port at which we run our marimo application on.
We then create a new user and switch to it with the USER
instruction, in order to limit the permissions of the marimo application. This is not required, but recommended.
The final step CMD
instructions what command to run when we run our docker container. Here we run our marimo application at the port 8080.
Running your application locally¶
Once you have your Dockerfile and your application files, you can test it out locally:
# Build your image, and tag it as my_app
docker build -t my_app .
# Start your container, mapping port 8080
docker run -p 8080:8080 -it my_app
# Visit http://localhost:8080
After verifying that your application runs without errors, you can use these files to deploy your application on your preferred cloud provider that supports dockerized applications.
Using Interactive Matplotlib Plots in Docker¶
If your notebook uses mo.mpl.interactive()
for interactive matplotlib plots, you’ll need to make some additional configurations in your Dockerfile:
# Add these lines before the CMD instruction
ENV MARIMO_MPL_HOST="0.0.0.0" # same as main host from `marimo run`.
ENV MARIMO_MPL_SECURE=true # if you are running on https
EXPOSE 10000 # Expose in addition to your main application port
This exposes the additional CSS and JavaScript required.
Health checks¶
You can add a health check to your Dockerfile to ensure that your application is running as expected. This is especially useful when deploying to a cloud provider.
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
The following endpoints may be useful when deploying your application:
/health
or/healthz
- A health check endpoint that returns a 200 status code if the application is running as expected/api/status
- A status endpoint that returns a JSON object with the status of the server