从零开始的 DevOps(自动化基础)
回顾
我们做了什么
- 创建了一个 Django TODO 应用程序
- 在 AWS 上配置了一台虚拟机 (VM)
- 在虚拟机上安装了所需的 Python 依赖项
- 将应用程序代码上传到虚拟机
- 在虚拟机上运行了数据库迁移
- 设置了 Supervisord 用于运行、监控和保持应用程序存活
痛点
- 手写命令复杂
- 难以在不同机器间重复执行
- 保持进程存活困难
- 机器依赖性
更好的工具和流程
- 使用代码,因为它更熟悉
- 使用配置文件以实现可重用性
- 使用代码和配置进行规模化配置
- 通过容器实现可移植的基础设施
- 使用容器运行时构建和交付应用程序
- 使用容器调度器进行装箱 (bin packing)
- 使用容器调度器进行规模化扩展
自动化
基础设施 (VMs / Fabric)
*.pem
*.tar
[tool.poetry]
name = "devops-from-scratch-automated-basics"
version = "0.1.0"
description = "DevOps from Scratch (Automated Basics)"
authors = ["user "]
license = "MIT"
readme = "README.md"
#packages = [{include = "devops_from_scratch_automated_basics"}]
[tool.poetry.dependencies]
#python = "^3.10.6"
python = "^3.11"
sortedcontainers = "^2.4.0"
httpx = "^0.23.0"
invoke = "2.0.0"
fabric = "^3.0.1"
paramiko = "^3.1.0"
typer = { version = "^0.9.0", extras = ["all"] }
#[tool.poetry.group.dev.dependencies]
#black = "^23.3.0"
#pytest = "7.3.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"#+name config.ini
[ubuntu.main]
host = ubuntu@15.222.44.100
app_dir = /home/ubuntu
pem_file = ubuntu-main.pem#+name fabfile.py
import configparser
from fabric import (
Connection, Config, task,
)
# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')
def get_server_connection(server, config=config):
# 定义任务执行的主机
host = config.get(server, 'host')
# 设置 .pem 文件路径
pem_file = config.get(server, 'pem_file')
# 为连接创建配置
fab_config = Config(
overrides={
'connect_kwargs': {
'key_filename': pem_file
}
})
# 创建连接
conn = Connection(host, config=fab_config)
return conn
# Ubuntu 主配置部分名称
#server = 'ubuntu.main'
# 定义应用程序目录
#app_dir = config.get(server, 'app_dir')
@task
def machine_info(ctx, server):
# 定义服务器连接
with get_server_connection(server) as conn:
conn.run('uname')
conn.run('uname -n')
conn.run('uname -v')
conn.run('uname -m')
conn.run('lsb_release -a')
conn.run('whoami')
conn.run('date')测试 (CI / PyTest)
下次再说……
部署 (CD / Docker)
我们将采取以下步骤来准备我们的初始虚拟机:
- 获取虚拟机
- 安装 Docker
- 设置 Docker Swarm
- 将其标记为管理节点 (Master Node)
安装 Docker
# 更新现有的软件包列表
sudo apt update
# 安装一些允许 `apt` 通过 HTTPS 使用软件包的先决条件包
sudo apt install apt-transport-https ca-certificates curl software-properties-common
# 将官方 Docker 仓库的 GPG 密钥添加到您的系统
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 将 Docker 仓库添加到 APT 源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 再次更新现有的软件包列表,以便识别新增的仓库
sudo apt update
# 确保您将从 Docker 仓库而不是默认的 Ubuntu 仓库安装
apt-cache policy docker-ce
# 安装 Docker
sudo apt install docker-ce
# 检查它是否正在运行
sudo systemctl status docker#+name fabfile.py
@task
def install_docker(ctx, server):
# 定义服务器连接
with get_server_connection(server) as conn:
# 更新现有的软件包列表
conn.sudo('apt update')
# 安装一些允许 `apt` 通过 HTTPS 使用软件包的先决条件包
conn.sudo('apt install apt-transport-https ca-certificates curl software-properties-common')
# 将官方 Docker 仓库的 GPG 密钥添加到您的系统
conn.run('curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg')
# 将 Docker 仓库添加到 APT 源
conn.run('echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null')
# 再次更新现有的软件包列表,以便识别新增的仓库
conn.sudo('apt update')
# 确保您将从 Docker 仓库而不是默认的 Ubuntu 仓库安装
conn.run('apt-cache policy docker-ce')
# 安装 Docker
conn.sudo('apt install docker-ce')
# 检查它是否正在运行
conn.sudo('systemctl status docker')请注意,`install_docker` 函数不是幂等的,在执行过程中可能会在某些步骤失败。
配置 Docker
无需 `sudo` 即可运行 Docker
# 将您的用户名添加到 docker 组
sudo usermod -aG docker ${USER}应用新的组成员身份,注销服务器并重新登录(可选?)
su - ${USER}
groups#+name fabfile.py
@task
def configure_docker(ctx, server):
# 定义服务器连接
with get_server_connection(server) as conn:
# 将您的用户名添加到 docker 组
conn.sudo('usermod -aG docker ${USER}')
#conn.run('su - ${USER}')
conn.run('groups')检查 Docker 安装
检查 Docker Hub 的镜像是否可访问并可下载
docker run hello-world#+name fabfile.py
@task
def check_docker(ctx, server):
# 定义服务器连接
with get_server_connection(server) as conn:
conn.run('docker run hello-world')容器
是什么?(定义)
英语
容器是一个轻量级、独立、可执行的软件包,包含运行软件所需的一切,包括代码、运行时、库、环境变量和配置文件。容器旨在提供一致且可重复的环境,可以轻松地在不同的主机系统之间移植。它们将应用程序进程与主机隔离,提供了额外的安全层,并允许进行资源控制,从而提高了效率。
法语
Un conteneur est un package logiciel léger, autonome et exécutable qui comprend tout ce qui est nécessaire pour exécuter un logiciel, y compris le code, un environnement d'exécution, des bibliothèques, des variables d'environnement et des fichiers de configuration. Les conteneurs sont conçus pour fournir un environnement cohérent et reproductible, qui peut être facilement porté sur différents systèmes hôtes. Ils isolent le processus d'application de l'hôte, offrant une couche supplémentaire de sécurité, et permettent un contrôle des ressources, offrant une efficacité.
为什么?(好处)
英语
使用容器是因为它们提供了几个好处。首先,它们确保应用程序无论在何处、何时运行,其运行方式都是相同的,从而提高了部署速度和可靠性。其次,它们通过将应用程序及其依赖项彼此分开来提供进程隔离,从而提高了安全性。第三,它们有效地利用系统资源,从而降低了基础设施成本。
法语
Les conteneurs sont utilisés parce qu'ils offrent plusieurs avantages. Premièrement, ils garantissent que les applications fonctionnent de la même manière, quel que soit le lieu et le moment où elles sont exécutées, ce qui augmente la vitesse et la fiabilité du déploiement. Deuxièmement, ils fournissent une isolation des processus en gardant les applications et leurs dépendances séparées les unes des autres, améliorant ainsi la sécurité. Troisièmement, ils utilisent efficacement les ressources du système, ce qui réduit les coûts d'infrastructure.
何时?(LXC 与 Docker)
英语
- LXC (LinuX Containers) 是一种操作系统级虚拟化方法,允许在单个控制主机上运行多个隔离的 Linux 系统(容器)。LXC 使用 Linux 内核的 cgroups 和命名空间功能将软件应用程序及其环境与底层系统隔离开来。LXC 于 2008 年首次发布,是 Linux 容器管理器的第一个、最完整的实现。它被认为比虚拟机“更轻”,因为它在操作系统级别运行,而不是在硬件级别运行。
- Docker 是一个开源平台,用于通过将应用程序打包到容器中来自动化应用程序的部署、扩展和管理。Docker 于 2013 年推出,扩展了 LXC 的方法,为开发人员和系统管理员提供了一个标准化的接口,以开发、打包和运行与操作系统环境无关的应用程序。此后,Docker 已取代 LXC 成为主要的容器化技术。
法语
- LXC (LinuX Containers) est une méthode de virtualisation au niveau du système d'exploitation qui permet d'exécuter plusieurs systèmes Linux isolés (conteneurs) sur un seul hôte de contrôle. LXC utilise les fonctionnalités cgroups et namespace du noyau Linux pour isoler les applications logicielles et leur environnement du système sous-jacent. LXC a été lancé pour la première fois en 2008 et a été la première implémentation la plus complète du gestionnaire de conteneurs Linux. Il est considéré comme "plus léger" qu'une VM car il fonctionne au niveau du système d'exploitation, et non au niveau du matériel.
- Docker est une plateforme open source utilisée pour automatiser le déploiement, la mise à l'échelle et la gestion des applications en les emballant dans des conteneurs. Docker, introduit en 2013, a développé l'approche de LXC en fournissant une interface standardisée pour les développeurs et les administrateurs système afin de développer, empaqueter et exécuter des applications indépendamment de l'environnement d'exploitation. Docker a depuis remplacé LXC comme la principale technologie de conteneurisation.
Docker 生态系统
英语
此图涵盖了 Docker 中的一些基本概念:
graph TB
DockerEngine(Docker Engine)
DockerEngine -- Runs --> DockerContainer
DockerEngine -- Builds --> DockerImage
DockerFile(Dockerfile: Recipe for Images) -- Defines --> DockerImage
DockerHub(Docker Hub: Public Repository) -- Stores and Shares --> DockerImage
DockerContainer(Docker Container: Tiny, stand-alone, executable package)
DockerImage(Docker Image: Blueprints for Containers) -- Creates --> DockerContainer
subgraph "Analogy: Construction"
DockerFile -- "Architect's Plan" --> DockerImage
DockerImage -- "Pre-fab house parts" --> DockerContainer
end- Docker Engine:构建和运行容器的运行时。这就像一家建造和维护房屋的建筑公司。
- Dockerfile:一个文本文档,包含用户可以在命令行上调用以组装镜像的所有命令。它就像房屋的建筑师蓝图。
- Docker Image:Docker 的蓝图,代表容器的特定实例。它就像房屋的预制件,准备好进行建造。
- Docker Container:一个可执行的软件包,包含运行应用程序所需的一切。这就像基于预制件(镜像)建造好的房屋。
- Docker Hub:一个基于云的注册表服务,允许您链接到代码仓库、构建镜像并对其进行测试。这就像各种预制房屋部件的公共展示或存储,任何建筑公司(Docker Engine)都可以使用。
法语
graph TB
DockerEngine(Moteur Docker)
DockerEngine -- Exécute --> DockerContainer
DockerEngine -- Construit --> DockerImage
DockerFile(Fichier Docker: Recette pour les Images) -- Définit --> DockerImage
DockerHub(Hub Docker: Dépôt Public) -- Stocke et Partage --> DockerImage
DockerContainer(Conteneur Docker: Petit paquet exécutable autonome)
DockerImage(Image Docker: Plans pour les Conteneurs) -- Crée --> DockerContainer
subgraph "Analogie: Construction"
DockerFile -- "Plan d'architecte" --> DockerImage
DockerImage -- "Pièces préfabriquées de maison" --> DockerContainer
endCe diagramme couvre quelques concepts de base de Docker :
- Docker Engine (Moteur Docker): L'environnement d'exécution qui construit et exécute des conteneurs. C'est comme une entreprise de construction qui construit et entretient des maisons.
- Dockerfile (Fichier Docker): Un document texte qui contient toutes les commandes qu'un utilisateur pourrait appeler sur la ligne de commande pour assembler une image. C'est comme le plan d'un architecte pour une maison.
- Docker Image (Image Docker): Le plan de Docker qui représente une instance spécifique d'un conteneur. C'est comme les pièces préfabriquées d'une maison, prêtes à être construites.
- Docker Container (Conteneur Docker): Un paquet exécutable qui comprend tout ce qui est nécessaire pour exécuter une application. C'est comme la maison construite, basée sur les pièces préfabriquées (Image).
- Docker Hub (Hub Docker): Un service de registre basé sur le cloud qui vous permet de lier à des dépôts de code, de construire vos images et de les tester. C'est comme une présentation publique ou un stockage de diverses pièces de maison préfabriquées, qui peuvent être utilisées par n'importe quelle entreprise de construction (Moteur Docker).
Docker Swarm
英语
Docker Swarm 是内置于 Docker 中的容器编排工具。它允许您管理多个 Docker 主机(节点)并将服务部署到它们,使它们表现得像一个单一的大型主机。Swarm 中的节点相互通信,以确保它们保持您部署的服务的期望状态。
让我们用一个类比来解释它。将 Docker Swarm 想象成管弦乐队的指挥,每个音乐家(Docker 主机/节点)都有特定的部分要演奏(任务),而指挥(Docker Swarm)确保每个人都和谐地演奏,以创造美妙的音乐(平稳运行的应用程序)。
这是一个说明 Docker Swarm 如何工作的 Mermaid 图:
graph LR
DockerSwarm(Docker Swarm: Orchestra Conductor)
DockerHost1(Docker Host 1: Musician 1)
DockerHost2(Docker Host 2: Musician 2)
DockerHost3(Docker Host 3: Musician 3)
DockerSwarm --> DockerHost1
DockerSwarm --> DockerHost2
DockerSwarm --> DockerHost3
subgraph ServicesOnHost1
Service1a(Service 1: Musical Score 1)
Service1b(Service 2: Musical Score 2)
end
subgraph ServicesOnHost2
Service2a(Service 1: Musical Score 1)
Service2b(Service 2: Musical Score 2)
end
subgraph ServicesOnHost3
Service3a(Service 1: Musical Score 1)
Service3b(Service 2: Musical Score 2)
end
DockerHost1 --> ServicesOnHost1
DockerHost2 --> ServicesOnHost2
DockerHost3 --> ServicesOnHost3在此图中:
- Docker Swarm:这是管弦乐队的指挥,管理每个 Docker 主机(或节点)如何运行其服务。
- Docker Hosts (1, 2, 3):管弦乐队中的音乐家,每个人都根据乐谱(服务)演奏自己的部分。
- Services (1, 2):乐谱,代表每个 Docker 主机需要执行的不同任务。每个 Docker 主机可能运行多个服务,就像音乐家可能在同一首乐曲中演奏不同的部分一样。
箭头表示 Docker Swarm 管理 Docker 主机,就像指挥指导管弦乐队中的音乐家一样;每个 Docker 主机管理其服务,就像音乐家遵循他们的乐谱一样。
法语
Docker Swarm est un outil d'orchestration de conteneurs intégré à Docker. Il permet de gérer plusieurs hôtes Docker (nœuds) et de déployer des services sur ceux-ci de manière à ce qu'ils agissent comme un seul et grand hôte. Les nœuds d'un Swarm communiquent entre eux pour garantir qu'ils maintiennent l'état souhaité des services que vous déployez.
Prenons une analogie. Pensez à Docker Swarm comme à un chef d'orchestre, où chaque musicien (hôte Docker/nœud) a une partie spécifique à jouer (tâche), et le chef d'orchestre (Docker Swarm) veille à ce que tout le monde joue en harmonie pour créer une belle musique (application fonctionnant sans accroc).
Voici un diagramme Mermaid qui illustre comment fonctionne Docker Swarm:
graph LR
DockerSwarm(Docker Swarm: Chef d'Orchestre)
DockerHost1(Hôte Docker 1: Musicien 1)
DockerHost2(Hôte Docker 2: Musicien 2)
DockerHost3(Hôte Docker 3: Musicien 3)
DockerSwarm --> DockerHost1
DockerSwarm --> DockerHost2
DockerSwarm --> DockerHost3
subgraph ServicesOnHost1
Service1a(Service 1: Partition Musicale 1)
Service1b(Service 2: Partition Musicale 2)
end
subgraph ServicesOnHost2
Service2a(Service 1: Partition Musicale 1)
Service2b(Service 2: Partition Musicale 2)
end
subgraph ServicesOnHost3
Service3a(Service 1: Partition Musicale 1)
Service3b(Service 2: Partition Musicale 2)
end
DockerHost1 --> ServicesOnHost1
DockerHost2 --> ServicesOnHost2
DockerHost3 --> ServicesOnHost3Dans ce diagramme :
- Docker Swarm: Il s'agit du chef d'orchestre, qui gère la façon dont chaque hôte Docker (ou nœud) exécute ses services.
- Hôtes Docker (1, 2, 3): Ce sont les musiciens de l'orchestre, chacun jouant son rôle en fonction des partitions musicales (services).
- Services (1, 2): Ce sont les partitions musicales, représentant les différentes tâches que chaque hôte Docker doit accomplir. Chaque hôte Docker peut exécuter plusieurs services, tout comme un musicien peut jouer différentes parties dans la même pièce musicale.
Les flèches représentent Docker Swarm qui gère les hôtes Docker, comme un chef d'orchestre dirigeant les musiciens dans un orchestre, et chaque hôte Docker gère ses services, comme un musicien suivant ses partitions musicales.
Docker 上的 Django 应用程序栈
英语
这是一个高级概述:
- 首先,为您的 Django 应用程序创建一个 Dockerfile,它将成为构建应用程序 Docker 镜像的蓝图。
- 然后,定义一个 Docker Compose 文件 (docker-compose.yml),它将描述应用程序的多容器 Docker 环境。此文件将包含 Django 应用程序容器和 Postgres 数据库容器的配置。
- 最后,使用 Docker Compose 命令构建并启动您的应用程序。
graph TB
DockerComposeFile[Docker Compose File]
DockerComposeCommand{Docker Compose Commands}
DockerComposeFile --> DjangoAppDockerFile[Django App Dockerfile]
DjangoAppDockerFile --> DjangoAppImage[Django App Docker Image]
DjangoAppImage --> DjangoAppContainer[Django App Container]
DockerComposeFile --> PostgresImage[Postgres Docker Image]
PostgresImage --> PostgresContainer[Postgres Container]
DockerComposeCommand --> DockerComposeFile
DjangoAppContainer -- Connects To --> PostgresContainer
subgraph "Application Stack"
DjangoAppContainer -- "Django Application" --> PostgresContainer
end此图表示该过程:
- Docker Compose File:此文件包含应用程序的多容器 Docker 配置。
- Docker Compose Commands:这是您运行以启动 Docker Compose 环境的命令。
- Django App Dockerfile:这是 Django 应用程序的 Dockerfile。它就像创建 Django 应用程序 Docker 镜像的蓝图。
- Django App Docker Image:这是从 Django 应用程序的 Dockerfile 创建的 Docker 镜像。
- Django App Container:这是运行 Django 应用程序的 Docker 容器。它是从 Django 应用程序的 Docker 镜像创建的。
- Postgres Docker Image:这是 Postgres 数据库的 Docker 镜像。它通常从 Docker Hub 下载。
- Postgres Container:这是运行 Postgres 数据库的 Docker 容器。它是从 Postgres Docker 镜像创建的。
Django App Container 和 Postgres Container 节点之间标记为“Connects To”的箭头表示 Django 应用程序连接到 Postgres 数据库。
标题为“Application Stack”的子图表示您的完整应用程序栈,包括 Django 应用程序和 Postgres 数据库。
法语
Voici un aperçu de haut niveau :
- Premièrement, créez un Dockerfile pour votre application Django, qui sera le plan pour construire une image Docker de votre application.
- Ensuite, définissez un fichier Docker Compose (docker-compose.yml), qui décrira l'environnement Docker multi-conteneur pour votre application. Ce fichier inclura la configuration pour votre conteneur d'application Django et le conteneur de base de données Postgres.
- Enfin, utilisez les commandes Docker Compose pour construire et démarrer votre application.
graph TB
DockerComposeFile[Fichier Docker Compose]
DockerComposeCommand{Commandes Docker Compose}
DockerComposeFile --> DjangoAppDockerFile[Dockerfile App Django]
DjangoAppDockerFile --> DjangoAppImage[Image Docker App Django]
DjangoAppImage --> DjangoAppContainer[Conteneur App Django]
DockerComposeFile --> PostgresImage[Image Docker Postgres]
PostgresImage --> PostgresContainer[Conteneur Postgres]
DockerComposeCommand --> DockerComposeFile
DjangoAppContainer -- Se Connecte à --> PostgresContainer
subgraph "Pile d'Applications"
DjangoAppContainer -- "Application Django" --> PostgresContainer
endCe diagramme représente le processus :
- Fichier Docker Compose : Ce fichier contient la configuration Docker multi-conteneur pour votre application.
- Commandes Docker Compose : Ce sont les commandes que vous exécutez pour démarrer votre environnement Docker Compose.
- Dockerfile App Django : C'est le Dockerfile pour votre application Django. C'est comme un plan pour créer une image Docker de votre application Django.
- Image Docker App Django : C'est l'image Docker créée à partir du Dockerfile pour votre application Django.
- Conteneur App Django : C'est le conteneur Docker exécutant votre application Django. Il est créé à partir de l'image Docker de votre application Django.
- Image Docker Postgres : C'est l'image Docker pour la base de données Postgres. Elle est généralement téléchargée depuis Docker Hub.
- Conteneur Postgres : C'est le conteneur Docker exécutant votre base de données Postgres. Il est créé à partir de l'image Docker Postgres.
La flèche étiquetée "Se Connecte à" entre les nœuds Conteneur App Django et Conteneur Postgres indique que l'application Django se connecte à la base de données Postgres.
Le sous-graphique intitulé "Pile d'Applications" représente votre pile d'applications complète, incluant l'application Django et la base de données Postgres.
演示
构建本地容器
将 Dockerfile 添加到项目中:
#+name Dockerfile
FROM python:3.10.6-bullseye
ENV PIP_NO_CACHE_DIR=True
ENV POETRY_VIRTUAL_ENVS_CREATE=False
RUN pip install -U \
pip \
setuptools \
wheel \
poetry
WORKDIR /app
RUN useradd -m -r user && \
chown user /app
COPY pyproject.toml poetry.lock ./
#RUN poetry install --no-dev
#RUN poetry install --no-dev && \
# rm -rf ~/.cache/pypoetry/{cache,artifacts}
RUN poetry export --without-hashes -f requirements.txt -o requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
RUN python3 manage.py migrate
USER user
EXPOSE 8000/tcp
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]构建容器:
docker build -t mytodos:v1 ./导出 Docker 镜像归档 (.tar 文件)
docker save mytodos:v1 > mytodos_app_container.tar上传 Docker 镜像归档并安装
#+name fabfile.py
@task
def upload_and_install_docker_archive(ctx, server, docker_archive_src, docker_archive_dest):
# 定义服务器连接
with get_server_connection(server) as conn:
# 上传 Docker 镜像归档
conn.put(docker_archive_src, docker_archive_dest)
# 安装 Docker 归档
conn.run(f'docker load -i {docker_archive_dest}')运行 Docker 镜像
#+name fabfile.py
@task
def remote_exec(ctx, server, cmd):
# 定义服务器连接
with get_server_connection(server) as conn:
# 执行命令
conn.run(cmd)修复任何不兼容性
修复方法是:
docker buildx build --platform linux/amd64 -t mytodos:v1 ./docker save mytodos:v2 > mytodos_app_container.tarDocker Swarm
fab remote-exec ubuntu.main "docker swarm init"#+name config.ini
[ubuntu.worker1]
host = ubuntu@35.183.61.2
app_dir = /home/ubuntu
pem_file = ubuntu-worker1.pem
token = SWMTKN-1-24z5u12objl9qho41g77nhkmds8qpjoea9ta8mpvfvwxojjs3y-2k5buiwingdxa97zalxu2076b 172.26.7.85:2377#+name config.ini
[ubuntu.worker2]
host = ubuntu@15.156.205.168
app_dir = /home/ubuntu
pem_file = ubuntu-worker2.pem
token = SWMTKN-1-24z5u12objl9qho41g77nhkmds8qpjoea9ta8mpvfvwxojjs3y-2k5buiwingdxa97zalxu2076b 172.26.7.85:2377docker swarm join --token SWMTKN-1-24z5u12objl9qho41g77nhkmds8qpjoea9ta8mpvfvwxojjs3y-2k5buiwingdxa97zalxu2076b 172.26.7.85:2377
docker node ls # 检查 Swarm 集群
docker stack deploy -c docker-compose.yaml mytodos # 使用服务名称 mytodos 部署堆栈我的 Django TODOs 应用程序栈
DATABASES = {
"default": {
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
"NAME": os.environ.get("SQL_DATABASE", BASE_DIR / "db.sqlite3"),
"USER": os.environ.get("SQL_USER", "user"),
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
"HOST": os.environ.get("SQL_HOST", "localhost"),
"PORT": os.environ.get("SQL_PORT", "5432"),
}
}#+name docker-compose.yaml
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
web:
image: mytodos:v3
#build: .
command: python manage.py runserver 0.0.0.0:8000
#volumes:
# - .:/code
ports:
- "8000:8000"
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
depends_on:
- db
