# πŸ’‘ Π›ΡƒΡ‡ΡˆΠΈΠ΅ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ## 1. Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ вСрсиями ### БСмантичСскоС вСрсионированиС ```bash # Основной ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚Π΅Π³ (Π΄Π²ΠΎΠΉΠ½ΠΎΠ΅ Ρ‚Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅) TAG1=latest TAG2=v1.0.0 # Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ: ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ alias + вСрсия TAG1=stable TAG2=v1.1.0 # ΠŸΡ€ΠΈΠΌΠ΅Ρ€ для ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎΠΉ Π²Π΅Ρ‚ΠΊΠΈ TAG1=dev # Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±Π΅Π· Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ‚Π΅Π³Π° # ΠŸΡ€Π΅Π΄Ρ€Π΅Π»ΠΈΠ·Π½Ρ‹Π΅ вСрсии TAG1=rc TAG2=v1.2.0-rc.1 TAG1=beta TAG2=v1.2.0-beta.1 TAG1=alpha TAG2=v1.2.0-alpha.1 # Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ алиасы TAG1=latest TAG1=stable TAG1=dev ``` ### АвтоматичСскоС вСрсионированиС ```bash # ИспользованиС Git commit hash TAG1=$(git rev-parse --short HEAD) # ИспользованиС Π΄Π°Ρ‚Ρ‹ TAG1=$(date +%Y%m%d-%H%M%S) # ИспользованиС Git Ρ‚Π΅Π³ΠΎΠ² TAG1=$(git describe --tags --always) ``` ## 2. Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ### ИспользованиС Π½Π΅ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ```dockerfile # Π’ Dockerfile RUN useradd -ms /bin/bash appuser USER appuser ``` ### Π‘ΠΊΠ°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ```bash # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° уязвимостСй docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy image myapp:latest # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° с Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠΌ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy image --severity HIGH,CRITICAL myapp:latest ``` ## 3. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ сборки ### ΠœΠ½ΠΎΠ³ΠΎΡΡ‚Π°ΠΏΠ½Π°Ρ сборка ```dockerfile # Build stage FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production # Production stage FROM node:18-alpine AS production WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY . . CMD ["npm", "start"] ``` ### ИспользованиС .dockerignore ```dockerfile # .dockerignore node_modules npm-debug.log .git .gitignore README.md .env .nyc_output coverage .nyc_output .coverage ``` ## 4. ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΈ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ### Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π»ΠΎΠ³ΠΈ ```bash # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π»ΠΎΠ³ΠΎΠ² с ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹ΠΌΠΈ make docker build \ IMAGE=myapp \ TAG1=v1.0.0 \ BUILD_ARGS="--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ LOG_DIR=./build-logs ``` ### ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ```bash # ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠ±Ρ€Π°Π·Π° docker images myapp:latest # Π”Π΅Ρ‚Π°Π»ΡŒΠ½Π°Ρ информация docker history myapp:latest # Анализ слоСв docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ wagoodman/dive:latest myapp:latest ``` ## 5. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ### ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слоСв Docker ```bash # Π‘Π±ΠΎΡ€ΠΊΠ° с использованиСм кэша make docker build IMAGE=myapp TAG1=v1.0.0 # Π‘Π±ΠΎΡ€ΠΊΠ° Π±Π΅Π· кэша (для чистых сборок) make docker rebuild IMAGE=myapp TAG1=v1.0.0 # ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΎΠ±Ρ€Π°Π·ΠΎΠ² make docker build IMAGE=myapp TAG1=v1.0.0 PULL=1 ``` ### ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Π°Ρ сборка ```bash # Π‘Π±ΠΎΡ€ΠΊΠ° Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ make docker build IMAGE=frontend TAG1=v1.0.0 & make docker build IMAGE=backend TAG1=v1.0.0 & make docker build IMAGE=worker TAG1=v1.0.0 & wait # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² docker images | grep -E "(frontend|backend|worker)" ``` ### ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ```bash # Π‘Π±ΠΎΡ€ΠΊΠ° с ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ make docker build \ IMAGE=myapp \ TAG1=minimal \ BUILD_ARGS="--build-arg BUILDKIT_INLINE_CACHE=1" # Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠ² make docker save \ SRC_IMAGE=myapp:latest \ COMPRESS=1 ``` ## 6. Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостями ### Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° ```bash # Π‘Π±ΠΎΡ€ΠΊΠ° Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° make docker build \ IMAGE=base-image \ TAG1=ubuntu-22.04 \ DOCKERFILE=Dockerfile.base # ИспользованиС Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° make docker build \ IMAGE=myapp \ TAG1=v1.0.0 \ BUILD_ARGS="--build-arg BASE_IMAGE=base-image:ubuntu-22.04" ``` ### Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостями ```bash # ОбновлСниС Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΎΠ±Ρ€Π°Π·ΠΎΠ² make docker build \ IMAGE=myapp \ TAG1=v1.0.0 \ PULL=1 # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ docker pull ubuntu:22.04 ``` ## 7. ΠžΡ‚Π»Π°Π΄ΠΊΠ° ΠΈ тСстированиС ### ВСстированиС ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ```bash # Запуск тСстов Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ make docker check RUN_CMD="npm test" # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ make docker check RUN_CMD="nginx -t" # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎΡ€Ρ‚ΠΎΠ² make docker check RUN_CMD="netstat -tlnp" ``` ### Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ ΠΎΡ‚Π»Π°Π΄ΠΊΠ° ```bash # Запуск ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° docker run -it --rm myapp:latest /bin/bash # Запуск с ΠΎΡ‚Π»Π°Π΄ΠΊΠΎΠΉ docker run -it --rm \ -p 8080:8080 \ -e DEBUG=1 \ myapp:latest ``` ## 8. ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ### Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ сборки ```bash # ВрСмя сборки time make docker build IMAGE=myapp TAG1=v1.0.0 # Π”Π΅Ρ‚Π°Π»ΡŒΠ½Π°Ρ статистика make docker build IMAGE=myapp TAG1=v1.0.0 2>&1 | tee build.log ``` ### ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ рСсурсов ```bash # ИспользованиС рСсурсов ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² docker stats --no-stream myapp-container # Анализ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠ±Ρ€Π°Π·ΠΎΠ² docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" ``` ## 9. ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ### Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Ρ„Π°ΠΉΠ»ΠΎΠ² ``` project/ β”œβ”€β”€ Dockerfile β”œβ”€β”€ makefile β”œβ”€β”€ .dockerignore β”œβ”€β”€ build.args β”œβ”€β”€ Makefile.local β”œβ”€β”€ docs/ β”‚ β”œβ”€β”€ installation.md β”‚ β”œβ”€β”€ dockerfile.md β”‚ β”œβ”€β”€ makefile.md β”‚ β”œβ”€β”€ examples.md β”‚ └── best-practices.md β”œβ”€β”€ logs/ β”œβ”€β”€ images/ └── .offline/ ``` ### Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ ```bash # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Makefile.local для ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° cat > Makefile.local << EOF REGISTRY=my-registry.com IMAGE=my-project TAG1=dev NO_CACHE=0 QUIET=0 EOF # ИспользованиС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ make docker build # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ настройки ΠΈΠ· Makefile.local ``` ## 10. Π Π΅Π·Π΅Ρ€Π²Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ### РСгулярноС сохранСниС ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ```bash # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ скрипта для Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎΠ³ΠΎ бэкапа cat > backup.sh << 'EOF' #!/bin/bash DATE=$(date +%Y%m%d) make docker save \ SRC_IMAGE=myapp:latest \ IMAGES_DIR=/backup/docker-images \ COMPRESS=1 EOF chmod +x backup.sh # Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² crontab echo "0 2 * * * /path/to/backup.sh" | crontab - ``` ### ВосстановлСниС ΠΈΠ· Π°Ρ€Ρ…ΠΈΠ²Π° ```bash # ВосстановлСниС ΠΎΠ±Ρ€Π°Π·Π° make docker load \ ARCHIVE=/backup/docker-images/myapp_latest.tar.gz \ REGISTRY=my-registry.com \ IMAGE=myapp \ TAG=restored \ LOGIN=1 \ PUSH_OFFLINE=1 ``` ## 11. Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ### Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ README для ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ```bash # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° cat > PROJECT_README.md << 'EOF' # My Project ## Быстрый старт ```bash make docker build IMAGE=myapp TAG=latest make docker push IMAGE=myapp TAG=latest ``` ## ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния - VERSION: ВСрсия прилоТСния - NODE_ENV: ΠžΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ (development/production) EOF ``` ### ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Dockerfile ```dockerfile # Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π· Ubuntu 22.04 ARG BASE_IMAGE=ubuntu:22.04 FROM ${BASE_IMAGE} # ΠœΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π·Π° LABEL maintainer="Sergey Antropov " \ description="Π£Π½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·" \ version="1.0" # Настройки окруТСния для Π½Π΅ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ установки ENV DEBIAN_FRONTEND=noninteractive \ TZ=Etc/UTC \ LANG=C.UTF-8 # Установка Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ RUN apt-get update && \ apt-get install -y \ ca-certificates \ curl \ wget \ bash \ tzdata \ nano \ mc \ tar \ gzip \ unzip \ net-tools \ iputils-ping && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Установка Ρ€Π°Π±ΠΎΡ‡Π΅ΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ WORKDIR /app ```