Cookbook Recipe App Dockerisation


RecipeBook: A Dockerized Flask CRUD Application

Title: Full-Stack CRUD RecipeBook App with Flask, SQLite, and Docker

Abbreviated: Dockerized Flask Recipe App


Introduction

This project details the development, containerization, and deployment of a full-stack, database-driven web application named RecipeBook. This application serves as a personal digital cookbook, allowing users to perform complete CRUD (Create, Read, Update, Delete) operations on their personal recipes.

Built with a Python and Flask backend, a standard HTML/CSS/JS frontend, and an SQLite database, the project emphasizes robust, real-world application design. By containerizing the final product using Docker and Docker Compose, this assignment showcases a complete, modern development pipeline, transforming a local application into a portable, reproducible, and easily distributable service.


Objectives of Part 1: Local Development (Flask & SQLite)

  • Design and develop a Python Flask web application to manage digital recipes.

  • Define an SQLite database schema to store recipe details, including ingredients, instructions, ratings, and reviews.

  • Implement full backend CRUD (Create, Read, Update, Delete) functionality for all recipes.

  • Build a clean, responsive HTML/CSS/JS frontend for user interaction, including forms and a recipe search feature.

  • Validate all application features and database persistence on localhost.


Objectives of Part 2: Containerization (Docker)

  • Author a Dockerfile to define a reproducible environment for the Flask application.

  • Write a docker-compose.yml file to manage the application service, configuration, and volumes.

  • Build the Docker image and launch the containerized application using Docker Compose.

  • Test the live container, ensuring the application runs identically to the local development version and that database data persists across container restarts.

Name of Containers Involved and Download Links

Component NameSource / TypePurpose
python:3.9-slimDocker Hub ImageBase image for building the custom application image.
recipebook-app:latestLocal Build (Dockerfile / docker-compose.yml)The custom-built container image running the Flask RecipeBook app.
VolumeDocker Feature (Managed via docker-compose.yml)Persists the recipes.db SQLite database file outside the container.
DockerfileProject File (Dockerfile)Instructions used by Docker to build the recipebook-app:latest image.

Objectives of Part 3

  • Implement Docker networking and volume management to enhance the RecipeBook application's container architecture.

  • Create a custom Docker network to enable seamless communication between RecipeBook and potential future containers (e.g., database or API services).

  • Configure a persistent Docker volume to retain RecipeBook data (such as uploaded images, recipes, and reviews) across container restarts or redeployments.

  • Deploy the RecipeBook Docker image (mrigankr/recipebook:latest) on the EC2 instance within the created network and volume setup.

  • Verify successful persistent storage and network integration by testing application functionality and ensuring data consistency after container restarts.

Other Software Involved Along With Purpose

  • Python 3.x: Core language for Flask backend development.

  • Flask: Lightweight web framework for handling HTTP routes and rendering templates.

  • Flask-SQLAlchemy: ORM for managing the SQLite database schema and queries.

  • SQLite: Self-contained, file-based SQL database for data persistence.

  • HTML/CSS/JS: Frontend technologies for the user interface, forms, and layout.

  • VS Code / Editor: Source code development, Dockerfile authoring.

  • Docker Desktop: Building and running containers locally.

  • Docker Compose: Tool for defining and running multi-container Docker applications.

  • Windows PowerShell/Terminal: Running all pip, flask, and docker commands.


Overall Architecture of the RecipeBook DA

Below is a line diagram representing the workflow from local development and database interaction to containerization with Docker Compose, clearly depicting all inputs and outputs:




Inputs:

  • Recipe data (name, ingredients, instructions, rating, review) submitted by the user via web forms.

  • Search terms entered by the user.

  • Source code (app.py, models.py, templates, etc.), Dockerfile, and docker-compose.yml provided by the developer.

Outputs:

  • HTML pages displaying recipe lists, details, and forms in the user's browser.

  • Persistent storage of recipe data in the recipes.db file (managed by the Docker volume).

  • A running Docker container serving the web application locally via http://localhost:5000.

