How to Dockerize Applications with Docker Compose (Using SQLite and Flask)

Below is a set of instructions for Dockerizing a Flask and SQLit project. This can also be done with other mixture of technologies such as using Postgres instead. This is intended to be a guide for other projects as well.

Step 1: Set Up a .dockerignore File

Before building the Docker image, create a .dockerignore file to exclude unnecessary files and directories from the Docker image.

  1. Create a .dockerignore file in the root of your project.

  2. Add common files to ignore:

    *.pyc
    __pycache__
    .git
    *.md
    docker-compose.yml
    *.py
    .env
    *.db

This will ensure unnecessary files like Python bytecode, Git history, and documentation aren't copied into your Docker image.


Step 2: Create a Dockerfile

The Dockerfile defines how to build the Docker image for your app.

2.1 Create a Dockerfile

  1. Create a Dockerfile in the root directory of your project.

  2. Add the following configuration for building the image:

    # Use the official Python image from DockerHub
    FROM python:3.11-slim
    
    # Set the working directory in the container
    WORKDIR /usr/src/app
    
    # Install system dependencies (e.g., gcc for compiling Python libraries)
    RUN apt-get update && apt-get install -y --no-install-recommends gcc
    
    # Copy the requirements.txt file into the container
    COPY requirements.txt .
    
    # Install Python dependencies
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Copy the rest of the application files into the container
    COPY . .
    
    # Expose the port the app will run on (default Flask port)
    EXPOSE 5000
    
    # Set environment variables (e.g., Flask app entry point)
    ENV FLASK_APP=main.py
    
    # Command to run the Flask app
    CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]

Explanation of the Dockerfile:

  • FROM python:3.11-slim: Use a minimal Python image.

  • WORKDIR /usr/src/app: Set the working directory inside the container.

  • RUN apt-get update && apt-get install gcc: Install system dependencies.

  • COPY requirements.txt .: Copy your requirements.txt file into the container.

  • RUN pip install --no-cache-dir -r requirements.txt: Install Python dependencies.

  • COPY . .: Copy all project files (excluding those in .dockerignore) into the container.

  • EXPOSE 5000: Expose port 5000, which is where Flask will run.

  • CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]: Start the Flask application.


Step 3: Create a docker-compose.yml File

For SQLite, you don’t need to set up a database service in Docker Compose because SQLite is just a file-based database. You’ll only need to configure the web app service.

3.1 Create a docker-compose.yml File

  1. Create a docker-compose.yml file in the root directory of your project.

  2. Add the following configuration for your web app:

    version: "3.8"
    
    services:
      web:
        build: .
        ports:
          - "5000:5000"
        environment:
          - FLASK_APP=main.py
        volumes:
          - ./data:/usr/src/app/data

Explanation of docker-compose.yml:

  • version: Specifies the version of the Docker Compose file format. We are using version 3.8.

  • services: Defines the services (containers) for your application.

    • web: The Flask application container.

      • build: Tells Docker Compose to build the image from the current directory (which includes the Dockerfile).

      • ports: Maps port 5000 on your local machine to port 5000 in the container.

      • environment: Sets the environment variable FLASK_APP=main.py, which tells Flask to use main.py as the entry point.

      • volumes: Maps a local directory (./data) to a directory in the container (/usr/src/app/data). This is where the SQLite database file will be stored. This ensures the database persists between container restarts.


Step 4: Build and Run the Application Using Docker Compose

Now that your Dockerfile and docker-compose.yml are set up, you can build and run your Flask application along with SQLite.

4.1 Build and Start the Containers

  1. Open a terminal and navigate to the directory where your docker-compose.yml file is located.

  2. Run the following command to build the images and start the containers:

    docker-compose up --build

    The --build flag will rebuild the images if there are changes in your Dockerfile.

  3. Once the containers are up and running, you can access your application in a web browser at http://localhost:5000.

4.2 Run Containers in Detached Mode (Optional)

If you want to run the containers in the background, use the -d flag:

docker-compose up -d --build

This will start the containers in the background and allow you to continue using the terminal.

4.3 Stop the Containers

To stop the containers and remove the associated networks, use the following command:

docker-compose down

Step 5: Using SQLite with Flask

Since you're using SQLite, the database file will be stored on the host machine and mapped to a directory inside the container (./data:/usr/src/app/data in the docker-compose.yml). By default, Flask with SQLite will create a file-based database (e.g., app.db).

  1. Ensure your Flask app is configured to use the SQLite database file from the mounted volume. For example, in your main.py file, you might have:

    import sqlite3
    from flask import Flask
    
    app = Flask(__name__)
    
    # SQLite database file path
    DATABASE = '/usr/src/app/data/app.db'
    
    def get_db():
        conn = sqlite3.connect(DATABASE)
        return conn
    
    @app.route('/')
    def index():
        conn = get_db()
        cursor = conn.cursor()
        cursor.execute('SELECT * FROM users')
        users = cursor.fetchall()
        conn.close()
        return f'Users: {users}'
    
    if __name__ == "__main__":
        app.run(debug=True)
  2. The DATABASE path is set to /usr/src/app/data/app.db, which is inside the container at /usr/src/app/data, but is mapped to a directory (./data) on the host. This means your SQLite database will be stored in the ./data folder on your host machine, and the container will be able to read/write from it.


Step 6: Push Docker Images to Docker Hub (Optional)

If you want to share your Docker images or deploy your app, you can push the image to Docker Hub.

6.1 Tag the Docker Image

Tag your image with your Docker Hub username and repository name:

docker tag your-image-name yourusername/your-image-name:latest

6.2 Push the Image

Push the tagged image to Docker Hub:

docker push yourusername/your-image-name:latest

Additional Notes

  • Database Persistence: By using a volume to store the SQLite database file, you ensure that your data persists even if you stop and remove the container.

  • Scaling with Docker Compose: If you need to scale your Flask app or add more services later, Docker Compose allows you to easily define and scale multiple instances of your services.

  • Backup SQLite: You can backup the SQLite database by copying the ./data directory from your host system.

Last updated