리눅스 서비스를 위한 Podman Quadlet과 Docker Compose 비교

적절한 컨테이너 워크플로우를 선택하세요.

Page content

Docker Compose와 Podman Quadlet은 겹치는 문제를 해결하지만 서로 다른 설계 관점에서 출발했으며, 이 중 무엇을 선택할지는 애플리케이션 스택으로 사고하는지 아니면 리눅스 서비스로 사고하는지에 따라 달라집니다.

단순한 오후의 실험을 넘어 리눅스 호스트에서 컨테이너를 실행하는 누구나 이 구분이 중요함을 알게 됩니다. Compose는 YAML 파일에서 서비스, 네트워크, 볼륨을 정의하고 docker compose up 명령어로 시작합니다. Quadlet은 systemd 스타일의 유닛 파일로 컨테이너를 정의하며 시스템 서비스 매니저가 라이프사이클을 소유하도록 합니다.

docker compose configuration

두 접근 방식 모두 자체 호스팅 서비스, 내부 도구, 작은 서버에 적합합니다. 올바른 선택은 운영 모델, 팀의 익숙함, 그리고 개발자 친화적인 스택 포맷을 선호하는지 아니면 systemd 네이티브 서비스 모델을 선호하는지에 달려 있습니다. 이 비교는 파일 형식, 라이프사이클 소유권, 루트리스(rootless) 컨테이너, 로깅, 업데이트, 네트워킹, 보안, 마이그레이션 경로와 같은 실용적인 차이점을 다룹니다. 이는 개발자 도구: 현대 개발 워크플로우 완전 가이드의 일부입니다.

빠른 권장 사항

다음과 같은 경우 Docker Compose를 사용하십시오:

  • 가장 빠른 다중 컨테이너 워크플로우가 필요합니다.
  • 이미 Docker Engine을 사용하고 있습니다.
  • 개발자들과 스택을 공유합니다.
  • 로컬 개발에 익숙한 compose.yaml이 필요합니다.
  • 단일 호스트에서 Docker로 작은 서비스를 배포합니다.
  • 프로젝트에서 기존 Compose 예제를 사용합니다.

다음과 같은 경우 Podman Quadlet을 사용하십시오:

  • systemd 네이티브 컨테이너 서비스가 필요합니다.
  • 루트리스(rootless) 컨테이너를 선호합니다.
  • 중앙 Docker 데몬을 원하지 않습니다.
  • 리눅스 호스트에서 장기간 실행되는 서비스를 실행합니다.
  • systemctl, journalctl, 타이머, 종속성, 자동 시작 기능을 원합니다.
  • systemd를 중심으로 자체 호스팅 또는 홈랩 서버를 구축합니다.
  • 컨테이너가 일반적인 리눅스 서비스 모델에 맞게 동작하기를 원합니다.

실용적인 규칙은 다음과 같습니다:

Docker Compose는 애플리케이션 스택에 더 적합합니다.
Podman Quadlet은 리눅스 서비스에 더 적합합니다.

이것은 법칙이 아닙니다. 유용한 기본값일 뿐입니다.

비교 표

영역 Docker Compose Podman Quadlet
주요 모델 다중 컨테이너 애플리케이션 systemd 관리 컨테이너 서비스
파일 형식 YAML systemd 유사 유닛 파일
런타임 Docker Engine Podman
데몬 Docker 데몬 사용 데몬리스 Podman 모델
서비스 매니저 Compose가 스택 라이프사이클 관리 systemd가 라이프사이클 관리
가장 적합한 용도 개발 스택, 앱 번들, 간단한 배포 장기간 실행되는 리눅스 서비스
루트리스 지원 가능하지만 기본 사고방식은 아님 매우 적합
로그 docker compose logs journalctlpodman logs
부팅 시 시작 일반적으로 systemd 래퍼 또는 재시작 정책 사용 네이티브 systemd 유닛
업데이트 docker compose pull && docker compose up -d Podman 자동 업데이트 또는 systemd 워크플로우
이식성 Docker 환경에서 매우 높음 systemd가 있는 Linux에서 가장 좋음
학습 곡선 대부분의 개발자에게 쉬움 systemd 사용자에게 쉬움
생태계 예제 매우 많음 적지만 성장 중

둘 다 Kubernetes는 아닙니다. 대부분의 작은 서비스는 클러스터를 필요로 하지 않습니다. 시작, 중지, 업데이트, 로깅, 복구를 위한 지루하지만 이해하기 쉬운 방식이 필요합니다.

Docker Compose가 뛰어난 점

Docker Compose는 다중 컨테이너 애플리케이션을 정의하고 실행하기 위한 도구입니다. 일반적인 Compose 파일은 서비스, 이미지, 빌드 컨텍스트, 포트, 볼륨, 네트워크, 환경 변수, 헬스 체크, 종속성, 프로필을 설명합니다.

