← Назад к вопросам

Как создать контейнер самостоятельно?

2.3 Middle🔥 181 комментариев
#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как создать Docker контейнер самостоятельно

Docker контейнер — это легковесный пакет, содержащий приложение, зависимости и окружение. Создание собственного контейнера требует написания Dockerfile и выполнения команд Docker.

1. Что такое Docker контейнер

Docker контейнер — это изолированное окружение, которое:

  • Содержит ваше приложение и все зависимости
  • Гарантирует одинаковую работу на любой машине
  • Быстрее запускается чем виртуальные машины
  • Использует меньше ресурсов
┌─────────────────────────────┐
│     Docker контейнер        │
├─────────────────────────────┤
│  Приложение (Java)          │
│  Зависимости (libraries)    │
│  ОС (Alpine/Ubuntu base)    │
├─────────────────────────────┤
│     Docker Engine (Linux)   │
└─────────────────────────────┘

2. Создание Dockerfile для Java приложения

Dockerfile — это текстовый файл с инструкциями для создания образа (image):

# 1. Базовый образ с Java 17
FROM openjdk:17-jdk-slim

# 2. Установка рабочей директории в контейнере
WORKDIR /app

# 3. Копирование JAR файла из локальной машины
COPY target/myapp-1.0.0.jar app.jar

# 4. Открытие портов
EXPOSE 8080

# 5. Переменные окружения
ENV JAVA_OPTS="-Xmx512m -Xms256m"

# 6. Команда запуска приложения
ENTRYPOINT ["java", "-jar", "app.jar"]

3. Пошаговое создание контейнера

Шаг 1: Создание Dockerfile

# Создаём файл в корне проекта
touch Dockerfile

# Содержимое файла для Spring Boot приложения
cat > Dockerfile << 'EOF'
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/demo-0.0.1-SNAPSHOT.jar demo.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "demo.jar"]
EOF

Шаг 2: Сборка проекта (создание JAR)

# Используем Maven
mvn clean package

# Или Gradle
gradle build

Шаг 3: Создание Docker образа

# Команда: docker build -t название:версия путь-к-dockerfile
docker build -t myapp:1.0.0 .

# Проверка созданного образа
docker images

Шаг 4: Запуск контейнера

# Базовый запуск
docker run -d \
  --name myapp-container \
  -p 8080:8080 \
  myapp:1.0.0

# С логами
docker logs myapp-container

# В интерактивном режиме
docker run -it \
  -p 8080:8080 \
  myapp:1.0.0

4. Продвинутый Dockerfile с multi-stage build

Multi-stage сборка сокращает размер образа:

# Этап 1: Сборка приложения (используется компилятор)
FROM maven:3.8-eclipse-temurin-17 as builder
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests

# Этап 2: Runtime образ (без инструментов сборки)
FROM openjdk:17-jdk-slim
WORKDIR /app

# Копируем только JAR из первого этапа
COPY --from=builder /app/target/*.jar app.jar

EXPOSE 8080
ENV JAVA_OPTS="-Xmx512m -Xms256m"
ENTRYPOINT ["java", "$JAVA_OPTS", "-jar", "app.jar"]

5. Docker Compose для локальной разработки

Когда приложению нужны другие сервисы (БД, Redis):

# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    container_name: my-java-app
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/mydb
      SPRING_DATASOURCE_USERNAME: user
      SPRING_DATASOURCE_PASSWORD: password
    depends_on:
      - postgres
    networks:
      - app-network

  postgres:
    image: postgres:15-alpine
    container_name: my-postgres
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

Запуск всей системы:

docker-compose up -d
docker-compose logs -f
docker-compose down

6. Практический пример: Spring Boot REST API в Docker

// Приложение
@SpringBootApplication
@RestController
@RequestMapping("/api/v1")
public class Application {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/users/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
    
    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User created = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
# Dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app

# Копируем исходный код
COPY . .

# Собираем приложение
RUN apt-get update && apt-get install -y maven && \
    mvn clean package -DskipTests

# Запускаем
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "target/app-0.0.1-SNAPSHOT.jar"]

Команды для создания контейнера:

# 1. Сборка образа
docker build -t userapi:1.0 .

# 2. Запуск контейнера
docker run -d \
  --name userapi \
  -p 8080:8080 \
  -e SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/users \
  userapi:1.0

# 3. Проверка логов
docker logs userapi

# 4. Тестирование API
curl http://localhost:8080/api/v1/users/1

# 5. Остановка контейнера
docker stop userapi

# 6. Удаление контейнера
docker rm userapi

7. Основные Docker команды

# Управление образами
docker build -t имя:версия .     # Создать образ
docker images                     # Список образов
docker rmi имя:версия            # Удалить образ
docker push имя:версия           # Загрузить в репозиторий

# Управление контейнерами
docker run [опции] образ         # Запустить контейнер
docker ps                        # Список запущенных контейнеров
docker ps -a                     # Все контейнеры (с остановленными)
docker logs контейнер            # Логи контейнера
docker exec -it контейнер bash   # Вход в контейнер
docker stop контейнер            # Остановить контейнер
docker rm контейнер              # Удалить контейнер

# Отладка
docker inspect контейнер         # Информация о контейнере
docker stats                     # Использование ресурсов
docker logs -f контейнер         # Текущие логи в реальном времени

8. Best Practices

Используйте slim образы — alpine, slim вместо full ✓ Multi-stage build — сокращает размер до 10 раз ✓ Не запускайте root — создайте непривилегированного пользователя ✓ Используйте .dockerignore — исключите ненужные файлы ✓ Кешируйте слои — копируйте pom.xml раньше исходного кода ✓ Переменные окружения — для конфигурации вместо хардкода ✓ Проверки здоровья — добавьте HEALTHCHECK

# Best practice Dockerfile
FROM openjdk:17-jdk-slim

# Создаём пользователя
RUN useradd -m -s /bin/bash appuser

WORKDIR /app

# Копируем зависимости первыми (для кеширования)
COPY pom.xml .
RUN mvn dependency:go-offline

# Копируем исходный код
COPY src ./src

# Собираем
RUN mvn clean package -DskipTests

# Переключаемся на непривилегированного пользователя
USER appuser

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

ENTRYPOINT ["java", "-jar", "target/app.jar"]

Резюме

Создание Docker контейнера состоит из:

  1. Dockerfile — инструкции для образа
  2. docker build — создание образа из Dockerfile
  3. docker run — запуск контейнера
  4. docker-compose (опционально) — оркестрация нескольких контейнеров

Docker позволяет упаковать Java приложение так, чтобы оно работало идентично везде: на локальной машине, в CI/CD, на production сервере.

Как создать контейнер самостоятельно? | PrepBro