Overview

In this guide, we will show you how to host a website and link it to a database using Docker and docker-compose. We walked you through the steps to create a configuration file, Dockerfile, and Python script to set up your web and database services. Then, we will show you how to build the Docker images and start the services. With just a few simple commands, you can now have a fully-functioning website and database running on Docker!


What you’ll need

  1. First, make sure you have Docker and docker-compose installed on your system. You can check if they are installed by running the following commands in your terminal:
docker --version
docker-compose --version

If you do not have Docker or docker-compose installed, you can install them by following the instructions on the Docker website. (https://docs.docker.com/get-docker/)[https://docs.docker.com/get-docker/]


Setup

  1. Create a directory for your project and navigate to it. You can do this by running the following commands in your terminal:
mkdir docker-compose-website
cd docker-compose-website
  1. Create a file called docker-compose.yml in your project directory. This file will contain the configuration for your Docker services. You can do this by running the following command in your terminal:
touch docker-compose.yml

Here is an example of what your docker-compose.yml file should look like:

version: "3"

services:
  web:
    build: .
    ports:
      - "8080:8080"
    links:
      - db
  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: my_database
      MYSQL_USER: my_user
      MYSQL_PASSWORD: my_password
      MYSQL_ROOT_PASSWORD: my_root_password
    ports:
      - "3306:3306"
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

This configuration file specifies the two services that we will be using: the web service, which will host our website, and the db service, which will be the MySQL database that our website will connect to.

Using the volumes key, we can mount the init.sql file to the /docker-entrypoint-initdb.d directory in the db service. This will cause the init.sql file to be executed when the db service is started. This is useful because it allows us to run SQL commands to create a database and table when the db service is started.

This is what init.sql might look like if we wanted to create a database called my_database with a users table:

CREATE DATABASE my_database;
USE my_database;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);

INSERT INTO users (name, email) VALUES ("John", "john@example.com");
INSERT INTO users (name, email) VALUES ("Jane", "jane@example.com");

Note: You can change the port numbers to whatever you want. However, you will need to change the port numbers in your Python script as well.

  1. Next, create a file called Dockerfile in the same directory and add the following code to it:
FROM python:3.8

# Create a working directory
RUN mkdir /app
WORKDIR /app

# Install required packages
RUN pip install Flask mysql-connector-python

# Copy the files in the current directory to the working directory
COPY . /app

# Expose port 8080
EXPOSE 8080

# Run the web service
CMD ["python", "app.py"]

This Dockerfile specifies the steps to build the Docker image for our web service. It installs the required packages, copies the files in the current directory to the working directory, exposes port 8080, and runs the web service.

Next, create a file called app.py in the same directory and add the following code to it:

from flask import Flask
from mysql.connector import connect

app = Flask(__name__)

# Connect to the MySQL database
db = connect(
    host="db",
    user="my_user",
    password="my_password",
    database="my_database"
)

@app.route("/")
def index():
    # Query the database and return the result
    cursor = db.cursor()
    cursor.execute("SELECT * FROM my_table")
    result = cursor.fetchall()
    return str(result)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Note: You should never store your database credentials in your code. However, for the sake of simplicity, we will be doing so in this guide.

This Python script sets up a Flask app, connects to the MySQL database using the configuration specified in the docker-compose.yml file, and defines a route that queries the database and returns the result.

You should also create a file called requirements.txt in the same directory and add the following code to it:

Flask
mysql-connector-python

Note: For more information on how to use Flask, check out the Flask documentation. (https://flask.palletsprojects.com/en/1.1.x/)[https://flask.palletsprojects.com/en/1.1.x/]

Building and Running the Services

After creating app.py, the next step is to build the Docker images for our web and db services using the following command:

docker-compose build

This command will use the configuration specified in the docker-compose.yml and Dockerfile files to build the Docker images for our services.

Once the images are built, we can start our services using the following command:

docker-compose up

Note: If you want to run the services in the background, you can use the following command:

docker-compose up -d

This command will start the web and db services and link them together. The web service will be accessible at http://localhost:8080 and the MySQL database will be accessible at localhost:3306.

You can verify that the website and database are working by visiting http://localhost:8080 in your web browser and checking the output of the database query.

If you need to make changes to your services, you can stop the services using the following command:

docker-compose down

Then, you can make the changes and rebuild and restart the services using the commands we used earlier.


Conclusion

To conclude, hosting a website and linking it to a database using Docker and docker-compose is a fun and easy way to get your web application up and running. With just a few simple steps and some code, you can have a fully-functioning website and database ready to serve your users. So why wait? Give it a try and see what you can create!