services:
  web:
    image: nginx:stable
    ports:
      - "8080:80"
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro

  redis:
    image: redis:7
    restart: unless-stopped

실행:

docker compose up -d

상태 확인:

docker compose ps

로그 읽기:

docker compose logs -f

정지:

docker compose down

Compose는 직접적이고 생산적입니다. 사고의 단위가 “이 애플리케이션에는 여러 컨테이너가 있다"일 때 특히 뛰어납니다. Compose 명령어와 패턴의 포괄적인 참조는 Docker Compose Cheatsheet을 참조하십시오. Compose를 넘어선 Docker 명령어(이미지, 볼륨, 네트워크, 정리)에 대해서는 Docker Cheatsheet을 참조하십시오.

Podman Quadlet이 뛰어난 점

Podman Quadlet은 systemd 스타일 파일을 사용하여 Podman 컨테이너를 정의하는 방법입니다. 전체 생성된 systemd 서비스를 수동으로 작성하는 대신 선언적 파일을 작성합니다:

[Unit]
Description=Example web container
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/library/nginx:stable
PublishPort=8080:80
Volume=/opt/example/html:/usr/share/nginx/html:ro

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

/etc/containers/systemd/example.container로 저장한 다음 systemd를 다시 로드합니다:

sudo systemctl daemon-reload

시작:

sudo systemctl enable --now example.service

확인:

systemctl status example.service
journalctl -u example.service -f

Quadlet의 핵심 매력: 컨테이너가 일반적인 리눅스 서비스가 됩니다.

철학적 차이

Docker Compose는 스택으로 생각합니다

Compose는 다음과 묻습니다: 이 애플리케이션을 구성하는 서비스는 무엇인가?

Compose 프로젝트는 일반적으로 애플리케이션 코드 근처에 존재합니다:

myapp/
  compose.yaml
  .env
  app/
  db/

단위로 프로젝트를 시작합니다:

docker compose up -d

단위로 프로젝트를 업데이트합니다:

docker compose pull
docker compose up -d

이는 간단하고 가시적이며 이식성이 있습니다.

Podman Quadlet은 서비스로 생각합니다

Quadlet은 다음과 묻습니다: 이 리눅스 호스트가 서비스로 실행해야 하는 컨테이너는 무엇인가?

Quadlet 파일은 systemd 관련 컨테이너 경로에 있습니다:

/etc/containers/systemd/
~/.config/containers/systemd/

systemd로 생성된 서비스를 관리합니다:

systemctl status myapp.service
systemctl restart myapp.service
journalctl -u myapp.service -f

이는 리눅스 서버에서 더 네이티브하게 느껴집니다. 일반적인 systemd 서비스 패턴에 대해서는 리눅스에서 실행 파일을 서비스로 실행하기를 참조하십시오.

중요한 차이: 라이프사이클 소유주는 누구인가?

Docker Compose의 경우 Compose가 애플리케이션 라이프사이클을 소유합니다. Quadlet의 경우 systemd가 서비스 라이프사이클을 소유합니다.

이는 부팅 동작, 종료 동작, 재시작 정책, 종속성 순서, 로그, 헬스 가시성, 사용자 서비스, 업데이트, 타이머 통합, 다른 호스트 서비스와의 통합에 영향을 미칩니다.

호스트의 모든 것을 systemd로 관리하고 있다면 Quadlet이 깔끔하게 맞습니다. 애플리케이션 스택 관점에서 주로 생각한다면 Compose가 일반적으로 더 편안합니다.

systemd 하의 Docker Compose vs Quadlet

Docker Compose를 systemd 서비스로 실행할 수 있습니다. 이는 종종 좋은 패턴입니다. 예시 systemd 유닛:

[Unit]
Description=MyApp Docker Compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecReload=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target

이것은 잘 작동합니다. 하지만 여전히 Compose의 래퍼입니다. systemd가 Compose 명령을 시작하고, Docker와 Compose가 그 뒤에 컨테이너를 처리합니다.

Quadlet의 경우 유닛 생성은 Podman과 systemd를 위해 직접 설계되었습니다. 컨테이너 지향적 유닛 파일을 작성하면 systemd가 생성된 서비스를 관리합니다.

이 구별은 미묘하지만 중요합니다:

systemd 하의 Docker Compose:
  systemd는 Compose 명령을 관리합니다.

Podman Quadlet:
  systemd는 생성된 컨테이너 서비스를 관리합니다.

이 패턴에 대한 자세한 안내는 systemd를 사용하여 리눅스 서비스로 Docker Compose 실행하기를 참조하십시오.

