|
|||||||||||||||||||||||||||||||||||||
|
Характерные примеры 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 Преимущества такого подхода:
Разница между двумя подходами:
Оба подхода дополняют друг друга и используются в зависимости от потребностей проекта! |
|||||||||||||||||||||||||||||||||||||
|
Так же в этом разделе:
|
|||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||
|