Skip to content

Commit

Permalink
feat: add new blog post draft
Browse files Browse the repository at this point in the history
  • Loading branch information
WayneGoosen committed Jun 14, 2024
1 parent 8aa34d9 commit 12f1ca5
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
Binary file added src/assets/images/streamlitdocker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
heroImage: /src/assets/images/streamlitdocker.png
category: Containers
description: Containerise Streamlit application and publish image to ghcr
pubDate: 2024-06-09T22:00:00.000Z
draft: true
tags:
- docker
- containers
- streamlit
title: 'Streamlit Containerization: A Complete Guide with Docker Best Practices'
---

I needed to create a quick proof of concept (PoC) using Streamlit but had two constraints:

- Self-host instead of using [Streamlit community cloud](https://streamlit.io/cloud)
- Control access to the deployed website

With this in mind, containerizing and hosting on Azure was the solution. This post starts a series with the list of parts below:

- Part 1: Containerized Streamlit app with a blank app.py file (just add your code). You are here😊
- Part 2: GitHub workflow to build and publish the image to ghcr.io.
- Part 3: Terraform code to manage infrastructure on Azure.
- Part 4: GitHub workflow to execute Terraform apply & destroy infrastructure.

# Prerequisite

Prerequisite is Docker. Follow installation information

# Docker best practices

Here are the high-level best practices for building Docker images:

	• Use multi-stage builds to reduce image size and improve efficiency.

	• Choose the right base image from trusted sources and keep it small.

	• Rebuild images frequently to incorporate updates and patches.

	• Use .dockerignore to exclude unnecessary files.

	• Create ephemeral containers for stateless applications.

	• Avoid installing unnecessary packages to minimize the attack surface.

	• Decouple applications into separate containers.

	• Sort multi-line arguments for better readability.

	• Leverage build cache for faster builds.

	• Pin base image versions to ensure consistency.

	• Integrate image build and tests in CI/CD pipelines.

For detailed information, visit [Docker Building Best Practices](https://docs.docker.com/build/building/best-practices/).

[https://docs.docker.com/build/building/best-practices/](https://docs.docker.com/build/building/best-practices/)

[https://codefresh.io/blog/docker-anti-patterns/](https://codefresh.io/blog/docker-anti-patterns/)

# Create a docker file

This is the full file we will create

```dockerfile
FROM python:3.9-slim

LABEL maintainer="Wayne Goosen"
LABEL version="1.0.0"
LABEL description="Streamlit template for Docker. Uses app.py as the main file."

WORKDIR /app

RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt .

RUN pip3 install -r requirements.txt

COPY .streamlit/config.toml .streamlit/
COPY app.py .

RUN groupadd -g 1005 appgroup && \
useradd -u 1005 -g appgroup appuser && \
chown -R appuser:appgroup /app

EXPOSE 80

USER appuser

ENTRYPOINT ["streamlit", "run"]
CMD ["app.py"]
```

# Dockerfile walkthrough

- The base image is python:3.9-slim.
- The Dockerfile creates a working directory at /app.
- It updates the package lists for upgrades and new package installations.
- It copies requirements.txt into the Docker image and installs the Python dependencies.
- It copies app.py (the main application file) into the Docker image.
- It creates a group appgroup and a user appuser with group ID and user ID 1005, respectively. It then changes the ownership of the /app directory to appuser\:appgroup.
- It exposes port 8501 for the Streamlit application.
- It sets appuser as the user to run the subsequent commands and the application.
- The entrypoint is set to streamlit run, and the command is set to run app.py with server port 8501 and server address 0.0.0.0.

# Build a docker image

To build the Docker image, navigate to the directory containing the Dockerfile and run the following command:

docker build -t my-streamlit-app .

The -t flag is used to tag the image. Here, we have tagged the image streamlit. If you run:

docker images

You should see a streamlit image under the REPOSITORY column. For example:

REPOSITORY TAG IMAGE ID CREATED SIZE
streamlit latest 70b0759a094d About a minute ago 1.02GB

# Run the docker container

To run the Docker container, use the following command:

docker run -p 8501:80 my-streamlit-app\:latest

To view your app, users can browse to [http://0.0.0.0:8501 or http://localhost:8501](http://0.0.0.0:8501 or http://localhost:8501)[
](https://docs.docker.com/build/building/best-practices/)

# Streamlit configuration

Besides the config.toml (Describe this more detail) the configuration can be passed as a param:

- "--server.port=8501"
- "--server.address=127.0.0.1"
- "--client.showErrorDetails=true"
- "--client.toolbarMode=minimal"

Find more configuration [here](https://docs.streamlit.io/develop/api-reference/configuration/config.toml)

Part 2 coming soon..

# References

- [Deploy streamlit using Docker](https://docs.streamlit.io/deploy/tutorials/docker)

0 comments on commit 12f1ca5

Please sign in to comment.