파일 형식 비교

Docker Compose YAML

Compose는 YAML을 사용합니다. 컴팩트하고 인기가 많으며 공유하기 쉽습니다. 또한 들여쓰기에 민감하며 스택이 커지면 지저분해질 수 있습니다.

services:
  app:
    image: ghcr.io/example/app:1.0.0
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      APP_ENV: production
    volumes:
      - app-data:/data

volumes:
  app-data:

Quadlet 유닛 파일

Quadlet은 systemd 유사 파일을 사용합니다. 서비스가 많으면 더 장황하지만 systemd를 이미 이해한다면 가독성이 좋습니다.

[Unit]
Description=Example app container
After=network-online.target
Wants=network-online.target

[Container]
Image=ghcr.io/example/app:1.0.0
PublishPort=8080:8080
Environment=APP_ENV=production
Volume=app-data.volume:/data

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

그리고 볼륨 파일:

[Volume]
VolumeName=app-data

적절한 systemd 컨테이너 디렉토리에 app.containerapp-data.volume로 저장합니다.

Docker Compose 개념을 Quadlet으로 매핑

Compose 개념 Quadlet 동등물
services .container 파일 또는 .pod.container
volumes .volume 파일 또는 바인드 마운트
networks .network 파일
ports PublishPort=
environment Environment= 또는 EnvironmentFile=
restart [Service] Restart=
depends_on systemd After=, Wants=, Requires=
healthcheck Podman 헬스 체크 옵션
profiles systemd 활성화 및 별도 유닛
docker compose logs journalctl -u servicepodman logs
docker compose up -d systemctl start service
docker compose down systemctl stop service
프로젝트 디렉토리 systemd 컨테이너 유닛 디렉토리

마이그레이션은 개념적으로는 간단하지만 기계적이지는 않습니다. Compose는 스택을 설명합니다. Quadlet은 서비스를 설명합니다.

루트리스(Rootless) 컨테이너

루트리스 컨테이너는 Podman과 Quadlet을 살펴봐야 할 가장 강력한 이유 중 하나입니다.

Docker의 경우 많은 사용자가 자신을 docker 그룹에 추가합니다. 이는 편리하지만 Docker 데몬에 대한 액세스는 효과적으로 강력한 호스트 액세스 권한입니다. 개인 워크스테이션에서는 이것이 허용될 수 있습니다. 공유 서버에서는 더 많은 주의가 필요합니다.

Podman은 루트리스 사용을 일류 워크플로우로 설계되었습니다. 루트리스 Quadlet은 사용자의 구성 디렉토리 아래에 존재합니다:

~/.config/containers/systemd/whoami.container

그 다음 사용자 systemd로 관리합니다:

systemctl --user daemon-reload
systemctl --user enable --now whoami.service
systemctl --user status whoami.service
journalctl --user -u whoami.service -f

로그아웃 후에도 사용자 서비스를 계속 실행하려면:

sudo loginctl enable-linger "$USER"

이는 사용자 소유 서비스에 대한 깔끔한 모델입니다.

루트리스 비교

영역 Docker Compose Podman Quadlet
기본 일반 설정 루트풀(rootful) Docker 데몬 루트리스 친화적 Podman
사용자 서비스 모델 가능하지만 덜 네이티브 systemctl --user로 네이티브
데몬 액세스 위험 Docker 소켓이 강력함 기본적으로 중앙 루트 데몬 없음
낮은 포트 바인딩 루트풀 Docker로 간단 루트리스일 때 추가 설정 필요
호스트 통합 매우 일반적 더 리눅스 네이티브
공유 서버 적합성 주의 필요 매우 적합

루트리스는 마법이 아닙니다. 네트워킹, 권한 상승 동작, 낮은 포트周围的人 tradeoffs가 있습니다. 그러나 장기간 실행되는 사용자 소유 서비스에 대해 Quadlet은 매우 우아한 모델입니다.

시작 및 부팅 동작

Docker Compose

Compose 자체는 부팅 서비스를 생성하지 않습니다. 일반적으로 Docker 재시작 정책, docker compose up -d 주변의 systemd 래퍼, 배포 스크립트 또는 더 높은 수준의 도구에 의존합니다.

예시 Compose 재시작 정책:

services:
  app:
    image: example/app:stable
    restart: unless-stopped

systemd 래퍼는 호스트 수준 서비스를 제공합니다. 이는 좋지만 여전히 추가 래퍼입니다. 전체 패턴은 systemd를 사용하여 리눅스 서비스로 Docker Compose 실행하기를 참조하십시오.

Podman Quadlet

Quadlet은 이미 systemd 지향적입니다. 부팅 시 활성화:

sudo systemctl enable myapp.service

