로컬 apt 미러로 행복코딩하기

Cover Image

apt-fast도 부족하다!! #

GitHub - ilikenwf/apt-fast: apt-fast: A shellscript wrapper for apt that speeds up downloading of packages.

GitHub - ilikenwf/apt-fast: apt-fast: A shellscript wrapper for apt that speeds …

apt-fast: A shellscript wrapper for apt that speeds up downloading of packages. - ilikenwf/apt-fast

github.com

Linux Ubuntu같은 OS를 설치할 때마다 항상 설치하는 패키지가 있으니, 바로 apt-fast입니다.

bash $ /bin/bash -c "$(curl -sL https://git.io/vokNn)"

apt는 패키지를 다운로드할 때 한 번에 하나의 파일을 다운로드하기 때문에, 대부분의 경우 네트워크 대역폭을 100% 뽑아먹지 못하는데요, apt-fast는 여러 개의 파일을 동시에 다운로드하기 때문에 시간을 확 줄일 수 있습니다.

그런데 최근 들어 rootfs를 빌드할 일이 잦아지며, 이것마저 불편해지기 시작했습니다.

그러던 중 든 생각..

나도 미러 만들까..?

텅텅 비어 있는 NAS도 있겠다, 이참에 로컬 apt 미러를 만들어보기로 했습니다.

NAS에 뭐 저장하세요? “로컬 apt 미러” #

GitHub - apt-mirror/apt-mirror: Official apt-mirror source.

GitHub - apt-mirror/apt-mirror: Official apt-mirror source.

Official apt-mirror source. Contribute to apt-mirror/apt-mirror development by creating an account on GitHub.

github.com

저 같은 생각을 한 사람들이 많은지, apt 미러를 쉽게 만드는 apt-mirror 프로젝트가 있었습니다.

GitHub - flavienbwk/apt-mirror-docker: Up to date apt-mirror script, containerized for mirroring + serving.

GitHub - flavienbwk/apt-mirror-docker: Up to date apt-mirror script, …

Up to date apt-mirror script, containerized for mirroring + serving. - flavienbwk/apt-mirror-docker

github.com

그리고 쉽게 실행할 수 있도록 Docker로 만들어둔 프로젝트도 여럿 있었습니다.

https://kycfeel.github.io/2019/07/22/Docker%EB%A1%9C-%EC%89%BD%EA%B2%8C-%EC%98%A …

kycfeel.github.io

그 중 국내 개발자가 만들어둔 https://github.com/kycfeel/dockerized-apt-mirror를 사용해 미러를 만들어보기로 했습니다.

→ 2025년 1월 26일 오후 8:20 - 사용된 apt-mirror가 오래되어, 지금 시점의 미러 디렉토리 구조를 완전히 따라가지 못했습니다. 윗쪽의 https://github.com/flavienbwk/apt-mirror-docker를 대신 사용합니다.

미러 볼륨 준비 #

1 TB가 넘어갈 apt 미러에 스냅샷이 찍히거나 백업되어 버리는 건 전혀 바라지 않기 때문에 분리된 dataset을 만들어주고,

nfs로 Docker host VM에 마운트했습니다.

미러 볼륨 준비 #

bash $ git https://github.com/flavienbwk/apt-mirror-docker && cd apt-mirror-docker $ nano mirror.list

리포지토리를 clone한 후 mirror.list 파일을 수정했습니다.

############# config ##################

#

set base_path /var/spool/apt-mirror #

#

set mirror_path $base_path/mirror #

set skel_path $base_path/skel #

set var_path $base_path/var #

set cleanscript $var_path/clean.sh #

set defaultarch amd64 arm64 set limit_rate 100m

set postmirror_script $var_path/postmirror.sh #

set run_postmirror 0 #

set nthreads 20 set _tilde 0

#

############# end config ##############

Ubuntu 22.04 LTS #

deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main restricted universe multiverse deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse

deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted universe multiverse deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted universe multiverse deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse

ROS2 Humble #