Detailed Architecture

The project's architecture is a streamlined model for a full-stack, containerized web application.

Inputs:

  • User-provided recipe data (name, ingredients, etc.)

  • User search queries

  • Source code, Dockerfile, docker-compose.yml

Outputs:

  • Rendered HTML pages (recipe list, add/edit forms)

  • Data stored in the recipes.db SQLite file

  • A portable Docker image


1. Frontend (Presentation) Layer

This layer is what the user interacts with. It consists of static HTML files rendered by Flask, styled with CSS, and enhanced with minimal JavaScript. It includes forms for adding/editing recipes and a card-based layout for viewing and searching all recipes.


2. Backend (Application) Layer

The core of the project, this layer is a Flask application (app.py). It defines all HTTP routes:

  • GET /: View all recipes (and handle search).

  • POST /add: Receive form data to create a new recipe.

  • POST /update/<id>: Update an existing recipe.

  • POST /delete/<id>: Delete a specific recipe.

    It processes user input, queries the database, and renders the appropriate HTML template.


3. Persistence (Database) Layer

Unlike the weather app which used an external API, this project uses an internal, persistent database. An SQLite file (recipes.db) is used to store all user data. Flask-SQLAlchemy acts as the Object-Relational Mapper (ORM), translating Python classes into database tables and making data queries simple and secure.


4. Containerization Layer

Docker encapsulates the entire application.

  • The Dockerfile provides instructions to build an image containing the Python environment, all code, and all dependencies (requirements.txt).

  • The docker-compose.yml file defines the "RecipeBook" service. It uses the built image, maps the container's port 5000 to the host's port 5000, and critically, mounts a volume. This volume links the recipes.db file inside the container to a file on the host machine, ensuring that even if the container is deleted, the user's data is safe.


End-to-End Dataflow (Adding a Recipe):

  1. User fills out the "Add Recipe" form in their browser and clicks "Submit."

  2. An HTTP POST request is sent to the Docker container.

  3. Docker forwards the request to the Flask application.

  4. The Flask /add route receives the form data.

  5. Flask-SQLAlchemy creates a new Recipe object and commits it to the SQLite database.

  6. The recipes.db file (managed by the Docker volume) is updated.

  7. Flask redirects the user back to the homepage, which reads the new data and displays the new recipe.



Procedure - Part 1: Local Development

(Steps involved in the process with screenshots: please insert your own original images for each step below.)

  1. Create project structure: recipe-app/, app.py, models.py, requirements.txt, static/, templates/.

  2. Define database in models.py: Create the Recipe class with columns for name, ingredients, instructions, rating, etc.

  3. Code app.py: Import Flask and models. Write all 5 CRUD routes (/, /add, /edit, /delete, /search).

  4. Create templates/: Build base.html, index.html (view/search), and add_recipe.html.

  5. Install dependencies: Run pip install -r requirements.txt.

  6. Initialize database & run: Run flask run and test all features on http://localhost:5000.









Procedure - Part 2: Containerization

  1. Install Docker Desktop and ensure it's running.

  2. Create Dockerfile: Specify python:3.9-slim, set WORKDIR, COPY project files, RUN pip install, EXPOSE 5000, and set CMD ["flask", "run", "--host=0.0.0.0"].

  3. Create docker-compose.yml: Define the recipe-app service. Set build: ., map ports: ["5000:5000"], and define volumes: [./data/recipes.db:/app/recipes.db].

  4. Build the image: Run docker-compose build.

  5. Launch the container: Run docker-compose up.

  6. Verify deployment: Open http://localhost:5000 in a browser. The app should be running. Add a recipe, then run docker-compose down and docker-compose up again to confirm the data is still there (persisted in the volume).









Procedure – Part 3: Using Docker Network and Volume for RecipeBook

1. Create a Custom Docker Network

To allow your RecipeBook container and any future services (like a database or API) to communicate internally:

sudo docker network create recipebook-network

This creates a dedicated bridge network named recipebook-network for your application containers.


2. Create a Docker Volume for Persistent Storage

The volume ensures RecipeBook’s data (like uploaded recipe images, reviews, or configurations) is saved even if the container restarts:

sudo docker volume create recipebook-data

This volume will be mounted to a directory inside the container where app data is stored.


3. Pull the RecipeBook Image from Docker Hub

Pull your uploaded image from your Docker Hub repository:

sudo docker pull mrigankr/recipebook:latest

4. Run the RecipeBook Container with Network and Volume

Now run your RecipeBook container with both network and volume attached:

sudo docker run -d \ --name recipebook \ --network recipebook-network \ -v recipebook-data:/usr/src/app/data \ -p 80:5000 \ --restart always \ mrigankr/recipebook:latest

--network recipebook-network → connects it to the custom network.
-v recipebook-data:/usr/src/app/data → stores data persistently in a Docker-managed volume.
-p 80:5000 → maps EC2 port 80 (HTTP) to container port 5000 (Flask default).


5. Verify Container and Network

Check if everything is running correctly:

sudo docker ps sudo docker network ls sudo docker volume ls

Inspect the container and network connections:

sudo docker inspect recipebook sudo docker network inspect recipebook-network

6. Access the RecipeBook Web App

Open your browser and go to:
👉 http://<EC2-Public-IP>

You should see your RecipeBook application running successfully.
Test the app by adding recipes, uploading images, and verifying that data remains available even after restarting the container.


7. Test Data Persistence

To confirm that your Docker volume works:

  1. Stop and remove the running container:

    sudo docker stop recipebook sudo docker rm recipebook
  2. Re-run it using the same command as before (the same volume will be reused).
    After restart, your uploaded recipe data should still exist — confirming persistent storage.




What Modification is Done in the Containers After Downloading

  • The official python:3.9-slim base image is not modified directly.

  • A new custom image is built from it.

  • Modifications include:

    1. Adding the project's source code (app.py, models.py, etc.).

    2. Installing all Python dependencies (Flask, SQLAlchemy) via pip.

    3. Setting the CMD to automatically start the Flask server when the container runs.

  • The docker-compose.yml file then runs this custom container, connecting its port 5000 and attaching a persistent volume for the database.

Docker Hub Link of Modified Container


Docker Hub: https://hub.docker.com/r/mrigankr/recipebook/tags


What are the Outcomes of Your DA?

  • A fully functional, full-stack web application demonstrating all CRUD operations.

  • A lightweight and persistent data solution using a local SQLite database.

  • A clean, responsive, and user-friendly interface.

  • A fully containerized application using Docker, ensuring portability and reproducible builds.

  • Practical experience in writing both a Dockerfile and a docker-compose.yml file to manage services and persistent data volumes.

Conclusion

This project successfully demonstrates the complete lifecycle of a modern web application, from initial Python coding to a final, portable Docker deployment. By integrating a Flask backend, an SQLite database, and Docker, the RecipeBook app serves as a robust, real-world example of a full-stack CRUD application. The use of Docker Compose, in particular, highlights best practices for managing services and ensuring data persistence, making the application easy to run and share on any system.




References and Acknowledgement

  • Docker Hub - Maintainers of the python:3.9-slim base image and providers of open Docker documentation.

  • Flask Documentation - For comprehensive guidance on the Flask web framework, Jinja templating, and extension usage (https://flask.palletsprojects.com/).

  • Flask-SQLAlchemy Documentation - For information on database integration and ORM usage (https://flask-sqlalchemy.palletsprojects.com/).

  • Docker Documentation - For detailed instructions on Dockerfile syntax, docker-compose, and volume management (https://docs.docker.com/).

  • SQLite Documentation - For reference on the SQL database engine used (https://www.sqlite.org/docs.html).

  • Faculty, friends, parents, and reviewers - For their invaluable guidance, support, feedback, and assistance during testing.

Comments