루트리스의 경우:

systemctl --user enable myapp.service
sudo loginctl enable-linger "$USER"

부팅 동작은 추가 기능이 아닙니다. 이는 모델 자체입니다.

재시작 동작

Compose는 일반적으로 YAML에서 restart: unless-stopped를 사용합니다. Quadlet은 일반적으로 systemd 재시작 동작을 사용합니다:

[Service]
Restart=always

또는:

[Service]
Restart=on-failure

이는 재시작 로직을 서비스 매니저로 이동시킵니다. 선호도: Compose 스택에는 Compose/Docker 재시작 정책을 사용하고, Quadlet에는 systemd 재시작 정책을 사용하며, 너무 많은 슈퍼바이저를 쌓지 마십시오. 재시작 동작의 하나의 명확한 소유주를 유지하십시오.

로깅 비교

Docker Compose 로그

docker compose logs -f
docker compose logs -f app

이는 개발자에게 훌륭합니다.

Quadlet 로그

Quadlet 서비스는 systemd 로그를 사용합니다:

journalctl -u app.service -f

루트리스 유닛의 경우:

journalctl --user -u app.service -f

여전히 Podman 로그를 사용할 수 있습니다:

podman logs -f container-name

서버 운영의 경우 journalctl 통합은 주요 장점입니다. 컨테이너가 다른 리눅스 서비스와 동일한 로그 워크플로우에 맞습니다.

업데이트

Docker Compose 업데이트

공통 업데이트 흐름:

cd /opt/myapp
docker compose pull
docker compose up -d --remove-orphans
docker image prune -f

스크립트 안에 쉽게 감쌀 수 있습니다:

#!/usr/bin/env bash
set -euo pipefail

cd /opt/myapp

docker compose config --quiet
docker compose pull
docker compose up -d --remove-orphans
docker image prune -f
docker compose ps

Podman Quadlet 업데이트

간단화된 수동 흐름:

sudo podman pull ghcr.io/example/app:1.0.1
sudo systemctl restart app.service

또는 루트리스의 경우:

podman pull ghcr.io/example/app:1.0.1
systemctl --user restart app.service

Podman은 컨테이너가 올바른 레이블과 이미지 정책으로 구성되어 있을 때 자동 업데이트 워크플로우를 지원할 수 있습니다. Quadlet의 장점은 업데이트가 항상 더 간단하다는 것이 아닙니다. 장점은 업데이트가 서비스 매니저 네이티브라는 것입니다.

자동 업데이트 철학

자동 업데이트는 편리합니다. 또한 위험이기도 합니다. 리스크가 낮은 홈랩 서비스의 경우 자동 컨테이너 업데이트가 괜찮을 수 있습니다. 데이터베이스, 상태ful 앱 또는 비즈니스 서비스의 경우 선호되는 흐름은 다음과 같습니다:

  1. 백업.
  2. 풀(Pull).
  3. 재생성 또는 재시작.
  4. 헬스 확인.
  5. 나중에 정리.

Compose는 이를 명시적으로 만듭니다. Quadlet과 Podman은 이를 systemd 네이티브로 만들 수 있습니다. 어떤 도구도 롤백 계획의 필요성을 제거하지 않습니다.

볼륨 및 영구 데이터

Compose 볼륨

Compose는 이름 붙여진 볼륨을 지원합니다:

services:
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

그리고 바인드 마운트:

services:
  app:
    image: example/app
    volumes:
      - ./config:/config:ro
      - ./data:/data

Quadlet 볼륨

Quadlet은 바인드 마운트를 사용할 수 있습니다:

[Container]
Volume=/opt/app/config:/config:ro
Volume=/opt/app/data:/data

또는 .volume 파일:

[Volume]
VolumeName=app-data

그런 다음 참조:

[Container]
Volume=app-data.volume:/data

Compose는 스택 수준 스토리지에 더 컴팩트합니다. Quadlet은 독립적으로 관리되는 서비스 유닛과 더 일치합니다.

시크릿 및 환경 파일

Compose

Compose는 일반적으로 YAML에서 env_file 또는 environment를 사용합니다. 작은 사설 서비스의 경우 .env가 일반적입니다. 심각한 시스템의 경우 .env를 민감하게 취급하고 Git에서 유지하십시오.

Quadlet

Quadlet은 다음을 사용할 수 있습니다:

[Container]
Environment=APP_ENV=production
EnvironmentFile=/opt/app/app.env

권한 제한:

chmod 600 /opt/app/app.env

Compose도 Quadlet도 자체적으로 완전한 시크릿 관리 시스템이 아닙니다. “명령줄에 없음"을 “보안"과 혼동하지 마십시오.

네트워킹

Compose 네트워킹

