MyTetra Share
Делитесь знаниями!
Характерные примеры Docker и Docker Compose
Время создания: 30.03.2026 22:08
Автор: alensav
Текстовые метки: Docker и Docker Compose
Раздел: UBUNTU_24-04
Запись: alensav/MyTetra2/main/base/1774897711w9n2dsa4c8/text.html на raw.githubusercontent.com

Характерные примеры Docker и Docker Compose

🐳 Пример 1: Docker (одиночный контейнер)

Сценарий: Разработка Python-приложения с изолированным окружением

Представьте, что вы разрабатываете Telegram-бота на Python, которому нужны специфические версии библиотек и системные зависимости.

Структура проекта:

text

telegram-bot/

├── bot.py

├── requirements.txt

└── Dockerfile

1. bot.py (сам бот)

python

import logging

from telegram import Update

from telegram.ext import Application, CommandHandler, ContextTypes


# Настройка логирования

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',

level=logging.INFO)


# Команда /start

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):

await update.message.reply_text('Привет! Я бот, работающий в Docker!')


# Команда /help

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):

await update.message.reply_text('Доступные команды:\n/start - приветствие\n/help - помощь')


def main():

# Токен бота (в реальном проекте брать из переменных окружения)

token = "YOUR_BOT_TOKEN"

# Создание приложения

application = Application.builder().token(token).build()

# Добавление обработчиков

application.add_handler(CommandHandler("start", start))

application.add_handler(CommandHandler("help", help_command))

# Запуск бота

application.run_polling()


if __name__ == '__main__':

main()

2. requirements.txt (зависимости Python)

txt

python-telegram-bot==20.7

requests==2.31.0

3. Dockerfile (описание образа)

dockerfile

# Базовый образ с Python 3.11

FROM python:3.11-slim


# Установка системных зависимостей (если нужны)

RUN apt-get update && apt-get install -y \

gcc \

