-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add Docker Compose to the course! #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jslvtr
merged 6 commits into
develop
from
jose/cou-323-add-information-on-docker-compose-to-the-course
Apr 4, 2024
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
a1baec9
🐛 fix(Alembic): Remove `compare_type` references
jslvtr c4768ad
🚸 ux(Lecture code): Add missing start/end lecture codes in 04_02
jslvtr fbc9a81
✨ feat(Docker compose): Add Docker compose lectures
jslvtr 9ba7bb6
Remove `-` from docker compose command
jslvtr ad4f496
🐛 fix(Indentation): Fix indentation in `env.py`
jslvtr 369e132
🐛 fix(JS): Fix VideoEmbed component allowfullscreen
jslvtr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
✨ feat(Docker compose): Add Docker compose lectures
One in Docker section to run the app on its own, and one when we introduce a PostgreSQL database to spin up both the app and db.
- Loading branch information
commit fbc9a816b8f35cbbd65f2ee2484d4d4ed93d24ef
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
docs/docs/04_docker_intro/04_run_with_docker_compose/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Run the REST API using Docker Compose | ||
|
|
||
| Now that we've got a Docker container for our REST API, we can set up Docker Compose to run the container. | ||
|
|
||
| Docker Compose is most useful to start multiple Docker containers at the same time, specifying configuration values for them and dependencies between them. | ||
|
|
||
| Later on, I'll show you how to use Docker Compose to start both a PostgreSQL database and the REST API. For now, we'll use it only for the REST API, to simplify starting its container up. | ||
|
|
||
| If you have Docker Desktop installed, you already have Docker Compose. If you want to install Docker Compose in a system without Docker Desktop, please refer to the [official installation instructions](https://docs.docker.com/compose/install/). | ||
|
|
||
| ## How to write a `docker-compose.yml` file | ||
|
|
||
| Create a file called `docker-compose.yml` in the root of your project (alongside your `Dockerfile`). Inside it, add the following contents: | ||
|
|
||
| ```yaml | ||
| version: '3' | ||
| services: | ||
| web: | ||
| build: . | ||
| ports: | ||
| - "5000:5000" | ||
| volumes: | ||
| - .:/app | ||
| ``` | ||
|
|
||
| This small file is all you need to tell Docker Compose that you have a service, called `web`, which is built using the current directory (by default, that looks for a file called `Dockerfile`). | ||
|
|
||
| Other settings provided are: | ||
|
|
||
| - `ports`, used to map a port in your local computer to one in the container. Since our container runs the Flask app on port 5000, we're targeting that port so that any traffic we access in port 5000 of our computer is sent to the container's port 5000. | ||
| - `volumes`, to map a local directory into a directory within the container. This makes it so you don't have to rebuild the image each time you make a code change. | ||
|
|
||
| ## How to run the Docker Compose services | ||
|
|
||
| Simply type: | ||
|
|
||
| ``` | ||
| docker compose up | ||
| ``` | ||
|
|
||
| And that will start all your services. For now, there's just one service, but later on when we add a database, this command will start everything. | ||
|
|
||
| When the services are running, you'll start seeing logs appear. These are the same logs as for running the `Dockerfile` on its own, but preceded by the service name. | ||
|
|
||
| In our case, we'll see `web-1 | ...` and the logs saying the service is running on `http://127.0.0.1:5000`. When you access that URL, you'll see the request logs printed in the console. | ||
|
|
||
| Congratulations, you've ran your first Docker Compose service! | ||
|
|
||
| ## Rebuilding the Docker image | ||
|
|
||
| If you need to rebuild the Docker image of your REST API service for whatever reason (e.g. configuration changes), you can run: | ||
|
|
||
| ``` | ||
| docker compose up --build --force-recreate --no-deps web | ||
| ``` | ||
|
|
||
| More information [here](https://stackoverflow.com/a/50802581). |
6 changes: 6 additions & 0 deletions
6
docs/docs/04_docker_intro/04_run_with_docker_compose/end/Dockerfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| FROM python:3.10 | ||
| EXPOSE 5000 | ||
| WORKDIR /app | ||
| RUN pip install flask | ||
| COPY . . | ||
| CMD ["flask", "run", "--host", "0.0.0.0"] |
45 changes: 45 additions & 0 deletions
45
docs/docs/04_docker_intro/04_run_with_docker_compose/end/app.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| from flask import Flask, request | ||
|
|
||
| app = Flask(__name__) | ||
|
|
||
| stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}] | ||
|
|
||
|
|
||
| @app.get("/store") | ||
| def get_stores(): | ||
| return {"stores": stores} | ||
|
|
||
|
|
||
| @app.post("/store") | ||
| def create_store(): | ||
| request_data = request.get_json() | ||
| new_store = {"name": request_data["name"], "items": []} | ||
| stores.append(new_store) | ||
| return new_store, 201 | ||
|
|
||
|
|
||
| @app.post("/store/<string:name>/item") | ||
| def create_item(name): | ||
| request_data = request.get_json() | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| new_item = {"name": request_data["name"], "price": request_data["price"]} | ||
| store["items"].append(new_item) | ||
| return new_item, 201 | ||
| return {"message": "Store not found"}, 404 | ||
|
|
||
|
|
||
| @app.get("/store/<string:name>") | ||
| def get_store(name): | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| return store | ||
| return {"message": "Store not found"}, 404 | ||
|
|
||
|
|
||
| @app.get("/store/<string:name>/item") | ||
| def get_item_in_store(name): | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| return {"items": store["items"]} | ||
| return {"message": "Store not found"}, 404 |
8 changes: 8 additions & 0 deletions
8
docs/docs/04_docker_intro/04_run_with_docker_compose/end/docker-compose.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| version: '3' | ||
| services: | ||
| web: | ||
| build: . | ||
| ports: | ||
| - "5000:5000" | ||
| volumes: | ||
| - .:/app |
6 changes: 6 additions & 0 deletions
6
docs/docs/04_docker_intro/04_run_with_docker_compose/start/Dockerfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| FROM python:3.10 | ||
| EXPOSE 5000 | ||
| WORKDIR /app | ||
| RUN pip install flask | ||
| COPY . . | ||
| CMD ["flask", "run", "--host", "0.0.0.0"] |
45 changes: 45 additions & 0 deletions
45
docs/docs/04_docker_intro/04_run_with_docker_compose/start/app.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| from flask import Flask, request | ||
|
|
||
| app = Flask(__name__) | ||
|
|
||
| stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}] | ||
|
|
||
|
|
||
| @app.get("/store") | ||
| def get_stores(): | ||
| return {"stores": stores} | ||
|
|
||
|
|
||
| @app.post("/store") | ||
| def create_store(): | ||
| request_data = request.get_json() | ||
| new_store = {"name": request_data["name"], "items": []} | ||
| stores.append(new_store) | ||
| return new_store, 201 | ||
|
|
||
|
|
||
| @app.post("/store/<string:name>/item") | ||
| def create_item(name): | ||
| request_data = request.get_json() | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| new_item = {"name": request_data["name"], "price": request_data["price"]} | ||
| store["items"].append(new_item) | ||
| return new_item, 201 | ||
| return {"message": "Store not found"}, 404 | ||
|
|
||
|
|
||
| @app.get("/store/<string:name>") | ||
| def get_store(name): | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| return store | ||
| return {"message": "Store not found"}, 404 | ||
|
|
||
|
|
||
| @app.get("/store/<string:name>/item") | ||
| def get_item_in_store(name): | ||
| for store in stores: | ||
| if store["name"] == name: | ||
| return {"items": store["items"]} | ||
| return {"message": "Store not found"}, 404 |
116 changes: 116 additions & 0 deletions
116
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| # How to run the app and database with Docker Compose | ||
|
|
||
| Up until now we've been running `docker-compose up` to start the REST API container. | ||
|
|
||
| Now let's modify our `docker-compose.yml` file to include spinning up a new PostgreSQL database. | ||
|
|
||
| ```yaml | ||
| version: '3' | ||
| services: | ||
| web: | ||
| build: . | ||
| ports: | ||
| - "5000:80" | ||
| depends_on: | ||
| - db | ||
| env_file: | ||
| - ./.env | ||
| volumes: | ||
| - .:/app | ||
| db: | ||
| image: postgres | ||
| environment: | ||
| - POSTGRES_PASSWORD=password | ||
| - POSTGRES_DB=myapp | ||
| volumes: | ||
| - postgres_data:/var/lib/postgresql/data | ||
| volumes: | ||
| postgres_data: | ||
| ``` | ||
|
|
||
| The `postgres` image accepts various environment variables, among them: | ||
|
|
||
| - `POSTGRES_PASSWORD`, defaulting to `postgres` | ||
| - `POSTGERS_DB`, defaulting to `postgres` | ||
| - `POSTGRES_USER`, defaulting to `postgres` | ||
| - `POSTGRES_HOST`, defaulting to `localhost` | ||
| - `POSTGRES_PORT`, defaulting to `5432` | ||
|
|
||
| We should at least set a secure password. Above we're changing the password and database to `password` and `myapp` respectively. | ||
|
|
||
| :::caution | ||
| Remember to also change your `DATABASE_URL` in your `.env` file that the REST API container is using. It should look like this: | ||
|
|
||
| ``` | ||
| DATABASE_URL=postgresql://postgres:password@db/myapp | ||
| ``` | ||
|
|
||
| When Docker Compose runs, it creates a virtual network[^1] which allows you to connect to `db`, which connects to the running `db` service container. | ||
| ::: | ||
|
|
||
| ## Named volumes in Docker Compose | ||
|
|
||
| You'll notice that our `docker-compose.yml` file has these lines: | ||
|
|
||
| ``` | ||
| volumes: | ||
| - postgres_data:/var/lib/postgresql/data | ||
| volumes: | ||
| postgres_data: | ||
| ``` | ||
|
|
||
| The bottom two lines define a named volume. This is data that will be stored by Docker and can be reused across container runs. We're calling it `postgres_data`, but it isn't assigned to anything there. | ||
|
|
||
| In the top two lines, which are part of the `db` service definition, we say that the `postgres_data` named volume is mapped to `/var/lib/postgresql/data` in the container. | ||
|
|
||
| `/var/lib/postgresql/data` is where the `postgres` image saves PostgreSQL data (such as databases, tables, etc). Therefore, as you create databases, tables, and store data, the named volume `postgres_data` will contain them. | ||
|
|
||
| When you restart the container (or even rebuilt it), you can use the same named volume to keep access to old data. | ||
|
|
||
| If you want to delete the entire database content, you can do so by deleting the volume through Docker Desktop, or with this command: | ||
|
|
||
| ``` | ||
| docker compose down -v | ||
| ``` | ||
|
|
||
| ## Starting the whole system | ||
|
|
||
| Now you're ready to start the Docker Compose system! If you need to rebuild the REST API container first, run: | ||
|
|
||
| ``` | ||
| docker compose up --build --force-recreate --no-deps web | ||
| ``` | ||
|
|
||
| You'll get an error due to no database being available. That's OK, as long as the container is rebuilt! | ||
|
|
||
| Then press `CTRL+C` to stop it, and start the whole system with: | ||
|
|
||
| ``` | ||
| docker compose up | ||
| ``` | ||
|
|
||
| Now you can make a request to your API on port 5000, and it should work, storing the data in the database! | ||
|
|
||
| ## Running the system in background mode | ||
|
|
||
| When we run the system with `docker compose up`, it takes up the terminal until we stop it with `CTRL+C`. | ||
|
|
||
| If you want to run it in "Daemon" mode, or in the background, so you can use the terminal for other things, you can use: | ||
|
|
||
| ``` | ||
| docker compose up -d | ||
| ``` | ||
|
|
||
| Then to stop the system, use: | ||
|
|
||
| ``` | ||
| docker compose down | ||
| ``` | ||
|
|
||
| Note you must be in the folder that contains your `docker-compose.yml` file in order to bring the system up or down. | ||
|
|
||
| :::warning | ||
| Running `docker compose down` will **not** delete your named volumes. You need to use the `-v` flag for that. Deleting the named volumes deletes the data in them irreversibly. | ||
| ::: | ||
|
|
||
| [^1]: [Networking in Compose (official docs)](https://docs.docker.com/compose/networking/) | ||
1 change: 1 addition & 0 deletions
1
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/.env.example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| DATABASE_URL= |
2 changes: 2 additions & 0 deletions
2
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/.flaskenv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| FLASK_APP=app | ||
| FLASK_DEBUG=True |
7 changes: 7 additions & 0 deletions
7
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| .env | ||
| .venv | ||
| .vscode | ||
| __pycache__ | ||
| data.db | ||
| *.pyc | ||
| .DS_Store |
7 changes: 7 additions & 0 deletions
7
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/CONTRIBUTING.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # CONTRIBUTING | ||
|
|
||
| ## How to run the Dockerfile locally | ||
|
|
||
| ``` | ||
| docker run -dp 5000:5000 -w /app -v "$(pwd):/app" IMAGE_NAME sh -c "flask run" | ||
jslvtr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
6 changes: 6 additions & 0 deletions
6
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/Dockerfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| FROM python:3.10 | ||
| WORKDIR /app | ||
| COPY requirements.txt . | ||
| RUN pip install --no-cache-dir --upgrade -r requirements.txt | ||
| COPY . . | ||
| CMD ["/bin/bash", "docker-entrypoint.sh"] |
3 changes: 3 additions & 0 deletions
3
docs/docs/11_deploy_to_render/06_run_everything_docker_compose/end/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # REST APIs Recording Project | ||
|
|
||
| Nothing here yet! |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.