Compose는 기본 프로젝트 네트워크를 생성하고 서비스 이름 기반 DNS 이름을 서비스에 제공합니다:

services:
  app:
    image: example/app
    depends_on:
      - db

  db:
    image: postgres:16

앱은 일반적으로 db에서 데이터베이스에 도달할 수 있습니다. 다중 컨테이너 앱 네트워킹은 자연스럽습니다. 이는 Compose의 가장 강력한 기능 중 하나입니다.

Quadlet 네트워킹

Quadlet은 .network 파일로 네트워크를 별도로 정의하거나 Podman 네트워크 옵션을 사용할 수 있습니다:

[Network]
NetworkName=appnet

컨테이너 파일:

[Container]
Image=example/app:stable
Network=appnet.network

이는 더 명시적이고 systemd 유사합니다. 하나 또는 두 개의 컨테이너에 대해서는 괜찮습니다. 큰 앱 스택의 경우 Compose가 읽기 더 쉬울 수 있습니다.

포드(Pods)

Podman에는 네이티브 포드 개념이 있습니다. 여러 컨테이너가 네트워크 네임스페이스와 라이프사이클 경계를 공유하는 Kubernetes 사고 모델이 нравится다면 중요합니다. Quadlet은 .pod 파일을 지원합니다:

[Pod]
PodName=myapp
PublishPort=8080:8080

컨테이너는 해당 포드에 참여할 수 있습니다:

[Container]
Image=ghcr.io/example/app:stable
Pod=myapp.pod

Compose에는 동일한 포드 모델이 없습니다. 네트워크상의 서비스를 가지고 있습니다. 대부분의 간단한 웹 앱에 대해 Compose 네트워크는 충분합니다. 포드 스타일 그룹화를 좋아하는 Podman 사용자의 경우 Quadlet이 더 잘 맞습니다.

빌드 워크플로우

Compose는 로컬 애플리케이션 워크플로우의 일부로 이미지를 빌드할 때 일반적으로 더 좋습니다:

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"

그런 다음:

docker compose up --build

이는 개발에 매우 편리합니다. Quadlet은 이미 빌드된 이미지를 서비스로 실행할 때 일반적으로 더 좋습니다. Podman으로 별도로 이미지를 빌드합니다:

podman build -t localhost/myapp:latest .

그런 다음 이미지를 참조하십시오:

[Container]
Image=localhost/myapp:latest

워크플로우가 “코드 수정, 다시 빌드, 스택 재시작"이라면 Compose가 승리합니다. 워크플로우가 “리눅스 서비스로 알려진 이미지 배포"라면 Quadlet이 승리합니다.

이식성

Compose 파일은 널리 공유됩니다. 많은 오픈소스 프로젝트가 compose.yaml 또는 docker-compose.yml을 제공합니다. 프로젝트가 “Docker Compose로 이 실행"이라고 하면 일반적으로 docker compose up -d로 빠르게 시작할 수 있습니다. 이는 주요 실용적 장점입니다.

Quadlet은 Podman, systemd 및 호환 Quadlet 지원을 갖춘 시스템 사이에서 이식 가능합니다. 이는 더 좁은 타겟이지만 현대 리눅스 서버에게 매우 좋습니다. Quadlet은 모든 가능한 개발자와 애플리케이션을 공유하기 위한 최상의 형식은 아닙니다. 특정 리눅스 호스트가 컨테이너화된 서비스를 어떻게 실행해야 하는지 설명하는 좋은 형식입니다.

개발자 경험

Docker Compose는 일반적으로 개발자 경험에서 승리합니다. 더 많은 예제, 더 많은 튜토리얼, 더 많은 프로젝트 템플릿, 더 쉬운 로컬 빌드, 쉬운 단일 파일 스택, 익숙한 docker compose up, 그리고 개발 종속성에 대한 강력한 적합성. 개발자는 이를 빠르게 읽을 수 있습니다:

services:
  db:
    image: postgres:16
  redis:
    image: redis:7
  app:
    build: .

Quadlet도 비슷한 일을 할 수 있지만 더 운영 중심적입니다. 로컬 개발의 경우 애플리케이션 자체가 Podman 또는 systemd에 관한 것이 아니면 Quadlet으로 시작하는 경우는 드뭅니다.

운영 경험

Quadlet은 리눅스 호스트에서 종종 운영 경험을 승리합니다. 이유:

  • 네이티브 systemctl
  • 네이티브 journalctl
  • 루트리스 사용자 서비스
  • systemd 종속성
  • systemd 타이머
  • systemd 재시작 동작
  • 중앙 Docker 데몬 없음
  • 호스트 서비스 관리와 더 나은 적합성

서버 관리자는 다음과 추론할 수 있습니다:

systemctl status app.service
journalctl -u app.service -f
systemctl restart app.service

이는 일반적인 리눅스 서비스 워크플로우입니다.

보안 모델

Docker Compose 보안 참고 사항

Docker Compose는 일반적으로 Docker 데몬과 통신합니다. 일반적인 리눅스 Docker 설치에서 Docker 소켓에 대한 액세스는 강력합니다. Docker를 제어할 수 있는 사용자는 종종 호스트 경로를 마운트하거나 권한 상승 컨테이너를 실행하거나 기타 방법으로 광범위한 호스트 제어를 얻을 수 있습니다. 루트리스 Docker를 포함한 설치 옵션에 대해서는 Ubuntu에 Docker 설치하기를 참조하십시오.

실용적인 조언:

  • /var/run/docker.sock을 함부로 노출하지 마십시오.
  • docker 그룹을 권한 상승으로 취급하십시오.
  • 권한 상승 컨테이너를 피하십시오.
  • 필요하지 않으면 호스트 마운트를 피하십시오.
  • 시크릿을 Git에서 유지하십시오.
  • 중요한 서비스에 명시적인 이미지 태그를 사용하십시오.
  • 게시된 포트를 검토하십시오.

Quadlet 보안 참고 사항

Podman Quadlet은 루트리스 컨테이너 및 사용자 systemd 서비스와 잘 어울립니다. 이는 특히 루트 데몬이 필요하지 않은 서비스를 가진 공유 호스트 또는 개인 서버에서 위험을 줄일 수 있습니다.

실용적인 조언:

  • 적합할 때 루트리스 서비스를 선호하십시오.
  • 사용자 소유 서비스에 사용자 유닛을 사용하십시오.
  • 호스트 수준 권한이 필요할 때만 시스템 유닛을 사용하십시오.
  • 불필요한 권한 상승 컨테이너를 피하십시오.
  • 환경 파일을 잠급니다.
  • 바인드 마운트에 대해 신중하게 생각하십시오.

루트리스는 위험이 없음을 의미하지 않습니다. 이는 기본 폭발 반경이 더 작을 수 있음을 의미합니다.

성능

대부분의 웹 서비스, 내부 도구, 자체 호스팅 앱의 경우 성능은 결정 요인이 아닙니다. 주요 차이는 운영적이지 않고 원시 속도가 아닙니다. 라이프사이클 모델, 보안 모델, 호스트 통합, 팀 익숙함, 업데이트 프로세스, 네트워킹 요구 사항, 디버깅 워크플로우를 기반으로 선택하십시오.

성능만 때문에 Compose와 Quadlet 사이에서 선택하고 있다면 아마도 잘못된 레이어를 최적화하고 있습니다.

실패 모드

Docker Compose 실패 모드

공통 문제:

  • Docker 데몬 실행 안됨
  • Compose 플러그인 누락
  • 잘못된 프로젝트 디렉토리
  • .env가 예상대로 로드되지 않음
  • 오래된 docker-compose 바이너리가 실수로 사용됨
  • 구성 변경 후 컨테이너 재생성 안됨
  • 서비스 이름 변경 후 고아 컨테이너 남음
  • down -v로 볼륨 삭제
  • Docker 로그가 디스크를 가득 채움
  • Docker 소켓 권한 오류

최상의 수정:

docker compose config
docker compose ps
docker compose logs -f
docker compose up -d --remove-orphans

Podman Quadlet 실패 모드

공통 문제:

  • 유닛 파일이 잘못된 디렉토리에 있음
  • systemctl daemon-reload 잊음
  • 사용자 유닛이 의도되었을 때 시스템 유닛 사용
  • 루트리스 서비스에 loginctl enable-linger 잊음
  • 이미지 풀이 systemd 시작 시간 초과보다 오래 걸림
  • cgroup v2 사용 불가
  • SELinux 레이블 또는 볼륨 권한
  • 서비스 이름이 파일 기대와 다름
  • 네트워크 또는 볼륨 유닛이 올바르게 활성화되거나 참조되지 않음

최상의 수정:

systemctl status app.service
journalctl -u app.service -f
systemctl daemon-reload
podman ps -a
podman logs container-name

루트리스의 경우:

systemctl --user status app.service
journalctl --user -u app.service -f

마이그레이션 예제: Compose에서 Quadlet으로

이 Compose 서비스로 시작:

services:
  whoami:
    image: traefik/whoami:v1.10
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      WHOAMI_NAME: compose-demo

Compose로 실행:

docker compose up -d

대략적인 Quadlet 동등물:

[Unit]
Description=Whoami demo container
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/traefik/whoami:v1.10
PublishPort=8080:80
Environment=WHOAMI_NAME=quadlet-demo

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

