get-started: update python guide (#18404)

* update python guide

Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
Co-authored-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
Craig Osterhout 2023-10-18 15:05:56 -07:00 committed by GitHub
parent 1c20b2ba67
commit ccecb1c3f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 532 additions and 568 deletions

View File

@ -6,18 +6,13 @@ toc_min: 1
toc_max: 2
---
The Python getting started guide teaches you how to containerize a Python application using Docker. In this guide, you'll learn how to:
The Python language-specific guide teaches you how to containerize a Python application using Docker. In this guide, youll learn how to:
* Create a new Dockerfile which contains instructions required to build a Python image
* Build an image and run the newly built image as a container
* Set up volumes and networking
* Orchestrate containers using Compose
* Use containers for development
* Configure a CI/CD pipeline for your application using GitHub Actions
* Deploy your application to the cloud
* Containerize and run a Python application
* Set up a local environment to develop a Python application using containers
* Configure a CI/CD pipeline for a containerized Python application using GitHub Actions
* Deploy your containerized Python application locally to Kubernetes to test and debug your deployment
After completing the Python getting started modules, you should be able to containerize your own Python application based on the examples and instructions provided in this guide.
Start by containerizing an existing Python application.
Let's get started!
{{< button text="Build your first Python image" url="build-images.md" >}}
{{< button text="Containerize a Python app" url="containerize.md" >}}

View File

@ -1,194 +0,0 @@
---
title: Build your Python image
keywords: python, build, images, dockerfile
description: Learn how to build an image of your Python application
---
## Prerequisites
* You have installed the latest version of [Docker Desktop](../../get-docker.md).
* You have a [git client](https://git-scm.com/downloads). The examples in this section use a command-line based git client, but you can use any client.
## Overview
This guide walks you through building your first Python image. An image
includes everything needed to run an application - the code or binary, runtime,
dependencies, and any other file system objects required.
## Sample application
The sample application uses the popular [Flask](https://flask.palletsprojects.com/) framework.
Clone the sample application to use with this guide. Open a terminal, change directory to a directory that you want to work in, and run the following command to clone the repository:
```console
$ git clone https://github.com/docker/python-docker
```
## Test the application without Docker (optional)
You can test the application locally without Docker before you continue building and running the application with Docker. This section requires you to have Python 3.11 or later installed on your machine. Download and install [Python](https://www.python.org/downloads/).
Open your terminal and navigate to the working directory you created. Create an environment, install the dependencies, and start the application to make sure its running.
```console
$ cd /path/to/python-docker
$ python3 -m venv .venv
$ source .venv/bin/activate
(.venv) $ python3 -m pip install -r requirements.txt
(.venv) $ python3 -m flask run
```
To test that the application is working, open a new browser and navigate to `http://localhost:5000`.
Switch back to the terminal where the server is running and you should see the following requests in the server logs. The data and timestamp will be different on your machine.
```shell
127.0.0.1 - - [22/Sep/2020 11:07:41] "GET / HTTP/1.1" 200 -
```
## Create a Dockerfile for Python
Now that you have an application, you can use `docker init` to create a Dockerfile for it. Inside the `python-docker` directory, run the `docker init` command. Refer to the following example to answer the prompts from `docker init`.
```console
$ docker init
Welcome to the Docker Init CLI!
This utility will walk you through creating the following files with sensible defaults for your project:
- .dockerignore
- Dockerfile
- compose.yaml
Let's get started!
? What application platform does your project use? Python
? What version of Python do you want to use? 3.11.4
? What port do you want your app to listen on? 5000
? What is the command to run your app? python3 -m flask run --host=0.0.0.0
```
You should now have the following 3 new files in your `python-docker`
directory:
- Dockerfile
- `.dockerignore`
- `compose.yaml`
The Dockerfile is used to build the image. Open the Dockerfile
in your favorite IDE or text editor and see what it contains. To learn more
about Dockerfiles, see the [Dockerfile reference](../../engine/reference/builder.md).
## .dockerignore file
When you run `docker init`, it also creates a [`.dockerignore`](../../engine/reference/builder.md#dockerignore-file) file. Use the `.dockerignore` file to specify patterns and paths that you don't want copied into the image in order to keep the image as small as possible. Open up the `.dockerignore` file in your favorite IDE or text editor and see what's inside already.
## Build an image
Now that youve created the Dockerfile, you can build the image. To do this, use the `docker build` command. The `docker build` command builds Docker images from a Dockerfile and a build context. A build context is the set of files that the build has access to.
The build command optionally takes a `--tag` flag. The tag sets the name of the image and an optional tag in the format `name:tag`. Leave off the optional `tag` for now to help simplify things. If you don't pass a tag, Docker uses “latest” as its default tag.
Build the Docker image.
```console
$ docker build --tag python-docker .
```
You should get output similar to the following.
```console
[+] Building 1.3s (12/12) FINISHED
=> [internal] load .dockerignore
=> => transferring context: 680B
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 1.59kB
=> resolve image config for docker.io/docker/dockerfile:1
=> CACHED docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4
=> [internal] load metadata for docker.io/library/python:3.11.4-slim
=> [base 1/5] FROM docker.io/library/python:3.11.4-slim@sha256:36b544be6e796eb5caa0bf1ab75a17d2e20211cad7f66f04f
=> [internal] load build context
=> => transferring context: 63B
=> CACHED [base 2/5] WORKDIR /app
=> CACHED [base 3/5] RUN adduser --disabled-password --gecos "" --home "/nonexistent" --shell
=> CACHED [base 4/5] RUN --mount=type=cache,target=/root/.cache/pip --mount=type=bind,source=requirements.tx
=> CACHED [base 5/5] COPY . .
=> exporting to image
=> => exporting layers
=> => writing image sha256:37f9294069a95e5b34bb9e9035c6ea6ad16657818207c9d0dc73594f70144ce4
=> => naming to docker.io/library/python-docker
```
## View local images
To see a list of images you have on your local machine, you have two options. One is to use the Docker CLI and the other is to use [Docker Desktop](../../desktop/use-desktop/images.md). As you are working in the terminal already, take a look at listing images using the CLI.
To list images, run the `docker images` command.
```console
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 3 minutes ago 123MB
```
You should see at least one image listed, including the image you just built `python-docker:latest`.
## Tag images
As mentioned earlier, an image name is made up of slash-separated name components. Name components may contain lowercase letters, digits, and separators. A separator can include a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.
An image is made up of a manifest and a list of layers. Don't worry too much about manifests and layers at this point other than a “tag” points to a combination of these artifacts. You can have multiple tags for an image. Create a second tag for the image you built and take a look at its layers.
To create a new tag for the image you built, run the following command.
```console
$ docker tag python-docker:latest python-docker:v1.0.0
```
The `docker tag` command creates a new tag for an image. It doesn't create a new image. The tag points to the same image and is just another way to reference the image.
Now, run the `docker images` command to see a list of the local images.
```console
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 4 minutes ago 123MB
python-docker v1.0.0 8cae92a8fbd6 4 minutes ago 123MB
...
```
You can see that two images start with `python-docker`. You know they're the same image because if you take a look at the `IMAGE ID` column, you can see that the values are the same for the two images.
Remove the tag you just created. To do this, use the `rmi` command. The `rmi` command stands for remove image.
```console
$ docker rmi python-docker:v1.0.0
Untagged: python-docker:v1.0.0
```
Note that the response from Docker tells you that Docker didn't remove the image, but only “untagged” it. You can check this by running the `docker images` command.
```console
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python-docker latest 8cae92a8fbd6 6 minutes ago 123MB
...
```
Docker removed the image tagged with `:v1.0.0`, but the `python-docker:latest` tag is available on your machine.
## Summary
This section showed how you can use `docker init` to create a Dockerfile and .dockerignore file for a Python application. It then showed you how to build an image. And finally, it showed you how to tag an image and list all images.
Related information:
- [Dockerfile reference](../../engine/reference/builder.md)
- [.dockerignore file reference](../../engine/reference/builder.md#dockerignore-file)
- [docker init CLI reference](../../engine/reference/commandline/init.md)
- [docker build CLI reference](../../engine/reference/commandline/build.md)
- [Build with Docker guide](../../build/guide/index.md)
## Next steps
In the next section learn how to run your image as a container.
{{< button text="Run the image as a container" url="run-containers.md" >}}

View File

@ -1,19 +1,133 @@
---
title: Configure CI/CD for your application
keywords: python, CI/CD, local, development
description: Learn how to Configure CI/CD for your application
title: Configure CI/CD for your Python application
keywords: ci/cd, github actions, python, flask
description: Learn how to configure CI/CD using GitHub Actions for your Python application.
---
## Get started with GitHub Actions
## Prerequisites
{{< include "gha-tutorial.md" >}}
Complete all the previous sections of this guide, starting with [Containerize a Python application](containerize.md). You must have a [GitHub](https://github.com/signup) account and a [Docker](https://hub.docker.com/signup) account to complete this section.
## Overview
In this section, you'll learn how to set up and use GitHub Actions to build and test your Docker image as well as push it to Docker Hub. You will complete the following steps:
1. Create a new repository on GitHub.
2. Define the GitHub Actions workflow.
3. Run the workflow.
## Step one: Create the repository
Create a GitHub repository, configure the Docker Hub secrets, and push your source code.
1. [Create a new repository](https://github.com/new) on GitHub.
2. Open the repository **Settings**, and go to **Secrets and variables** >
**Actions**.
3. Create a new secret named `DOCKER_USERNAME` and your Docker ID as value.
4. Create a new [Personal Access Token
(PAT)](/docker-hub/access-tokens/#create-an-access-token) for Docker Hub. You
can name this token `python-docker`.
5. Add the PAT as a second secret in your GitHub repository, with the name
`DOCKERHUB_TOKEN`.
6. In your local repository on your machine, run the following command to change
the origin to the repository you just created. Make sure you change
`your-username` to your GitHub username and `your-repository` to the name of
the repository you created.
```console
$ git remote set-url origin https://github.com/your-username/your-repository.git
```
7. Run the following commands to stage, commit, and push your local repository to GitHub.
```console
$ git add -A
$ git commit -m "my commit"
$ git push -u origin main
```
## Step two: Set up the workflow
Set up your GitHub Actions workflow for building, testing, and pushing the image
to Docker Hub.
1. Go to your repository on GitHub and then select the **Actions** tab.
2. Select **set up a workflow yourself**.
This takes you to a page for creating a new GitHub actions workflow file in
your repository, under `.github/workflows/main.yml` by default.
3. In the editor window, copy and paste the following YAML configuration.
```yaml
name: ci
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}:latest
```
For more information about the YAML syntax used here, see [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions).
## Step three: Run the workflow
Save the workflow file and run the job.
1. Select **Commit changes...** and push the changes to the `main` branch.
After pushing the commit, the workflow starts automatically.
2. Go to the **Actions** tab. It displays the workflow.
Selecting the workflow shows you the breakdown of all the steps.
3. When the workflow is complete, go to your
[repositories on Docker Hub](https://hub.docker.com/repositories).
If you see the new repository in that list, it means the GitHub Actions
successfully pushed the image to Docker Hub.
## Summary
In this section, you have learned how to set up GitHub Actions workflow to an existing Docker project, optimize your workflow to improve build times and reduce the number of pull requests, and finally, you learned how to push only specific versions to Docker Hub. You can also set up nightly tests against the latest tag, test each PR, or do something more elegant with the tags you are using and make use of the Git tag for the same tag in your image.
In this section, you learned how to set up a GitHub Actions workflow for your Python application.
Related information:
- [Introduction to GitHub Actions](../../build/ci/github-actions/index.md)
- [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
## Next steps
Next, learn how you can deploy your application.
Next, learn how you can locally test and debug your workloads on Kubernetes before deploying.
{{< button text="Deploy your app" url="deploy.md" >}}
{{< button text="Test your deployment" url="./deploy.md" >}}

View File

@ -0,0 +1,140 @@
---
title: Containerize a Python application
keywords: python, flask, containerize, initialize
description: Learn how to containerize a Python application.
redirect_from:
- /language/python/build-images/
- /language/python/run-containers/
---
## Prerequisites
* You have installed the latest version of [Docker Desktop](../../get-docker.md).
* You have a [git client](https://git-scm.com/downloads). The examples in this section use a command-line based git client, but you can use any client.
## Overview
This section walks you through containerizing and running a Python application.
## Get the sample application
The sample application uses the popular [Flask](https://flask.palletsprojects.com/) framework.
Clone the sample application to use with this guide. Open a terminal, change directory to a directory that you want to work in, and run the following command to clone the repository:
```console
$ git clone https://github.com/docker/python-docker
```
## Test the application without Docker (optional)
You can test the application locally without Docker before you continue building and running the application with Docker. This section requires you to have Python 3.11 or later installed on your machine. Download and install [Python](https://www.python.org/downloads/).
Open your terminal and navigate to the working directory you created. Create an environment, install the dependencies, and start the application to make sure its running.
```console
$ cd /path/to/python-docker
$ python3 -m venv .venv
$ source .venv/bin/activate
(.venv) $ python3 -m pip install -r requirements.txt
(.venv) $ python3 -m flask run
```
To test that the application is working, open a new browser and navigate to `http://localhost:5000`.
Switch back to the terminal where the server is running and you should see the following requests in the server logs. The data and timestamp will be different on your machine.
```shell
127.0.0.1 - - [22/Sep/2020 11:07:41] "GET / HTTP/1.1" 200 -
```
## Initialize Docker assets
Now that you have an application, you can use `docker init` to create the necessary Docker assets to containerize your application. Inside the `python-docker` directory, run the `docker init` command. Refer to the following example to answer the prompts from `docker init`.
```console
$ docker init
Welcome to the Docker Init CLI!
This utility will walk you through creating the following files with sensible defaults for your project:
- .dockerignore
- Dockerfile
- compose.yaml
Let's get started!
? What application platform does your project use? Python
? What version of Python do you want to use? 3.11.4
? What port do you want your app to listen on? 5000
? What is the command to run your app? python3 -m flask run --host=0.0.0.0
```
You should now have the following contents in your `python-docker`
directory.
```
├── python-docker/
│ ├── app.py
│ ├── requirements.txt
│ ├── .dockerignore
│ ├── compose.yaml
│ ├── Dockerfile
│ └── README.md
```
To learn more about the files that `docker init` added, see the following:
- [Dockerfile](../../engine/reference/builder.md)
- [.dockerignore](../../engine/reference/builder.md#dockerignore-file)
- [compose.yaml](../../compose/compose-file/_index.md)
## Run the application
Inside the `python-docker` directory, run the following command in a
terminal.
```console
$ docker compose up --build
```
Open a browser and view the application at [http://localhost:5000](http://localhost:5000). You should see a simple Flask application.
In the terminal, press `ctrl`+`c` to stop the application.
### Run the application in the background
You can run the application detached from the terminal by adding the `-d`
option. Inside the `python-docker` directory, run the following command
in a terminal.
```console
$ docker compose up --build -d
```
Open a browser and view the application at [http://localhost:5000](http://localhost:5000).
You should see a simple Flask application.
In the terminal, run the following command to stop the application.
```console
$ docker compose down
```
For more information about Compose commands, see the [Compose CLI
reference](../../compose/reference/_index.md).
## Summary
In this section, you learned how you can containerize and run your Python
application using Docker.
Related information:
- [Build with Docker guide](../../build/guide/index.md)
- [Docker Compose overview](../../compose/_index.md)
## Next steps
In the next section, you'll learn how you can develop your application using
containers.
{{< button text="Develop your application" url="develop.md" >}}

View File

@ -1,7 +1,142 @@
---
title: Deploy your app
keywords: deploy, ACI, ECS, Python, local, development
description: Learn how to deploy your application
title: Test your Python deployment
keywords: deploy, kubernetes, python
description: Learn how to develop locally using Kubernetes
---
{{< include "deploy.md" >}}
## Prerequisites
- Complete all the previous sections of this guide, starting with [Containerize a Python application](containerize.md).
- [Turn on Kubernetes](/desktop/kubernetes/#turn-on-kubernetes) in Docker Desktop.
## Overview
In this section, you'll learn how to use Docker Desktop to deploy your application to a fully-featured Kubernetes environment on your development machine. This allows you to test and debug your workloads on Kubernetes locally before deploying.
## Create a Kubernetes YAML file
In your `python-docker-dev` directory, create a file named
`docker-python-kubernetes.yaml`. Open the file in an IDE or text editor and add
the following contents. Replace `DOCKER_USERNAME/REPO_NAME` with your Docker
username and the name of the repository that you created in [Configure CI/CD for
your Python application](configure-ci-cd.md).
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-python-demo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
service: flask
template:
metadata:
labels:
service: flask
spec:
containers:
- name: flask-service
image: DOCKER_USERNAME/REPO_NAME
imagePullPolicy: Always
env:
- name: POSTGRES_PASSWORD
value: mysecretpassword
---
apiVersion: v1
kind: Service
metadata:
name: service-entrypoint
namespace: default
spec:
type: NodePort
selector:
service: flask
ports:
- port: 5000
targetPort: 5000
nodePort: 30001
```
In this Kubernetes YAML file, there are two objects, separated by the `---`:
- A Deployment, describing a scalable group of identical pods. In this case,
you'll get just one replica, or copy of your pod. That pod, which is
described under `template`, has just one container in it. The
container is created from the image built by GitHub Actions in [Configure CI/CD for
your Python application](configure-ci-cd.md).
- A NodePort service, which will route traffic from port 30001 on your host to
port 5000 inside the pods it routes to, allowing you to reach your app
from the network.
To learn more about Kubernetes objects, see the [Kubernetes documentation](https://kubernetes.io/docs/home/).
## Deploy and check your application
1. In a terminal, navigate to `python-docker-dev` and deploy your application to
Kubernetes.
```console
$ kubectl apply -f docker-python-kubernetes.yaml
```
You should see output that looks like the following, indicating your Kubernetes objects were created successfully.
```shell
deployment.apps/docker-python-demo created
service/service-entrypoint created
```
2. Make sure everything worked by listing your deployments.
```console
$ kubectl get deployments
```
Your deployment should be listed as follows:
```shell
NAME READY UP-TO-DATE AVAILABLE AGE
docker-python-demo 1/1 1 1 15s
```
This indicates all one of the pods you asked for in your YAML are up and running. Do the same check for your services.
```console
$ kubectl get services
```
You should get output like the following.
```shell
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h
service-entrypoint NodePort 10.99.128.230 <none> 5000:30001/TCP 75s
```
In addition to the default `kubernetes` service, you can see your `service-entrypoint` service, accepting traffic on port 30001/TCP.
3. In a terminal, curl the service. Note that a database was not deployed in
this example.
```console
$ curl http://localhost:30001/
Hello, Docker!!!
```
4. Run the following command to tear down your application.
```console
$ kubectl delete -f docker-python-kubernetes.yaml
```
## Summary
In this section, you learned how to use Docker Desktop to deploy your application to a fully-featured Kubernetes environment on your development machine.
Related information:
- [Kubernetes documentation](https://kubernetes.io/docs/home/)
- [Deploy on Kubernetes with Docker Desktop](../../desktop/kubernetes.md)
- [Swarm mode overview](../../engine/swarm/_index.md)

View File

@ -1,89 +1,21 @@
---
title: Use containers for development
keywords: python, local, development, run,
description: Learn how to develop your application locally.
title: Use containers for Python development
keywords: python, local, development
description: Learn how to develop your Python application locally.
---
## Prerequisites
Work through the steps to build an image and run it as a containerized application in [Run your image as a container](run-containers.md).
Complete [Containerize a Python application](containerize.md).
## Introduction
## Overview
In this section, youll learn how to use volumes and networking in Docker. Youll also use Docker to build your images and Docker Compose to make everything a whole lot easier.
In this section, you'll learn how to set up a development environment for your containerized application. This includes:
First, youll take a look at running a database in a container and how you can use volumes and networking to persist your data and let your application to talk with the database. Then youll pull everything together into a Compose file which lets you to set up and run a local development environment with one command.
- Adding a local database and persisting data
- Configuring Compose to automatically update your running Compose services as you edit and save your code
## Run a database in a container
Instead of downloading PostgreSQL, installing, configuring, and then running the PostgreSQL database on your system directly, you can use the Docker Official Image for PostgreSQL and run it in a container.
Before you run PostgreSQL in a container, create a volume that Docker can manage to store your persistent data and configuration.
Run the following command to create your volume.
```console
$ docker volume create db-data
```
Now create a network that your application and database will use to talk to each other. The network is called a user-defined bridge network and gives you a nice DNS lookup service which you can use when creating your connection string.
```console
$ docker network create postgresnet
```
Now you can run PostgreSQL in a container and attach to the volume and network that you created above. Docker pulls the image from Hub and runs it for you locally.
In the following command, option `--mount` is for starting the container with a volume. For more information, see [Docker volumes](../../storage/volumes.md).
{{< tabs >}}
{{< tab name="Mac / Linux" >}}
```console
$ docker run --rm -d \
--mount type=volume,src=db-data,target=/var/lib/postgresql/data \
-p 5432:5432 \
--network postgresnet \
--name db \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_DB=example \
postgres
```
{{< /tab >}}
{{< tab name="Windows" >}}
```powershell
$ docker run --rm -d `
--mount type=volume,src=db-data,target=/var/lib/postgresql/data `
-p 5432:5432 `
--network postgresnet `
--name db `
-e POSTGRES_PASSWORD=mysecretpassword `
-e POSTGRES_DB=example `
postgres
```
{{< /tab >}}
{{< /tabs >}}
Now, make sure that your PostgreSQL database is running and that you can connect to it. Connect to the running PostgreSQL database inside the container.
```console
$ docker exec -it db psql -U postgres
```
You should see output like the following.
```console
psql (15.3 (Debian 15.3-1.pgdg110+1))
Type "help" for help.
postgres=#
```
In the previous command, you logged in to the PostgreSQL database by passing the `psql` command to the `db` container. Press ctrl-d to exit the PostgreSQL interactive terminal.
## Get and run the sample application
## Get the sample application
You'll need to clone a new repository to get a sample application that includes logic to connect to the database.
@ -112,62 +44,9 @@ You'll need to clone a new repository to get a sample application that includes
? What is the command to run your app? python3 -m flask run --host=0.0.0.0
```
3. In the cloned repository's directory, run `docker build` to build the image.
## Add a local database and persist data
```console
$ docker build -t python-docker-dev .
```
4. If you have any containers running from the previous sections using the name `rest-server` or port 8000, [stop and remove](./run-containers.md/#stop-start-and-name-containers) them now.
5. Run `docker run` with the following options to run the image as a container on the same network as the database.
{{< tabs >}}
{{< tab name="Mac / Linux" >}}
```console
$ docker run --rm -d \
--network postgresnet \
--name rest-server \
-p 8000:5000 \
-e POSTGRES_PASSWORD=mysecretpassword \
python-docker-dev
```
{{< /tab >}}
{{< tab name="Windows" >}}
```powershell
$ docker run --rm -d `
--network postgresnet `
--name rest-server `
-p 8000:5000 `
-e POSTGRES_PASSWORD=mysecretpassword `
python-docker-dev
```
{{< /tab >}}
{{< /tabs >}}
6. Test that your application is connected to the database and is able to list the widgets.
```console
$ curl http://localhost:8000/initdb
$ curl http://localhost:8000/widgets
```
You should receive the following JSON back from your service.
```json
[]
```
This is because your database is empty.
## Use Compose to develop locally
When you run `docker init`, in addition to a `Dockerfile`, it also creates a `compose.yaml` file.
This Compose file is super convenient as you don't have to type all the parameters to pass to the `docker run` command. You can declaratively do that using a Compose file.
You can use containers to set up local services, like a database. In this section, you'll update the `compose.yaml` file to define a database service and a volume to persist data.
In the cloned repository's directory, open the `compose.yaml` file in an IDE or text editor. `docker init` handled creating most of the instructions, but you'll need to update it for your unique application.
@ -176,15 +55,6 @@ In the `compose.yaml` file, you need to uncomment all of the database instructio
The following is the updated `compose.yaml` file.
```yaml
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Docker compose reference guide at
# https://docs.docker.com/compose/compose-file/
# Here the instructions define your application as a service called "server".
# This service is built from the Dockerfile in the current directory.
# You can add other services your application may depend on here, such as a
# database or a cache. For examples, see the Awesome Compose repository:
# https://github.com/docker/awesome-compose
services:
server:
build:
@ -193,13 +63,6 @@ services:
- 5000:5000
environment:
- POSTGRES_PASSWORD=mysecretpassword
# The commented out section below is an example of how to define a PostgreSQL
# database that your application can use. `depends_on` tells Docker Compose to
# start the database before your application. The `db-data` volume persists the
# database data between container restarts. The `db-password` secret is used
# to set the database password. You must create `db/password.txt` and add
# a password of your choosing to it before running `docker compose up`.
depends_on:
db:
condition: service_healthy
@ -228,7 +91,10 @@ secrets:
file: db/password.txt
```
Note that the file doesn't specify a network for those 2 services. Compose automatically creates a network and connects the services to it. For more information see [Networking in Compose](../../compose/networking.md).
> **Note**
>
> To learn more about the instructions in the Compose file, see [Compose file
> reference](/compose/compose-file/).
Before you run the application using Compose, notice that this Compose file specifies a `password.txt` file to hold the database's password. You must create this file as it's not included in the source repository.
@ -238,7 +104,22 @@ In the cloned repository's directory, create a new directory named `db` and insi
mysecretpassword
```
If you have any other containers running from the previous sections, [stop](./run-containers.md/#stop-start-and-name-containers) them now.
Save and close the `password.txt` file.
You should now have the following contents in your `python-docker-dev`
directory.
```
├── python-docker-dev/
│ ├── db/
│ │ └── password.txt
│ ├── app.py
│ ├── requirements.txt
│ ├── .dockerignore
│ ├── compose.yaml
│ ├── Dockerfile
│ └── README.md
```
Now, run the following `docker compose up` command to start your application.
@ -246,8 +127,6 @@ Now, run the following `docker compose up` command to start your application.
$ docker compose up --build
```
The command passes the `--build` flag so Docker will compile your image and then start the containers.
Now test your API endpoint. Open a new terminal then make a request to the server using the curl commands:
```console
@ -261,18 +140,103 @@ You should receive the following response:
[]
```
This is because your database is empty.
The response is empty because your database is empty.
Press `ctrl+c` in the terminal to stop your application.
## Automatically update services
Use Compose Watch to automatically update your running Compose services as you
edit and save your code. For more details about Compose Watch, see [Use Compose
Watch](../../compose/file-watch.md).
Open your `compose.yaml` file in an IDE or text editor and then add the Compose
Watch instructions. The following is the updated `compose.yaml` file.
```yaml
services:
server:
build:
context: .
ports:
- 5000:5000
environment:
- POSTGRES_PASSWORD=mysecretpassword
depends_on:
db:
condition: service_healthy
develop:
watch:
- action: rebuild
path: .
db:
image: postgres
restart: always
user: postgres
secrets:
- db-password
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=example
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
expose:
- 5432
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:
secrets:
db-password:
file: db/password.txt
```
Run the following command to run your application with Compose Watch.
```console
$ docker compose watch
```
In a terminal, curl the application to get a response.
```console
$ curl http://localhost:5000
Hello, Docker!
```
Any changes to the application's source files on your local machine will now be immediately reflected in the running container.
Open `python-docker-dev/app.py` in an IDE or text editor and update the `Hello, Docker!` string by adding a few more exclamation marks.
```diff
- return 'Hello, Docker!'
+ return 'Hello, Docker!!!'
```
Save the changes to `app.py` and then wait a few seconds for the application to rebuild. Curl the application again and verify that the updated text appears.
```console
$ curl http://localhost:5000
Hello, Docker!!!
```
Press `ctrl+c` in the terminal to stop your application.
# Summary
In this section, you took a look at setting up your Compose file to run your Python application and database with a single command.
In this section, you took a look at setting up your Compose file to add a local
database and persist data. You also learned how to use Compose Watch to automatically rebuild and run your container when you update your code.
Related information:
- [Volumes](../../storage/volumes.md)
- [Compose overview](../../compose/index.md)
- [Compose file reference](/compose/compose-file/)
- [Compose file watch](../../compose/file-watch.md)
- [Multi-stage builds](../../build/building/multi-stage.md)
## Next steps
In the next section, you'll take a look at how to set up a CI/CD pipeline using GitHub Actions.
{{< button text="Configure CI/CD" url="configure-ci-cd.md" >}}
{{< button text="Configure CI/CD" url="configure-ci-cd.md" >}}

View File

@ -1,188 +0,0 @@
---
title: Run your image as a container
keywords: Python, run, image, container,
description: Learn how to run the image as a container.
---
## Prerequisites
Work through the steps to build a Python image in [Build your Python image](build-images.md).
## Overview
In the previous module, you got the sample application and then created a Dockerfile that you used to produce an image. You created your image using the Docker command `docker build`. Now that you have an image, you can run that image and see if your application is running correctly.
A container is a normal operating system process except that this process is isolated in that it has its own file system, its own networking, and its own isolated process tree separate from the host.
To run an image inside of a container, use the `docker run` command. The `docker run` command requires one parameter which is the name of the image. Start your image and make sure it is running correctly. Run the following command in your terminal.
```console
$ docker run python-docker
```
After running this command, youll notice that you were not returned to the command prompt. This is because your application is a REST server and runs in a loop waiting for incoming requests without returning control back to the OS until you stop the container.
Open a new terminal then make a `GET` request to the server using the `curl` command.
```console
$ curl localhost:5000
curl: (7) Failed to connect to localhost port 5000: Connection refused
```
As you can see, your `curl` command failed because the connection to your server was refused. This means you were not able to connect to localhost on port 5000. This is expected because your container is running in isolation which includes networking. Stop the container and restart with port 5000 published on your local network.
To stop the container, press ctrl-c. This will return you to the terminal prompt.
To publish a port for your container, use the `--publish` flag (`-p` for short) on the `docker run` command. The format of the `--publish` command is `[host port]:[container port]`. So, if you wanted to expose port 5000 inside the container to port 3000 outside the container, you would pass `3000:5000` to the `--publish` flag.
You did not specify a port when running the flask application in the container and the default is 5000. If you want your previous request going to port 5000 to work, you can map the host's port 8000 to the container's port 5000:
```console
$ docker run --publish 8000:5000 python-docker
```
Now, open a new terminal window and re-run the `curl` command.
```console
$ curl localhost:8000
Hello, Docker!
```
Success! You were able to connect to the application running inside of your container on port 8000. Switch back to the terminal where your container is running and you should see the `GET` request logged to the console.
```shell
[31/Jan/2021 23:39:31] "GET / HTTP/1.1" 200 -
```
Press ctrl-c to stop the container.
## Run in detached mode
This is great so far, but your sample application is a web server and you don't have to be connected to the container. Docker can run your container in detached mode or in the background. To do this, you can use the `--detach` or `-d` for short. Docker starts your container the same as before but this time will “detach” from the container and return you to the terminal prompt.
```console
$ docker run -d -p 8000:5000 python-docker
ce02b3179f0f10085db9edfccd731101868f58631bdf918ca490ff6fd223a93b
```
Docker started your container in the background and printed the container ID on the terminal.
Again, make sure that your container is running properly. Run the same curl command from above.
```console
$ curl localhost:8000
Hello, Docker!
```
## List containers
Since you ran your container in the background, how do you know if your container is running or what other containers are running on your machine? Well, to see a list of containers running on your machine, run `docker ps`. This is similar to how the ps command is used to see a list of processes on a Linux machine.
```console
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce02b3179f0f python-docker "python3 -m flask ru…" 6 minutes ago Up 6 minutes 0.0.0.0:8000->5000/tcp wonderful_kalam
```
The `docker ps` command provides a bunch of information about your running containers. You can see the container ID, the image running inside the container, the command that was used to start the container, when it was created, the status, ports that were exposed, and the name of the container.
You are probably wondering where the name of your container is coming from. Since you didnt provide a name for the container when you started it, Docker generated a random name. Youll fix this in a minute, but first you need to stop the container. To stop the container, run the `docker stop` command which does just that, stops the container. You need to pass the name of the container or you can use the container ID.
```console
$ docker stop wonderful_kalam
wonderful_kalam
```
Now, rerun the `docker ps` command to see a list of running containers.
```console
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
```
## Stop, start, and name containers
You can start, stop, and restart Docker containers. When you stop a container, it is not removed, but the status is changed to stopped and the process inside the container is stopped. When you ran the `docker ps` command in the previous module, the default output only shows running containers. When you pass the `--all` or `-a` for short, you see all containers on your machine, irrespective of their start or stop status.
```console
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce02b3179f0f python-docker "python3 -m flask ru…" 16 minutes ago Exited (0) 5 minutes ago wonderful_kalam
ec45285c456d python-docker "python3 -m flask ru…" 28 minutes ago Exited (0) 20 minutes ago agitated_moser
fb7a41809e5d python-docker "python3 -m flask ru…" 37 minutes ago Exited (0) 36 minutes ago goofy_khayyam
```
You should now see several containers listed. These are containers that you started and stopped but have not been removed.
Restart the container that you just stopped. To do this, locate the name of the container you just stopped and replace the name of the container below in the restart command.
```console
$ docker restart wonderful_kalam
```
Now list all the containers again using the `docker ps` command.
```console
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce02b3179f0f python-docker "python3 -m flask ru…" 19 minutes ago Up 8 seconds 0.0.0.0:8000->5000/tcp wonderful_kalam
ec45285c456d python-docker "python3 -m flask ru…" 31 minutes ago Exited (0) 23 minutes ago agitated_moser
fb7a41809e5d python-docker "python3 -m flask ru…" 40 minutes ago Exited (0) 39 minutes ago goofy_khayyam
```
Notice that the container you just restarted has been started in detached mode and has port 8000 exposed. Also, observe the status of the container is “Up X seconds”. When you restart a container, it starts with the same flags or commands that it was originally started with.
Now, stop and remove all of your containers and take a look at fixing the random naming issue. Stop the container you just started. Find the name of your running container and replace the name in the command below with the name of the container on your system.
```console
$ docker stop wonderful_kalam
wonderful_kalam
```
Now that all of your containers are stopped, remove them. When you remove a container, it is no longer running, nor it is in the stopped status, but the process inside the container has been stopped and the metadata for the container has been removed.
```console
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce02b3179f0f python-docker "python3 -m flask ru…" 19 minutes ago Exited (0) 5 seconds ago wonderful_kalam
ec45285c456d python-docker "python3 -m flask ru…" 31 minutes ago Exited (0) 23 minutes ago agitated_moser
fb7a41809e5d python-docker "python3 -m flask ru…" 40 minutes ago Exited (0) 39 minutes ago goofy_khayyam
```
To remove a container, run the `docker rm` command with the container name. You can pass multiple container names to the command using a single command. Again, replace the container names in the following command with the container names from your system.
```console
$ docker rm wonderful_kalam agitated_moser goofy_khayyam
wonderful_kalam
agitated_moser
goofy_khayyam
```
Run the `docker ps --all` command again to see that all containers are removed.
Now, address the random naming issue. Standard practice is to name your containers for the simple reason that it is easier to identify what is running in the container and what application or service it is associated with.
To name a container, you just need to pass the `--name` flag to the `docker run` command.
```console
$ docker run -d -p 8000:5000 --name rest-server python-docker
1aa5d46418a68705c81782a58456a4ccdb56a309cb5e6bd399478d01eaa5cdda
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1aa5d46418a6 python-docker "python3 -m flask ru…" 3 seconds ago Up 3 seconds 0.0.0.0:8000->5000/tcp rest-server
```
Thats better! You can now easily identify your container based on the name.
## Summary
In this section, you took a look at running containers. You also took a look at managing containers by starting, stopping, and restarting them. And finally, you looked at naming your containers so they are more easily identifiable.
Related information:
- [docker run CLI reference](../../engine/reference/commandline/run.md)
## Next steps
In the next section, youll learn how to run a database in a container and connect it to a Python application.
{{< button text="How to develop your application" url="develop.md" >}}

View File

@ -47,15 +47,13 @@ Guides:
section:
- title: "Overview"
path: /language/python/
- title: "Build images"
path: /language/python/build-images/
- title: "Run containers"
path: /language/python/run-containers/
- title: "Containerize your app"
path: /language/python/containerize/
- title: "Develop your app"
path: /language/python/develop/
- title: "Configure CI/CD"
path: /language/python/configure-ci-cd/
- title: "Deploy your app"
- title: "Test your deployment"
path: /language/python/deploy/
- sectiontitle: Java
section: