Using docker-compose with Podman rootless
rootless Podman에서 docker-compose 사용하기
Podman의 Docker API 호환 소켓을 열고 `DOCKER_HOST`를 지정하면 root 권한 없이 기존 `docker-compose` 명령을 사용할 수 있습니다. 글은 설정 절차와 컨테이너 파일 접근, 로그아웃 뒤에도 컨테이너를 유지하는 방법을 설명하고, 네트워크 동작 등 Docker와 다른 점도 짚습니다.
- 주제
AI 요약
Podman은 Linux에서 Docker 데몬 없이 컨테이너를 실행하는 도구입니다. Docker API와 호환되는 UNIX 도메인 소켓도 제공하므로, 이 소켓을 가리키면 docker-compose 같은 Docker 생태계 도구를 rootless 방식으로 쓸 수 있습니다. rootless Podman은 user namespace를 이용해 컨테이너 안의 root를 호스트 사용자에 대응시키고, 다른 UID와 GID는 /etc/subuid, /etc/subgid에 지정한 범위에 매핑합니다.
Podman 소켓 설정
root가 아닌 사용자로 다음 명령을 실행합니다.
systemctl --user enable --now podman.socket
소켓은 ${XDG_RUNTIME_DIR}/podman/podman.sock에 생성됩니다. ${XDG_RUNTIME_DIR}은 사용자별로 마운트되는 비공개 tmpfs 경로입니다. 이 명령은 systemd 세션이 필요합니다. sudo는 systemd 세션을 만들지 않으므로 다른 사용자 계정에서 그대로 실행할 수 없습니다. 글은 machinectl shell --uid=사용자명을 쓰거나 해당 사용자로 TTY 또는 SSH에 로그인하는 방법을 안내합니다.
Docker 도구가 Podman에 연결되도록 설정
docker-compose는 DOCKER_HOST 환경 변수에서 Docker API 주소를 읽습니다. 다음 값을 설정하면 앞서 만든 Podman 소켓에 연결합니다.
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/podman/podman.sock"
계속 적용하려면 셸 설정 파일에 추가합니다. 설정 뒤에는 docker-compose config, docker-compose up -d, docker-compose ps, docker-compose down --volumes를 평소처럼 실행하면 됩니다. 배포판에 따라 명령이 docker-compose가 아니라 docker compose로 제공될 수 있으며, 둘 다 사용할 수 있습니다. 필요하면 셸 별칭으로 명령 이름을 맞춥니다.
Docker가 설치돼 있어도 서비스를 중지하고 비활성화하면 rootful Docker와 소켓이 함께 실행되는 상황을 피할 수 있습니다. 글은 root 권한으로 systemctl disable --now docker.service docker.socket과 rm -f /var/run/docker.sock을 실행하는 방법을 제시합니다. 이 명령은 Docker 데이터를 지우지 않습니다. 다시 사용하려면 systemctl enable --now docker.service로 서비스를 켭니다. docker 명령도 DOCKER_HOST를 읽으므로 Podman 소켓에 연결해 계속 쓸 수 있습니다.
컨테이너 파일과 사용자 세션
podman unshare는 실제 호스트 root 권한을 얻는 대신 user namespace 안에서 root로 동작하는 셸을 엽니다. 컨테이너 사용자 소유 파일의 권한을 조정할 때 쓸 수 있습니다. 실행 중인 컨테이너의 파일을 편집하려면 먼저 podman unshare를 실행하고, podman mount 컨테이너명 또는 ID가 반환하는 경로로 이동합니다. 글은 해당 경로에서 TUI 편집기를 실행하는 예를 듭니다.
사용자의 마지막 systemd 세션이 끝나면 Podman 컨테이너는 기본 설정상 중지됩니다. 로그아웃 뒤에도 계속 실행하려면 root 권한으로 loginctl enable-linger 사용자명을 실행합니다. Docker를 rootless로 설치하는 방법도 있지만, 글에 따르면 podman unshare와 podman mount에 해당하는 기능은 없으며 unshare, nsenter로 비슷한 작업을 해야 합니다.
Lobsters 반응
- @refi64 — 첫 단계는 몇 가지 간소화할 수 있습니다. 보통 Podman에는 systemd 소켓 정의도 들어 있으므로, 소켓을 직접 활성화하거나 시작하지 않아도 됩니다. 소켓에 접근하면 systemd가 서비스를 자동으로 시작합니다. 다른 사용자의 rootless Podman 세션을 활성화하려면
systemctl --user [email protected] [...]를 쓸 수도 있습니다.machinectl과 같은 내부 메커니즘으로 해당 사용자의 systemd 세션을 대상으로 합니다.- @Exagone313 — 제 시스템인 Arch Linux에서는 Podman 소켓, 즉 systemd의 소켓 활성화가 기본으로 시작되지 않습니다. 다른 사용자 관련 제안은 좋네요. 덧붙이면 wheel 그룹에 속해 있을 때는 작동하지 않는 것 같습니다. root 권한이 필요한 듯합니다.
- @refi64 — 제 시스템인 Arch Linux에서는 Podman 소켓이 기본으로 시작되지 않는군요. 제가 어느 시점에 켜 둔 모양입니다. 서비스를 켜는 대신 소켓을 활성화하면 필요할 때까지 Podman이 시작되지 않으니 더 나을 수는 있습니다. 다만 실행 중인 컨테이너가 없을 때 Podman이 자원을 많이 쓰지는 않을 것 같습니다. wheel 그룹에 속해 있을 때 작동하지 않는다는 점은 의외네요. polkit을 거치지 않거나 다른 경로를 따르는 건가요? 최근에 올라온 관련 이슈도 있습니다.
- @landon — sudo 그룹을 써 보거나 wheel 그룹에 sudo 권한을 명시적으로 설정해 보세요. systemd에는 sudo 통합 기능이 있습니다. 예전과 달리 wheel 그룹 자체에 특별한 의미가 있다고 보기는 어려울 것 같습니다. 참고로 저는 Docker 소켓을 써 본 적은 없지만 rootless Podman을 주로 씁니다.
- @jbe_ — 흥미롭네요. 저는 지금까지 compose 작업에 podman-compose만 썼습니다.
- @bityard — 안내 감사합니다. 개인 서비스에 docker-compose를 많이 씁니다. Docker 대신 Podman을 쓰면 docker-compose의 어떤 기능을 포기하거나 어떤 차이를 겪나요? 모든 동작이 똑같나요? 많은 사람이 Podman에서 여러 컨테이너를 관리할 때 Quadlet을 선호한다는 점은 압니다. 하지만 서비스를 어디서든
git clone다음docker compose up -d두 명령만으로 배포하는 간결함은 포기하고 싶지 않습니다.- @Exagone313 — 지금까지 찾은 차이는 root가 예약한 포트를 공개할 수 없다는 점과 내부 네트워크가 실제로는 내부 네트워크가 아니라는 점입니다.
- @cyberia — 공식적으로 docker-compose는 Podman을 지원하지 않으므로
podman-compose를 써야 합니다. 그래도 저는 여기 설명한 설정을 몇 년째 쓰고 있고 잘 작동합니다. 다만 일부 예외 상황은 문서에 나오지 않을 수 있습니다. 지금 바로 떠오르지는 않지만 몇 가지 문제를 겪었습니다. - @hoistbypetard — 글에는 이유가 나오지 않는데 궁금합니다. 이미 Podman을 쓰면서
podman-compose대신docker-compose를 고른 이유가 있나요?- @Exagone313 — 마지막으로 확인했을 때
podman-compose는 기능이 많이 빠져 있었고 쉽게 문제가 생겼습니다. 그 뒤로 개선됐을 수도 있지만, 그때부터docker-compose를 계속 썼습니다. 그래도 관련 링크를 추가하겠습니다. - @hoistbypetard — 이해했습니다. 제게는 괜찮아 보였지만, 저는 Quadlet이 마음에 들어 Podman을 쓸 때 두 compose 도구에서 점점 멀어졌습니다.
- @Exagone313 — 저도 배포 환경은 Podman Quadlet으로 옮겼습니다. 처음에는 이 주제로 글을 쓰려 했지만 다루기에는 범위가 너무 컸습니다. 업무 개발용으로 Linux 머신을 쓸 때는 여전히 docker-compose를 사용합니다. 바탕에서 실제 Docker가 돌아가는 건 아니지만, 다른 사람과 같은 도구를 쓴다고 설명하기 쉽습니다.
- @Exagone313 — 마지막으로 확인했을 때
원문: Elouan Martinet / 번역·요약: Trawling