Пълно ръководство за Docker и Docker Compose

Пълно ръководство за Docker и Docker Compose

Пълно ръководство за Docker и Docker Compose | UrociBG

Научете всичко необходимо за контейнеризацията – от основите до напреднали техники

20+ минути четене
15+ практически примера
100% безплатно

Съдържание

Какво е Docker?

Docker е революционна платформа за контейнеризация, която променя начина, по който разработваме, доставяме и управляваме приложения. За разлика от традиционните методи на разработка, Docker позволява опаковането на приложения заедно с всички техни зависимости в леки, портативни контейнери.

Важно за разбиране

Представете си Docker като универсална кутия за доставка, която може да съдържа всякакви стоки (вашето приложение) и да бъде транспортирана безопасно навсякъде по света (всеки сървър), без да се притеснявате за съвместимостта.

Кратка история на Docker

Docker беше създаден през 2013 година от Solomon Hykes в компанията dotCloud (по-късно преименувана на Docker Inc.). Проектът бързо стана популярен сред разработчиците поради способността му да решава проблема "работи на моята машина, но не работи на сървъра".

Пълна консистентност

Вашето приложение ще работи абсолютно еднакво във всяка среда – от лаптопа ви до продукционния сървър. Забравете за проблемите със съвместимостта!

Изключителна ефективност

Контейнерите са до 10 пъти по-леки от виртуалните машини, тъй като споделят ядрото на операционната система, но остават напълно изолирани.

Истинска портабилност

Създайте веднъж, стартирайте навсякъде! Контейнерите работят еднакво на Windows, macOS, Linux и всички облачни платформи.

Лесно скалиране

Стартирайте десетки копия на вашето приложение за секунди. Docker прави хоризонталното скалиране детска игра.

Подобрена сигурност

Всеки контейнер е изолиран и не може да повлияе на другите. Ако нещо се счупи, проблемът остава в рамките на един контейнер.

Бързо внедряване

Стартирането на нов контейнер отнема секунди, за разлика от минутите, необходими за стартиране на виртуална машина.

Защо да използвате Docker?

Проблемите, които Docker решава

Преди Docker, разработчиците се сблъскваха с множество предизвикателства:

  • "Работи на моята машина" синдромът – Приложенията работят различно на различните машини
  • Сложна настройка на среди – Всеки разработчик трябва да конфигурира средата си
  • Зависимости към операционната система – Различни версии на библиотеки създават конфликти
  • Трудно скалиране – Добавянето на нови сървъри е бавен и сложен процес
  • Проблеми с връщането назад – Трудно е да се върнете към предишна версия

Традиционен подход

  • Дълга и сложна настройка на среди
  • Различни конфигурации за всяка машина
  • Конфликти между зависимости
  • Трудно репликиране на production среда
  • Бавно стартиране на приложения
  • Сложно внедряване на нови версии
  • Ограничени възможности за скалиране

Docker подход

  • Еднократна настройка, работи навсякъде
  • Еднаква конфигурация за всички
  • Пълна изолация на зависимости
  • Идентични среди за development и production
  • Мгновено стартиране на контейнери
  • Безопасно и бързо внедряване
  • Автоматично скалиране по необходимост

Статистика

Според проучване на Stack Overflow от 2023 г., над 69% от професионалните разработчици използват Docker в ежедневната си работа, което го прави един от най-популярните инструменти в индустрията.

Основни концепции в Docker

Docker Image (Образ)

Docker образът е като "снимка" или "шаблон" на файлова система, която съдържа всичко необходимо за стартиране на приложение:

  • Операционна система – обикновено минимална Linux дистрибуция
  • Runtime среда – например Node.js, Python, Java
  • Библиотеки и зависимости – всички npm пакети, pip модули и т.н.
  • Код на приложението – вашите файлове
  • Конфигурация – настройки и метаданни

Наслоена архитектура

Docker образите използват наслоена файлова система. Всеки слой съдържа промените спрямо предишния. Това позволява ефективно споделяне на общи компоненти между различни образи.

Docker Container (Контейнер)

Контейнерът е работеща инстанция на образ. Това е изолирана среда, която:

  • Има собствена файлова система
  • Може да има собствени мрежови настройки
  • Работи като отделен процес в операционната система
  • Може да бъде стартиран, спрян, изтрит и рестартиран

Dockerfile

Dockerfile е текстов файл с инструкции за създаване на Docker образ. Всяка инструкция създава нов слой в образа:

Пример за базов Dockerfile
# Базов образ - официален Node.js образ
FROM node:18-alpine

# Информация за създателя
LABEL maintainer="[email protected]"

