From 12f1ca50f57e73b1a8f747324a0a4a489f2a2e4b Mon Sep 17 00:00:00 2001 From: WayneGoosen <13494899+WayneGoosen@users.noreply.github.com> Date: Fri, 14 Jun 2024 23:54:29 +0200 Subject: [PATCH] feat: add new blog post draft --- src/assets/images/streamlitdocker.png | Bin 0 -> 44174 bytes ...-application-and-publish-image-to-ghcr.mdx | 148 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 src/assets/images/streamlitdocker.png create mode 100644 src/content/blog/Containerise-Streamlit-application-and-publish-image-to-ghcr.mdx diff --git a/src/assets/images/streamlitdocker.png b/src/assets/images/streamlitdocker.png new file mode 100644 index 0000000000000000000000000000000000000000..77eee999e7be5aa5148172f190b7ec9298771b55 GIT binary patch literal 44174 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 z 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 Dq1Va~ literal 0 HcmV?d00001 diff --git a/src/content/blog/Containerise-Streamlit-application-and-publish-image-to-ghcr.mdx b/src/content/blog/Containerise-Streamlit-application-and-publish-image-to-ghcr.mdx new file mode 100644 index 0000000..ccea2ef --- /dev/null +++ b/src/content/blog/Containerise-Streamlit-application-and-publish-image-to-ghcr.mdx @@ -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)