/etc/containers/systemd/whoami.container로 저장한 다음:

sudo systemctl daemon-reload
sudo systemctl enable --now whoami.service
sudo systemctl status whoami.service

예제는 컨테이너가 하나이므로 쉽습니다. 데이터베이스, 네트워크, 볼륨, 빌드 단계를 가진 더 큰 Compose 스택은 더 신중한 번역이 필요합니다.

마이그레이션 체크리스트

Compose에서 Quadlet으로 이동하기 전에 질문:

[ ] 이 스택이 실제로 장기간 실행되는 호스트 서비스의 집합인가?
[ ] 이미지가 이미 빌드되고 게시되었는가?
[ ] 루트리스 서비스가 필요한가?
[ ] systemd 종속성과 타이머가 필요한가?
[ ] 볼륨과 바인드 마운트가 명확하게 이해되었는가?
[ ] 포트가 문서화되었는가?
[ ] 시크릿이 Git 외부에서 처리되었는가?
[ ] 백업 및 복원 프로세스가 있는가?
[ ] journalctl을 통해 로그를 모니터링할 수 있는가?
[ ] 롤백 경로가 있는가?

대부분의 답변이 예라면 Quadlet이 좋은 적합성일 수 있습니다. 스택이 주로 로컬 개발을 위한 것이라면 Compose가 아마도 여전히 더 낫습니다.

Docker Compose를 유지할 때

다음과 같은 경우 Compose를 유지하십시오:

  • 프로젝트가 이미 좋은 Compose 파일을 제공합니다.
  • 가장 쉬운 온보딩 경로가 필요합니다.
  • 개발자가 로컬에서 동일한 스택을 실행합니다.
  • 개발 중에 이미지를 빌드합니다.
  • 서비스, 볼륨, 네트워크에 대해 하나의 YAML 파일을 원합니다.
  • 최대 튜토리얼 및 커뮤니티 호환성을 원합니다.
  • 현재 systemd 래퍼가 잘 작동합니다.

Quadlet이 이론적으로 더 깔끔하기 때문에 작동하는 Compose 스택을 마이그레이션한다고 해서 상이 주어지지 않습니다. Compose가 사용 사례에 대해 지루하고 신뢰할 수 있다면 그대로 유지하십시오.

Podman Quadlet으로 이동할 때

다음과 같은 경우 Quadlet으로 이동하십시오:

  • 스택이 실제로 호스트 서비스입니다.
  • 루트리스 서비스 관리를 원합니다.
  • Docker보다 Podman을 선호합니다.
  • systemd가 라이프사이클을 소유하기를 원합니다.
  • journalctl 로그를 원합니다.
  • 서비스 종속성을 원합니다.
  • 로그아웃 후에도 생존하는 사용자 서비스를 원합니다.
  • Docker 데몬 노출을 줄이고 싶습니다.
  • systemd를 중심으로 자체 호스팅 호스트를 구축하고 있습니다.

Quadlet은 “Compose보다 더 나은” 것이 아닙니다. 다른 설계 중심입니다.

권장 패턴

패턴 1: 로컬 개발

Docker Compose 사용. 빠르고, 익숙하며, 이식성이 좋고, 재빌드가 쉬우며, 팀에게 쉽습니다.

패턴 2: 단일 호스트 자체 호스팅

둘 중 하나 사용. 프로젝트가 이미 Compose 파일을 제공하면 Compose를 선택하십시오. systemd 네이티브 서비스 관리를 원하면 Quadlet을 선택하십시오. Compose는 더 나은 앱 번들을 제공하고, Quadlet은 더 나은 리눅스 서비스를 제공합니다.

패턴 3: 사용자 소유 루트리스 서비스

Podman Quadlet 사용. 루트리스 워크플로우, 사용자 수준 서비스 관리, 중앙 Docker 데몬 없음.

~/.config/containers/systemd/app.container
systemctl --user enable --now app.service
loginctl enable-linger

패턴 4: 프로덕션 유사 단일 서버

규율 있는 systemd 래퍼와 함께 Docker Compose 사용, 또는 팀이 Podman에 익숙하다면 Quadlet 사용. 유행을 기반으로 선택하지 마십시오.凌晨 2시에 누가 운영할 것인가를 기반으로 선택하십시오.

패턴 5: 다중 노드 플랫폼

최종 오케스트레이션 레이어로 둘 다 사용하지 마십시오. Kubernetes, Nomad, Swarm 또는 관리 플랫폼을 고려하십시오. Compose와 Quadlet은 훌륭한 단일 호스트 도구입니다. 클러스터 스케줄러는 아닙니다.

실용적인 결정 트리