# Работна директория в контейнера
WORKDIR /app

# Копиране на package.json и package-lock.json
COPY package*.json ./

# Инсталиране на зависимости
RUN npm ci --only=production

# Копиране на останалия код
COPY . .

# Създаване на не-root потребител за сигурност
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Промяна на собственика на файловете
RUN chown -R nextjs:nodejs /app
USER nextjs

# Порт, който приложението използва
EXPOSE 3000

# Команда за стартиране на приложението
CMD ["npm", "start"]

Обяснение на инструкциите:

  • FROM – Определя базовия образ
  • WORKDIR – Задава работната директория
  • COPY – Копира файлове от хост машината в образа
  • RUN – Изпълнява команди по време на създаването на образа
  • EXPOSE – Декларира порт, който контейнерът използва
  • CMD – Определя командата за стартиране на контейнера

Docker архитектура

Docker Host

Машината, която стартира Docker

Docker Daemon

Управлява контейнери и образи

Docker Client

Командният ред интерфейс

Docker Registry

Хранилище за образи (Docker Hub)

Инсталиране и настройка

Docker може да бъде инсталиран на всички основни операционни системи. Ето подробни инструкции за всяка платформа:

Ubuntu/Debian

Актуализиране на системата

sudo apt update
sudo apt upgrade -y

Инсталиране на необходимите пакети

sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

Добавяне на официалния GPG ключ на Docker

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Добавяне на Docker repository

echo \
  "deb [arch=amd64 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

Инсталиране на Docker Engine

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Стартиране и активиране на Docker

sudo systemctl enable docker
sudo systemctl start docker

Добавяне на потребителя към docker групата

sudo usermod -aG docker $USER

Важно!

След тази команда трябва да излезете от терминала и да влезете отново, или да рестартирате системата, за да влезе в сила промяната.

Windows

За Windows се препоръчва използването на Docker Desktop:

  1. Посетете официалния сайт на Docker Desktop
  2. Изтеглете инсталатора за Windows
  3. Стартирайте инсталатора и следвайте инструкциите
  4. Рестартирайте компютъра
  5. Стартирайте Docker Desktop от Start менюто

macOS

За macOS също се използва Docker Desktop:

  1. Изтеглете Docker Desktop за Mac
  2. Отворете .dmg файла
  3. Плъзнете Docker в Applications папката
  4. Стартирайте Docker от Applications

Проверка на инсталацията

Проверка на версията
docker --version
docker-compose --version
Docker version 24.0.7, build afdd53b Docker Compose version v2.23.3-desktop.2
Тест за правилна работа
docker run hello-world

Успешна инсталация

Ако виждате съобщение "Hello from Docker!", вашата инсталация е успешна и готова за използване!

Първи стъпки с Docker

Сега, когато Docker е инсталиран, нека направим първите ни стъпки. Ще започнем с основните команди и постепенно ще преминем към по-сложни операции.

Изтегляне на образи

Docker Hub е официалното хранилище за Docker образи. Там можете да намерите образи за почти всички популярни технологии.

Изтегляне на популярни образи
# Официален Ubuntu образ
docker pull ubuntu:22.04

# Официален Node.js образ
docker pull node:18-alpine

# Официален Python образ
docker pull python:3.11-slim

# Nginx web сървър
docker pull nginx:alpine

Стартиране на първия контейнер

Интерактивен Ubuntu контейнер
# Стартиране на интерактивен Ubuntu контейнер
docker run -it ubuntu:22.04 /bin/bash

# След стартиране ще влезете в bash shell на контейнера
# Можете да изпълнявате команди като:
ls -la
cat /etc/os-release
exit  # за излизане

Обяснение на параметрите

  • -i (interactive) – запазва STDIN отворен
  • -t (tty) – създава псевдо TTY
  • -it – комбинация от двата параметъра за интерактивна работа

Основни команди за управление

Преглед на контейнери и образи
# Списък с всички работещи контейнери
docker ps

# Списък с всички контейнери (включително спрените)
docker ps -a

# Списък с всички образи
docker images

# Детайлна информация за контейнер
docker inspect 

# Статистики за ресурсите на контейнерите
docker stats

Стартиране на web сървър

Нека стартираме простичък Nginx web сървър:

Nginx web сървър
# Стартиране на Nginx на порт 8080
docker run -d -p 8080:80 --name my-nginx nginx:alpine

# Проверка дали работи
curl http://localhost:8080

# Или отворете http://localhost:8080 в браузъра си

Обяснение на параметрите

  • -d (detached) – стартира контейнера в background
  • -p 8080:80 – пренасочва порт 8080 от хоста към порт 80 в контейнера
  • –name my-nginx – дава име на контейнера за лесно управление