&& rm -rf /var/lib/apt/lists/*


# Установка рабочей директории

WORKDIR /app


# Копирование файлов зависимостей

COPY requirements.txt .


# Установка Python-зависимостей

RUN pip install --no-cache-dir -r requirements.txt


# Копирование исходного кода

COPY bot.py .


# Запуск бота

CMD ["python", "bot.py"]

Сборка и запуск:

bash

# Сборка образа

docker build -t telegram-bot .


# Запуск контейнера

docker run -d --name my-bot telegram-bot


# Просмотр логов

docker logs -f my-bot


# Остановка

docker stop my-bot


# Удаление

docker rm my-bot

Запуск с переменными окружения (безопаснее):

bash

docker run -d \

--name my-bot \

-e BOT_TOKEN="your_token_here" \

telegram-bot


🐳🐳 Пример 2: Docker Compose (многоконтейнерное приложение)

Сценарий: Веб-приложение с бэкендом, базой данных и кэшем

Представьте, что вы разрабатываете интернет-магазин с Flask (Python), PostgreSQL и Redis.

Структура проекта:

text

ecommerce/

├── app/

│ ├── app.py

│ ├── requirements.txt

│ └── Dockerfile

├── docker-compose.yml

├── .env

└── nginx/

└── nginx.conf

1. app/app.py (Flask приложение)

python

import os

import redis

import psycopg2

from flask import Flask, jsonify, request

from flask_caching import Cache


app = Flask(__name__)


# Конфигурация из переменных окружения

app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')

app.config['CACHE_TYPE'] = 'RedisCache'

app.config['CACHE_REDIS_HOST'] = os.getenv('REDIS_HOST', 'redis')

app.config['CACHE_REDIS_PORT'] = 6379

app.config['CACHE_REDIS_DB'] = 0


cache = Cache(app)


# Подключение к БД

def get_db_connection():

conn = psycopg2.connect(

host=os.getenv('DB_HOST', 'postgres'),

database=os.getenv('DB_NAME', 'ecommerce'),

user=os.getenv('DB_USER', 'user'),

password=os.getenv('DB_PASSWORD', 'password')

)

return conn


# Создание таблиц (для демо)

def init_db():

conn = get_db_connection()

cur = conn.cursor()

cur.execute('''

CREATE TABLE IF NOT EXISTS products (

id SERIAL PRIMARY KEY,

name VARCHAR(100),

price DECIMAL(10,2),

stock INTEGER

)

''')

conn.commit()

cur.close()

conn.close()


@app.route('/')

def hello():

return jsonify({'message': 'Добро пожаловать в интернет-магазин!'})


@app.route('/products')

@cache.cached(timeout=60) # Кэширование на 60 секунд

def get_products():

conn = get_db_connection()

cur = conn.cursor()

cur.execute('SELECT * FROM products')

products = cur.fetchall()

cur.close()

conn.close()

return jsonify([{'id': p[0], 'name': p[1], 'price': str(p[2]), 'stock': p[3]} for p in products])


@app.route('/products', methods=['POST'])

def add_product():

data = request.json

conn = get_db_connection()

cur = conn.cursor()

cur.execute(

'INSERT INTO products (name, price, stock) VALUES (%s, %s, %s)',

(data['name'], data['price'], data['stock'])

)

conn.commit()

cur.close()

conn.close()

# Очистка кэша

cache.delete('get_products')

return jsonify({'message': 'Товар добавлен'}), 201


@app.route('/stats')

def stats():

# Информация о Redis

r = redis.Redis(host=os.getenv('REDIS_HOST', 'redis'), port=6379, db=0)

redis_info = r.info()

return jsonify({

'redis_keys': redis_info['db0']['keys'],

'redis_used_memory': redis_info['used_memory_human']

})


if __name__ == '__main__':

init_db()

app.run(host='0.0.0.0', port=5000)

2. app/requirements.txt

txt

Flask==3.0.0

psycopg2-binary==2.9.9

redis==5.0.1

flask-caching==2.1.0

3. app/Dockerfile

dockerfile

FROM python:3.11-slim


WORKDIR /app


COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt


COPY app.py .


CMD ["python", "app.py"]

4. docker-compose.yml (главный файл)

yaml

version: '3.8'


services:

# PostgreSQL база данных

postgres:

image: postgres:15-alpine

container_name: ecommerce-postgres

environment:

POSTGRES_DB: ${DB_NAME:-ecommerce}

POSTGRES_USER: ${DB_USER:-user}

POSTGRES_PASSWORD: ${DB_PASSWORD:-password}

volumes:

- postgres_data:/var/lib/postgresql/data

ports:

- "5432:5432"

networks:

- ecommerce-network

healthcheck:

test: ["CMD-SHELL", "pg_isready -U user"]

interval: 10s

timeout: 5s

retries: 5


# Redis кэш

redis:

image: redis:7-alpine

container_name: ecommerce-redis

command: redis-server --appendonly yes

volumes:

- redis_data:/data

ports:

- "6379:6379"

networks:

- ecommerce-network

healthcheck:

test: ["CMD", "redis-cli", "ping"]

interval: 10s

timeout: 5s

retries: 5


# Flask приложение

app:

build: ./app

container_name: ecommerce-app

environment:

DB_HOST: postgres

DB_NAME: ${DB_NAME:-ecommerce}

DB_USER: ${DB_USER:-user}

DB_PASSWORD: ${DB_PASSWORD:-password}

REDIS_HOST: redis

DATABASE_URL: postgresql://${DB_USER:-user}:${DB_PASSWORD:-password}@postgres/${DB_NAME:-ecommerce}

depends_on:

postgres:

condition: service_healthy

redis:

condition: service_healthy

ports:

- "5000:5000"

networks:

- ecommerce-network

volumes:

- ./app:/app # для разработки (горячая перезагрузка)

restart: unless-stopped


# Nginx (опционально, как reverse proxy)

nginx:

image: nginx:alpine

container_name: ecommerce-nginx

volumes:

- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf

ports:

- "80:80"

depends_on:

- app

networks:

- ecommerce-network

restart: unless-stopped


# Тома для персистентности данных

volumes:

postgres_data:

redis_data:


# Сети

networks:

ecommerce-network:

driver: bridge

5. .env (переменные окружения)

env

DB_NAME=ecommerce

DB_USER=admin

DB_PASSWORD=strong_password_123

6. nginx/nginx.conf (прокси)

nginx

server {

listen 80;

server_name localhost;


location / {

proxy_pass http://app:5000;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

}

}


Запуск всего стека:

bash

# Запуск всех сервисов в фоне

docker compose up -d


# Просмотр статуса

docker compose ps


# Просмотр логов всех сервисов

docker compose logs -f


# Просмотр логов конкретного сервиса

docker compose logs -f app


# Выполнение команды внутри контейнера (например, создание миграций)

docker compose exec app python -c "from app import init_db; init_db()"


# Масштабирование приложения (запуск 3 экземпляров app)

docker compose up -d --scale app=3


# Проверка работоспособности

curl http://localhost/products

curl -X POST http://localhost/products \

-H "Content-Type: application/json" \

-d '{"name":"Ноутбук","price":999.99,"stock":10}'


# Остановка всех сервисов

docker compose down


# Остановка с удалением томов (очистка данных)

docker compose down -v


Преимущества такого подхода:


Аспект

Реализация

Изоляция

Каждый сервис в своём контейнере

Персистентность

Тома для БД и Redis

Разработка

Монтирование кода для hot-reload

Сети

Изолированная сеть между сервисами

Зависимости

Управление порядком запуска через depends_on

Масштабирование

Легко добавить реплики

Конфигурация

Переменные окружения из .env


Разница между двумя подходами:


Характеристика

Docker (один контейнер)

Docker Compose

Сложность

Простота

Умеренная

Сценарий

Отдельный сервис

Связанные сервисы

Сети

Ручная настройка

Автоматические

Управление

Отдельные команды

Единая команда

Разработка

Базовая

Удобная (hot-reload)

Продакшен

Возможен

Требует доработки

Оба подхода дополняют друг друга и используются в зависимости от потребностей проекта!



 
MyTetra Share v.0.67
Яндекс индекс цитирования