이것이 주로 로컬 개발을 위한가?
  예:
    Docker Compose 사용
  아니오:
    계속

프로젝트가 이미 유지 관리되는 compose.yaml을 제공하는가?
  예:
    마이그레이션할 강력한 이유가 없으면 Docker Compose 사용
  아니오:
    계속

systemd가 관리하는 루트리스 장기간 실행 서비스를 원하는가?
  예:
    Podman Quadlet 사용
  아니오:
    계속

가장 쉬운 다중 컨테이너 앱 정의를 원하는가?
  예:
    Docker Compose 사용
  아니오:
    계속

컨테이너가 일반적인 리눅스 서비스처럼 동작하기를 원하는가?
  예:
    Podman Quadlet 사용
  아니오:
    Docker Compose 사용

나란히 명령어

작업 Docker Compose Podman Quadlet
시작 docker compose up -d systemctl start app.service
중지 docker compose down systemctl stop app.service
재시작 docker compose restart systemctl restart app.service
변경 적용 docker compose up -d systemctl daemon-reload && systemctl restart app.service
로그 docker compose logs -f journalctl -u app.service -f
상태 docker compose ps systemctl status app.service
부팅 시 활성화 systemd 래퍼 또는 재시작 정책 systemctl enable app.service
업데이트 풀 docker compose pull podman pull image
루트리스 서비스 가능 systemctl --user로 자연적

일반적인 오해

“Quadlet이 Docker Compose를 대체합니다”

정확하지 않습니다. Quadlet은 특히 장기간 실행되는 리눅스 서비스와 같은 일부 Compose 사용 사례를 대체합니다. 개발자를 위한 가장 쉬운 애플리케이션 스택 형식으로서의 Compose를 대체하지는 않습니다.

“Docker Compose는 프로덕션 준비가 되지 않았습니다”

너무 광범위합니다. 백업, 업데이트, 로깅, 재시작 동작, 호스트 보안을 이해한다면 Compose는 작은 프로덕션 시스템에 완벽하게 합리적일 수 있습니다. 문제는 Compose가 아닙니다. 문제는 단일 호스트 Compose 배포가 클러스터 오케스트레이터와 동일한 특성을 가지고 있다고 속이는 것입니다.

“Podman은 데몬 없는 Docker일 뿐입니다”

너무 단순합니다. Podman에는 Docker 호환 명령어가 있지만 설계 중심은 다릅니다: 데몬리스 운영, 루트리스 워크플로우, 포드, 리눅스 통합.

“루트리스는 안전함을 의미합니다”

아니요. 루트리스는 일부 위험을 줄입니다. 나쁜 이미지, 노출된 시크릿, 안전한 바인드 마운트, 취약한 앱을 안전하게 만들지는 않습니다.

“systemd는 컨테이너에 너무 무겁습니다”

systemd는 이미 대부분의 주류 리눅스 서버에서 서비스 매니저입니다. 이를 사용하여 장기간 실행되는 컨테이너를 관리하는 것은 이상하지 않습니다. 종종 지루하고 올바른 일을 하는 것입니다.

최종 권장 사항

애플리케이션 스택이 주요 것일 때 Docker Compose를 사용하십시오. 리눅스 서비스가 주요 것일 때 Podman Quadlet을 사용하십시오.

어느 도구가 더 나은지 논쟁하는 것보다 이 구별이 더 유용합니다. 개발자 워크플로우에 대해 Compose는 넘기기가 어렵습니다. 인기 있고, 가독성이 좋으며, 이식성이 좋고, 수많은 프로젝트에서 지원됩니다. 장기간 실행되는 리눅스 서비스에 대해 Quadlet은 조용히 훌륭합니다. 컨테이너가 네이티브 systemd 서비스처럼 느끼게 하고, 루트리스 Podman과 자연스럽게 작동하며, 심각한 리눅스 호스트의 운영 모델과 맞습니다.

선호되는 분할:

로컬 개발: Docker Compose
이식성 있는 앱 예제: Docker Compose
작은 자체 호스팅 스택: Docker Compose 또는 Quadlet
루트리스 사용자 서비스: Podman Quadlet
장기간 실행되는 호스트 서비스: Podman Quadlet
다중 노드 오케스트레이션: 둘 다 아님; 실제 오케스트레이터 사용

현대적이기 위해 마이그레이션하지 마십시오. 라이프사이클 모델이 더 좋을 때 마이그레이션하십시오. Compose는 훌륭한 스택 도구입니다. Quadlet은 훌륭한 서비스 도구입니다. 스마트한 선택은 각각의 사고 모델이 작업과 일치하는 곳에서 사용하는 것입니다.

참조

구독하기

시스템, 인프라, AI 엔지니어링에 관한 새 글을 받아보세요.