deb [arch=amd64] http://packages.ros.org/ros2/ubuntu jammy main deb [arch=arm64] http://packages.ros.org/ros2/ubuntu jammy main

clean http://archive.ubuntu.com/ubuntu/ clean http://ports.ubuntu.com/ubuntu-ports/ clean http://packages.ros.org/ros2/ubuntu/

Ubuntu를 M2 MacBook의 Parallels에서 사용하는 경우가 잦아 arm64를, ROS2도 가끔 사용해 역시나 집어넣었습니다.

접속 문제 임시 조치 (클릭해 펼치기) #

제 인터넷 환경의 문제인지, 아니면 트래픽 차단이 있는 건지 연결을 기다리는 상태가 지속되어 다운로드가 막히는 게 잦더라고요. apt-mirror의 wget 옵션을 변경해 타임아웃 시간을 줄여, 조금 대기가 걸린다 싶으면 다시 시도하고 포기하도록 했습니다. - https://github.com/TecArt/apt-mirror/commit/fff66a410668f12caa6baf30b41aefcb324e8c62#diff-a65c2f37bd03dc1df0a6f7bc3c15c7dd220d7e5ecd3242c3507efba075d95441R270

bash $ sudo docker exec -it (컨테이너 이름) sh

컨테이너 접속한 후 #

$ apt update && apt install nano -y $ nano /usr/bin/apt-mirror

exec 'wget' 을 찾은 뒤, 주석처리한 후 아래 내용 붙여 넣음 #

exec 'wget', '--no-cache', '--retry-connrefused', '--waitretry=2', '--read-timeout=12', '--dns-timeout=3', '--connect-timeout=3', '--tries=5', '--limit-rate=' . get_variable("limit_rate"), '-r', '-N', '-l', 'inf', '-o', get_variable("var_path") . "/$stage-log.$i", '-i', get_variable("var_path") . "/$stage-urls.$i", @args;

다운로드를 스킵하게 되면 로그에 기록이 되기 때문에, 첫 다운로드는 로그를 지켜보며 여러 번 명령을 실행하기로 했습니다. (하루가 지난 후 900GB 중 500GB정도가 다운로드에 실패했습니다 😢)

미러링 실행 #

마지막으로 docker-compose.yaml 파일의 볼륨 경로를 적당히 수정한 후, 실행!

bash $ docker-compose build $ docker-compose up mirror

열심히 다운로드하네요 🙂

웹서버 실행 #

어느정도 다운로드가 완료되었다면 웹서버를 실행합니다.

bash $ docker-compose up -d server

docker-compose에는 nginx 웹서버도 들어가 있기 때문에 80번 포트로 접속하면 미러 페이지가 열리게 됩니다.

테스트 #

다음날 확인해보니 다운로드가 완료되어 있었습니다. 총 용량은 1 TB 정도가 나오네요.

테스트 못참죠 🙂 깨끗한 VM을 하나 새로 만든 후 apt 다운로드 경로를 로컬 미러로 변경했습니다.

bash $ sudo nano /etc/apt/sources.list

apt update run!

로컬 서버에서 리스트를 잘 가져옵니다!

한번 설치도 해봐야죠. 커다란게 어떤게 있을까 고민하다가 ROS2 Humble을 다운로드해보기로 했습니다.

공식 Docs를 따라하되, source 리스트를 로컬 서버로 변경했습니다.

apt update 후, apt로 커다란 ros-humble-desktop-full를 다운로드했습니다.

bash $ sudo apt install --download-only ros-humble-desktop-full -y

로컬 미러에서 다운로드

무려 4초컷 🫢

글로벌 서버에서 다운로드

로컬 미러 대신 일반 서버에서 다운로드했을 때는 4분 반이 걸렸습니다.

마무리 #

6일간의 명절 기간동안 집을 비우는 김에 엄청난 트래픽을 유발.. 아니 아무튼 로컬 미러를 만들어보았습니다.

막상 지금 와서 생각해보니 집에서 코딩할 일이 많..나..? 싶기는 하지만, 일단 행복하니 된걸로 쳐야겠습니다 🙂