Спиране и изтриване на контейнери

Управление на контейнери
# Спиране на контейнер
docker stop my-nginx

# Стартиране на спрян контейнер
docker start my-nginx

# Рестартиране на контейнер
docker restart my-nginx

# Изтриване на спрян контейнер
docker rm my-nginx

# Принудително изтриване на работещ контейнер
docker rm -f my-nginx

# Изтриване на всички спрени контейнери
docker container prune

Преглед на логове

Работа с логове
# Преглед на логовете на контейнер
docker logs my-nginx

# Следене на логовете в реално време
docker logs -f my-nginx

# Последните 50 реда от логовете
docker logs --tail 50 my-nginx

# Логове с timestamps
docker logs -t my-nginx

Създаване на Dockerfile

Dockerfile е рецептата за създаване на ваши собствени Docker образи. Нека създадем практически пример с Node.js приложение.

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

Първо, нека създадем примерно Node.js приложение:

package.json
{
  "name": "docker-example-app",
  "version": "1.0.0",
  "description": "Примерно приложение за Docker",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}
server.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Здравей от Docker контейнер!',
    timestamp: new Date().toISOString(),
    nodeVersion: process.version
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'OK', uptime: process.uptime() });
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Сървърът работи на порт ${PORT}`);
});

Оптимизиран Dockerfile

Dockerfile с най-добри практики
# Използваме официален Node.js образ базиран на Alpine Linux
FROM node:18-alpine

# Добавяме метаданни
LABEL maintainer="[email protected]"
LABEL version="1.0"
LABEL description="Примерно Node.js приложение с Docker"

# Инсталираме dumb-init за правилно управление на процеси
RUN apk add --no-cache dumb-init

# Създаваме не-root потребител за сигурност
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Задаваме работна директория
WORKDIR /app

# Копираме package файловете първо (за по-добро кеширане)
COPY --chown=nextjs:nodejs package*.json ./

# Инсталираме зависимостите
RUN npm ci --only=production && npm cache clean --force

# Копираме останалия код
COPY --chown=nextjs:nodejs . .

# Преминаваме към не-root потребител
USER nextjs

# Декларираме порта
EXPOSE 3000

# Добавяме health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js

# Използваме dumb-init като PID 1
ENTRYPOINT ["dumb-init", "--"]

# Стартираме приложението
CMD ["node", "server.js"]

Health Check файл

healthcheck.js
const http = require('http');

const options = {
  hostname: 'localhost',
  port: 3000,
  path: '/health',
  method: 'GET',
  timeout: 2000
};

const req = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

req.on('error', () => {
  process.exit(1);
});

req.end();

.dockerignore файл

Подобно на .gitignore, .dockerignore определя кои файлове да НЕ се копират в образа:

.dockerignore
# Зависимости
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime данни
pids
*.pid
*.seed
*.pid.lock

# Coverage директория използвана от инструменти като istanbul
coverage
*.lcov

# Документация
README.md
.gitignore
.git

# IDE файлове
.vscode
.idea
*.swp
*.swo

# OS файлове
.DS_Store
Thumbs.db

# Docker файлове
Dockerfile*
docker-compose*

Създаване на образа

Build команди
# Създаване на образ
docker build -t my-node-app:1.0 .

# Създаване с подробен изход
docker build -t my-node-app:1.0 --progress=plain .

# Създаване без кеш
docker build -t my-node-app:1.0 --no-cache .

# Стартиране на контейнер от нашия образ
docker run -d -p 3000:3000 --name my-app my-node-app:1.0

Multi-stage Build

За по-малки production образи можем да използваме multi-stage build:

Dockerfile с multi-stage build
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build  # ако имаме build process

# Production stage
FROM node:18-alpine AS production
RUN apk add --no-cache dumb-init
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

WORKDIR /app
COPY --chown=nextjs:nodejs package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Копираме само необходимите файлове от build stage
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --chown=nextjs:nodejs server.js .

USER nextjs
EXPOSE 3000
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]

Docker Compose – Управление на множество контейнери

Docker Compose е инструмент, който ви позволява да дефинирате и стартирате многоконтейнерни Docker приложения. С помощта на YAML файл можете да конфигурирате всички услуги на вашето приложение.

Основна структура на docker-compose.yml

docker-compose.yml – основен пример
version: '3.8'

services:
  # Web приложение
  web:
    build: .
    ports:
      - "3000:3000"
    env_file:
      - .env

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    env_file:
      - .env

Скалиране на услуги

Скалиране на контейнери
# Стартиране на 3 инстанции на web услугата
docker-compose up --scale web=3

# Скалиране на multiple услуги
docker-compose up --scale web=3 --scale worker=2

# Скалиране без пресъздаване на други услуги
docker-compose up --scale web=5 --no-recreate

Практически примери

WordPress с MySQL

Пълна WordPress инсталация с база данни:

docker-compose.yml за WordPress
version: '3.8'

services:
  wordpress:
    image: wordpress:6-apache
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  wordpress_data:
  db_data:

Monitoring Stack (Prometheus + Grafana)

Monitoring с Docker Compose
version: '3.8'

services:
  # Prometheus за събиране на метрики
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
    networks:
      - monitoring

  # Grafana за визуализация
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/dashboards:/etc/grafana/provisioning/dashboards
      - ./grafana/datasources:/etc/grafana/provisioning/datasources
    networks:
      - monitoring

  # Node Exporter за system метрики
  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.rootfs=/rootfs'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)'
    networks:
      - monitoring

  # AlertManager за alerts
  alertmanager:
    image: prom/alertmanager:latest
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
      - alertmanager_data:/alertmanager
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:
  alertmanager_data:

networks:
  monitoring:
    driver: bridge

Full Stack Application

Пълен пример за React + Node.js + PostgreSQL + Redis:

Full stack docker-compose.yml
version: '3.8'

services:
  # React Frontend
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      target: development
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      - REACT_APP_API_URL=http://localhost:5000
      - CHOKIDAR_USEPOLLING=true
    depends_on:
      - backend
    networks:
      - app-network

  # Node.js Backend API
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    ports:
      - "5000:5000"
      - "9229:9229"  # Debug port
    volumes:
      - ./backend:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_NAME=appdb
      - DB_USER=appuser
      - DB_PASSWORD=apppassword
      - REDIS_URL=redis://redis:6379
      - JWT_SECRET=your-secret-key
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - app-network
    command: npm run dev

  # PostgreSQL Database
  postgres:
    image: postgres:15-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: apppassword
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  # Redis Cache
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    networks:
      - app-network

  # Nginx Reverse Proxy
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - frontend
      - backend
    networks:
      - app-network

  # Background Job Worker
  worker:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    volumes:
      - ./backend:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_NAME=appdb
      - DB_USER=appuser
      - DB_PASSWORD=apppassword
      - REDIS_URL=redis://redis:6379
    depends_on:
      - postgres
      - redis
    networks:
      - app-network
    command: npm run worker

volumes:
  postgres_data:
  redis_data:

networks:
  app-network:
    driver: bridge

Най-добри практики

Сигурност

Не-root потребители

Винаги създавайте и използвайте не-root потребител в контейнерите си за по-добра сигурност.

Секретна информация

Никога не поставяйте пароли и API ключове директно в Dockerfile. Използвайте environment variables или Docker secrets.

Редовни актуализации

Актуализирайте базовите образи редовно за да получите последните security patches.

Производителност

Оптимизация на слоевете

Неефективно

# Всяка RUN команда създава нов слой
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y vim
RUN apt-get clean

Ефективно

# Една RUN команда = един слой
RUN apt-get update && \
    apt-get install -y curl vim && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

.dockerignore за по-малки образи

Детайлен .dockerignore
# Dependencies
node_modules
bower_components

# Logs
*.log
logs

# Runtime data
pids
*.pid
*.seed

# Coverage directory used by tools like istanbul
coverage

# Dependency directories
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env.local
.env.development.local
.env.test.local
.env.production.local

# IDE
.vscode
.idea
*.swp
*.swo

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Git
.git
.gitignore

# Docker
Dockerfile*
docker-compose*
.dockerignore

# Documentation
README.md
CHANGELOG.md
LICENSE

# Tests
test
tests
__tests__
*.test.js
*.spec.js

Health Checks

Различни типове health checks
# HTTP health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# TCP health check
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD nc -z localhost 5432 || exit 1

# Custom script health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD ./healthcheck.sh

# Database health check
HEALTHCHECK --interval=30s --timeout=5s --retries=5 \
  CMD pg_isready -U $POSTGRES_USER -d $POSTGRES_DB || exit 1

Управление на версии

Semantic Versioning

Използвайте семантично версиониране за вашите образи: myapp:1.2.3, myapp:1.2, myapp:1, myapp:latest

Пример за версиониране
# Build с множество tags
docker build -t myapp:1.2.3 -t myapp:1.2 -t myapp:1 -t myapp:latest .

# Push на всички версии
docker push myapp:1.2.3
docker push myapp:1.2
docker push myapp:1
docker push myapp:latest

Управление на данни

Named volumes vs Bind mounts
# Named volume (препоръчително за production)
volumes:
  - postgres_data:/var/lib/postgresql/data

# Bind mount (добре за development)
volumes:
  - ./data:/var/lib/postgresql/data

# Tmpfs mount (за временни данни)
tmpfs:
  - /tmp

Мрежи

Custom networks
# Създаване на custom network
docker network create --driver bridge my-network

# Свързване на контейнер към мрежа
docker run --network my-network my-app

# В docker-compose
networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # Не позволява external достъп

Решаване на проблеми

Често срещани проблеми

Недостатъчно дисково пространство

Почистване на Docker ресурси
# Преглед на използваното пространство
docker system df

# Почистване на неизползвани ресурси
docker system prune

# Агресивно почистване (внимавайте!)
docker system prune -a --volumes

# Почистване на конкретен тип ресурси
docker container prune  # Неизползвани контейнери
docker image prune      # Неизползвани образи
docker volume prune     # Неизползвани volumes
docker network prune    # Неизползвани мрежи

Проблеми с портове

Порт вече се използва

Ако получавате грешка "port is already allocated", проверете кой процес използва порта:

Откриване на заети портове
# Linux/Mac
sudo lsof -i :3000
netstat -tulpn | grep :3000

# Windows
netstat -ano | findstr :3000

# Спиране на контейнер, който използва порта
docker ps
docker stop 

Проблеми с памет

Мониторинг на ресурсите
# Преглед на ресурсите на всички контейнери
docker stats

# Преглед на ресурсите на конкретен контейнер
docker stats 

# Ограничаване на паметта
docker run -m 512m my-app

# В docker-compose
services:
  web:
    image: my-app
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

Debugging техники

Влизане в контейнер

Debug команди
# Влизане в работещ контейнер
docker exec -it  /bin/bash

# Ако bash не е наличен (alpine образи)
docker exec -it  /bin/sh

# Стартиране на нов контейнер за debugging
docker run -it --rm  /bin/bash

# Копиране на файлове от/към контейнер
docker cp :/path/to/file ./local/path
docker cp ./local/file :/path/to/destination

Анализ на логове

Работа с логове
# Преглед на логовете
docker logs 

# Следене на логове в реално време
docker logs -f 

# Последните N реда
docker logs --tail 100 

# Логове с timestamps
docker logs -t 

# Логове за определен период
docker logs --since="2023-01-01" --until="2023-01-02" 

# В docker-compose
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=50 db

Инспектиране на контейнери

Детайлна информация
# Пълна информация за контейнер
docker inspect 

# Специфична информация
docker inspect --format='{{.State.Status}}' 
docker inspect --format='{{.NetworkSettings.IPAddress}}' 

# Информация за образ
docker inspect 

# Процеси в контейнер
docker top 

# Файлови промени
docker diff 

Полезни инструменти

Portainer

Web-based UI за управление на Docker контейнери, образи, volumes и мрежи.

docker run -d -p 9000:9000 \
  --name portainer \
  -v /var/run/docker.sock:/var/run/docker.sock \
  portainer/portainer-ce

ctop

Top-like интерфейс за мониторинг на Docker контейнери в реално време.

# Инсталиране
sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 -O /usr/local/bin/ctop
sudo chmod +x /usr/local/bin/ctop

# Стартиране
ctop

dive

Инструмент за анализ и оптимизация на Docker образи – показва слоевете и техния размер.

# Инсталиране
wget https://github.com/wagoodman/dive/releases/download/v0.10.0/dive_0.10.0_linux_amd64.deb
sudo apt install ./dive_0.10.0_linux_amd64.deb

# Анализ на образ
dive my-app:latest

Checklist за production

Production готовност

  • ✅ Използвайте не-root потребители
  • ✅ Имплементирайте health checks
  • ✅ Настройте restart policies
  • ✅ Ограничете ресурсите (CPU, память)
  • ✅ Използвайте secrets за чувствителна информация
  • ✅ Конфигурирайте logging
  • ✅ Настройте мониторинг
  • ✅ Тествайте backup и restore процедури
  • ✅ Документирайте deployment процеса

Федя Серафиев

Федя Серафиев

Федя Серафиев e собственик на уебсайта urocibg.eu. Той намира удовлетворение в това да помага на хората да решават и най-сложните технически проблеми. Сегашната му цел е да пише лесни за следване статии, така че подобни проблеми изобщо да не възникват.

Благодарим ви за прочитането на статията! Ако намерихте информацията за полезна, можете да дарите посредством бутоните по-долу: