Posted under » Ubuntu » Python » System Admin on 23 May 2025
From docker intro... you have learnt how to `run' a docker container. However, there are times where you need to run something more complex just like a PHP composer.
First, confirm the latest version available in their releases page. At the time of this writing, the most current stable version is 2.36.1. For Ubuntu,
$ mkdir -p ~/.docker/cli-plugins/ $ curl -SL https://github.com/docker/compose/releases/download/v2.3.6/docker-compose-linux-x86_64 \ -o ~/.docker/cli-plugins/docker-compose
Set the correct permissions so that the docker compose command is executable
$ chmod +x ~/.docker/cli-plugins/docker-compose $ docker compose version
Next we set up our first docker-compose.yml file. Let's create something simple like ... Create a page in python Flask and then store data in Redis to track the number of hits. Flask is like a simpler version of Django. Redis is a super-fast database using RAM.
We begin by creating a directory. eg. /home/ubuntu/docker/compose/flask-redis
In flask-redis, create a Python file app.py.
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return f'Hello World! I have been seen {count} times.\n'
In this example, the default redis port, 6379 is used. Note the way the get_hit_count function is written. This basic retry loop attempts the request multiple times if the Redis service is not available. This is useful at startup while the application comes online, but also makes the application more resilient if the Redis service needs to be restarted anytime during the app's lifetime. In a cluster, this also helps handling momentary connection drops between nodes.
Create another file called requirements.txt. In Python, we install using pip and to automate installations, we use requirements.txt. I remember using this for AWS elastic beanstalk.
flask redis
You will see requirements.txt being used by the `Dockerfile'. Create and check that the Dockerfile has no file extension. A Dockerfile contains instructions so that Docker can build images automatically.
# syntax=docker/dockerfile:1 FROM python:3.10-alpine WORKDIR /code ENV FLASK_APP=app.py ENV FLASK_RUN_HOST=0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt EXPOSE 5000 COPY . . CMD ["flask", "run", "--debug"]
Compose simplifies the control of your entire application stack, making it easy to manage services, networks, and volumes in a single, comprehensible YAML configuration file.
Create a file called compose.yaml in your project directory
services: web: build: . ports: - "8000:5000" redis: image: "redis:alpine"
This Compose file defines two services: web and redis.
1. The web service uses an image that's built from the Dockerfile in the current directory. It then binds the container and the host machine to the exposed port, 8000. This example service uses the default port for the Flask web server, 5000.
2. Compose pulls a public Redis image from the Docker Hub registry, builds an image for your code, and starts the services you defined.
With a single command, you create and start all the services from your configuration file. From your project directory, start up your application by running docker compose up. It is best that you open a screen to run `compose up' or you can use the detached or -d command
You will often see 'alpine' in docker. Alpine is a minimal linux distribution version.
$ docker compose up
Enter http://localhost:8000/ in a browser to see the application running.
In this case, the code is statically copied into the image at build time. Which means, when you change the file at /home/ubuntu/docker/compose/flask-redis/app.py it will not show on the instance unless you rebuild the image. That python app of the instance is running on the image's WORKDIR /code according to the `Dockerfile'. If you want to be able to change the file and see it in effect, you need to create a volume to it.
Lets create another web page using docker compose where you can change and see the contents being changed without having to rebuild the image
by using volume in our next docker compose tutorial using Ngnix »