wisePocket

[NAS 배포★] 다시 원점으로, Docker Hub를 이용해보자 07_01 본문

Synology NAS Server Tutorials

[NAS 배포★] 다시 원점으로, Docker Hub를 이용해보자 07_01

ohnyong 2023. 7. 21. 20:15

1. Docker Hub를 가입하고 Test 레포지토리를 생성

2. Docker를 통해서 이미지 Push를 진행했지만 denied: requested access to the resource is denied 에러가 발생했다.

구글링을 통해 알아본 결과

  • docker hub에 로그인이 되지 않을 경우
  • user name과 docker hub 에 로그인된 ID가 일치하지 않을 경우

해당 에러가 발생 할 수 있다.

로그인과 이메일 인증은 완료된 상황이라 user name이 어디있고 어떻게 해결 할 수 있을지 찾아봤다.

 

우선 user name이 다름

현재 naspublish-flask, naspublish-nginx처럼 표기되어 있으나

dockhub와 연결되려면 <username>/naspublish-flask 처럼 username/이 앞에 붙어야 한다.

  • Docker 레지스트리 사용자 이름이 이미지를 생성하는 데 사용한 로컬 사용자 이름과 다른 경우 레지스트리 사용자 이름으로 이미지에 태그를 지정해야 합니다. 마지막 단계에 제공된 예의 경우 다음을 입력합니다.
  • ex) docker tag user/ubuntu-nodejs docker-registry-username/ubuntu-nodejs
  • public -> gildong/myweb:1.0 처럼 앞에 USER ID 를 입력해야 한다
  • private -> reg.test.com:5000/myweb:1.0 or 192.168.1.101:5000/myweb:1.0 처럼 앞에 주소를 입력해야 한다
  • local -> myweb:1.0 처럼 이미지 이름과 태그만 입력하면 된다

일단은 public으로 간단하게 user만 추가하는 식으로 하고 private는 registry를 구성하고하는 것이라 다음번에 시도하기로.

처음 프로젝트 배포 준비 할 때 Docker Image를 생성 할 때 태그옵션을 추가했었어야 한다. 간단히 image이름 앞에 user/가 들어가면 인식을 하는 것인지 아니면 특별히 tag의 기능이 있는지는 확실하지 않다. 일단은 user/image 간단히 이것을 인식하는 것으로 보여지는데 크게 어렵지 않을 것 같다. 이것은 일단 배포까지 진행되는지 테스트하고 이후에 생각하기로 했다.

 

3. image에 user Tag 붙이기

docker tag naspublish-nginx <user>/mynaspublish-nginx:1.0
docker tag naspublish-flask<user>/mynaspublish-flask:1.0

4. Tag가 붙은 새로운 이름의 image 푸시(Local PC -> DockerHub로)

docker push <user>/mynaspublish-nginx:1.0
docker push <user>/mynaspublish-flask:1.0

이로써 내가 원하던 형태로 이미지가 생성 됬으며, Docker hub에도 해당 이름의 repository가 자동 생성되고 image가 푸시되었다.

5. 원격 Repository에 있는 image Pull (DockerHub -> NAS로)

이 과정은 사실 내가 Docker를 사용할 때 다른 개발자들의 프로그램을 가져올때와 같은 상황인 것으로 보인다. 이제서야 deepdive/ docker/ 이렇게 이미지 이름 앞에 이름이 표시되는 이유를 알 것 같다.

Public으로 올렸기 때문에 나도 다른 개발자들 프로그램처럼 NAS의 Docker에서 user이름가지고 내가 올려둔 image를 확인 할 수 있었다. 

해당 이미지를 NAS Docker내로 다운받는다.

위 이미지를 받아오는 행동은 배포 첫 준비 과정때 Dockerfile로 이미지를 생성하던 과정을 이미 생성된 이미지를 카피해와서 Dockerfile에서 설정한 내용들은 이미 적용된 이미지들이라는 것이다.

6. NAS에서 컨테이너[flask(+uwsgi)이미지+nginx이미지] 구성하고 실행해보기

이제 docker-compose 행동이 필요하다.

NAS의 Docker는 경량화된 GUI를 가지고 있어서 조금 메뉴가 상이하다. 어쨋든 어떻게든 아래 그림처럼 2개의 이미지가 컨테이너에서 물려서 함께 돌아가면 되고, nginx의 포트는 80:80인것을 기억해두었다.

이 행동은 이전 docker-compose.yml에 작성한것을 수행하는 것이다.

 

무언가 문제가 발생했다. 의심되는 것은 image를 다운받아서 그런것인가?

그럼 이미 2개의 이미지를 담고있는 컨테이너 자체를 옮길순 없을까?

docker의 명령어를 보는 도중 export, import가 보였다. 하지만 이미지와 컨테이너는 개념이 다르다. 컨테이너는 이미지가 돌아가는 것이고, 이미지는 파일 자체기 때문에 이동이 되니까 어떻게든 2개 이미지를 NAS 안에서 묶어야 한다.

7. 다시 한번 docker-compose를 NAS에서 설치해보자.

NAS 저장소로 로컬에서 docker-compose CLI로 진행했던 폴더 자체를 옮겨왔다. 이전에 06에서 SSH 포트추가로 외부(로컬PC)에서 NAS를 접근하고자 한다. 

 

ssh - DDNS 설정한 외부접속을 통해 들어간다.

ssh nas-admin@test.synology.me

슈퍼유저(root권한)로 변경한다.

sudo -i

무언가 문제가 생긴다.

갑자기 무언가 까먹은 느낌에 NAS의 ubuntu 터미널로 돌아갔다.

apt-get install docker-compose

분명히 어제 안되던 것 같았는데 설치가 진행된다. 뭔가 오타가있었는지 잘못된 정보를 봤었는지 기억이 안난다. 아무튼 docker-compose가 설치되었다.

하지만 root계정 말고 $home을 접근 할 수 있는 상태(내 프로젝트 폴더를 볼 수 있는 곳)에서 docker-compose --version을 확인 할 수 없었다. stackoverflow에서 /tmp 폴더를 마운트 하라는 답변을 보았다.

결과 관리자 계정에서도 모두 Docker-compose 를 사용할 준비가 되었다.

8. 모든 준비가 되었다. Docker-compose 

 이제 NAS의 ubuntu 터미널에서 docker-compose.yml이 세팅되어있는 복사해둔 프로젝트가 있는 곳으로 이동하자.

nginx가 80번 포트를 사용하려는데 이미 바인드중이다. 어떻게 할 지 생각하다가 kill pid는 임시 방편이기 때문에 나의 프로젝트를 81번 포트로 옮겨주고 ddns에서 손봐주기로 결정했다. NAS가 웹 스테이션 자체에서 80번 포트를 사용중이라 어떻게 대처해야 될지 결정을 못했기 때문이다.

 

docker-compose.yml에서 80번 포트로 되어있는 부분을 81번 포트로 수정해야 한다.

수정된 파일을 NAS의 프로젝트 root폴더로 이동시키고

다시한번 빌드

이전과 다르게 이미 빌드가 끝난 부분은 재구성하지 않고 스킵하여 넘어가고 오류 부분이 수정된 것만 정상적으로 변경하고 컨테이너를 구성한다.

 

CLI로도 naspublish_nginx / naspublish_flask가 정상적으로 컨테이너가 구성된 모습을 볼 수 있다. WAS인 nginx는 (0.0.0.0):81번 포트로 연결되어 있다.

GUI로도 nginx(naspublish_nginx) / flask(naspublish_flask) 컨테이너가 정상적으로 생성되었으며, Local PC의 Docker Desktop과 비교해서 NAS에서는 1개의 컨테이너 묶음으로 표현되지는 않는것 같다. 

192.168.0.10:81 로 접속하면 해당 프로젝트가 정상적으로 작동하는 것을 볼 수 있다. 아주 소규모 프로젝트지만 사실 로그인(세션,쿠키) 관리와 OAuth Token활용, 계정 타입(admin/user/guest)에 따른 유저별 페이지 구분, 네비게이션 구현, ajax는 볼 수 없는 프로젝트지만 OpenAPI인 날씨 정보, MongoDB의 Cloud 서비스인 Atlas와의 연동으로 CR(UD)기능 기록 및 목록출력, 가수노래순위순위변동이 연결된 웹 크롤링 기능, CSS, JS 등 핵심적인 기능 모두 정상적으로 작동한다.

 


이제 해야할 것

 

192.168.0.10은 NAS의 내부 IP주소이며 :81포트 또한 내부 IP주소의 포트이다. 80번은 DSM으로 접속해야하는 경우 필요하기 때문에 남겨두어야 한다.

외부 접속 DDNS설정을 통해 내가 NAS서버 DSM에 접속하는 것 처럼 81번 포트로 들어갈 수 있도록 외부 접속 루트를 연결 시켜야 한다.

 

나의 도메인을 사용할지 Synology의 도메인을 사용할지 생각해봐야 된다. 아무튼 도메인에서 서브 도메인을 분기하고 각 서브도메인마다 DSM, 해당 웹페이지, 회사 홈페이지를 각각 포트로 연결하여 외부 접속시 구분되도록 한다.


배포 및 버전 관리에 대한 생각

해당 프로젝트 경험으로 추후 프로젝트 구성 시, NAS Drive를 통해 작업 파일 수정이 실시간으로 적용 되어야 할 지, 배포 과정을 버전관리화 시켜서 배포 타이밍에만 업로드 및 백업을 해야 할 지 생각해야 한다. 분명히 실시간 수정 및 반영은 좋겠지만 NAS 서버로의 데이터 이동의 시간이 문제다. 따라서 Git을 통해서 작업 관리를 하고 특정 버전 출시 시 NAS로 동기화 시키는 것이 맞다. 하지만 NAS에서 배포 버전이 덮어 씌워지면 과거 백업이 사라지기 때문에, NAS의 백업 기능을 활용해서 지속적인 백업, 버전업 배포 과정으로 진행해야 올바른 선택일 것 같다. 말 그대로 배포는 프로젝트에서 여러번 하지 않는다. 규모에 따라 다르지만 1.0 2.0 또는 1.1.0 1.2.0 수준으로 기능이 추가 되고 테스트 되었을 때 배포하는 것이 맞지 않을까. 그만큼 자주 있는 일은 아닐 것 같지만, 스스로 이해해서 너무 뿌듯하다.


사실 너무 많은 길을 돌아가고 아직까진 잘 이해안되거나 몰라도 되는 부분까지 시도해봤다. 간단하게 이제와서야 이렇게 하면 되겠네 라고 볼 수 있게 됬지만 시행착오 과정에서 어깨넘어 배운 지식과 이런것도 있네?하는 배워 봐야 겠다고 생각이 든 부분이 쌓인게 엄청 많다.

 

아래는 위 과정을 작성하며 실습을 진행하다가 산으로 가던 과정을 일단 지우지 않고 기록해두려한다. Docker를 사용하는것 정말 파면 팔수록 엄청 많은 것들이 쏟아져 나오고 너무 유용하다.


 

더보기

3. Private Registry 구현

조금 더 찾아보니 docker hub에 push, pull 하기 위해서는 registry라는 과정이 필요하다.

 

1. registry 관련 이미지 풀

GUI로 진행해도 되지만 참고 blog에 따라 CLI로 진행했다.

 

 

docker pull registry

 

docker pull hyper/docker-registry-web

2. 이미지 저장소와 인증

이미지 저장소에 인증정보를 보내야 한다. 3종류가 있다.

  • public registry : docker hub에 공개된다. 모든 사용자가 이미지를 push할 수 있고 pull은 하루 100개 받을 수 있다.
  • private registry : 특정 사용자 / 그룹 사용자만 접속 할 수 있다. 로그인 할때는 docker login 주소를 입력해야 한다
  • local registry : 사용자만 사용한다. 컨테이너 생성시 1차적으로 local registry를 검색한다(내 PC에 docker 앱, 패키지가 직접 설치한 그 공간이다.)

registry 구축해보기 5001포트로 변경(Mac 포트충돌)

docker container run -d -p 5001:5000 --restart=always -name registry -v /home/rapa/registry:/var/lib/registry registry

블로그에 안내된 커맨드를 입력했으나

뭔가 커맨드가 변경되었나? docker container run --help로 옵션들을 살펴보았다.

-name이라는 태그를 못읽는다 검색해보니

--name으로 표기되어야 하는것 같다.

 

이번엔 다른 문제가 생겼다. 내가 보기엔 경로에 이상이 있는것 같다. /home/rapa/registry/ ? 이미지의 경로를 확인해보았다. 역시나 처음보는 경로다.

조금더 찾아보았다. MacOS는 원래 Docker를 지원하지 않는데 Hyperkit이란것을 이용해서 이미지를 실행한다고 한다.

  • Docker는 기본적으로 macOS와 호환되지 않으므로 Hyperkit을 사용하여 가상 이미지를 실행합니다. 가상 이미지 데이터는 다음 위치에 있습니다.

그리고 OS마다 docker 컨테이너, 이미지 저장소 위치는 참고겸 기록해둔다.

  • Ubuntu: /var/lib/docker/
  • Fedora: /var/lib/docker/
  • Debian: /var/lib/docker/
  • Windows: C:\ProgramData\DockerDesktop, C:\Program Files\Docker\Docker
  • MacOS: ~/Library/Containers/com.docker.docker/Data/vms/0/

따라서 ~/Library/Containers/com.docker.docker/Data/vms/0/로 이동해보았다.

그럼  /var/lib/docker/부분을 ~/Library/Containers/com.docker.docker/Data/vms/0/ 로 변경해볼까 했더니 애초에 이미지 자체도 안보인다.

더찾아보니 MacOS의 도커 구조는 다음과 같다.

/var/lib/docker 디렉토리가 없는 이유 그저 LinuxKit VM으로 가동되기 때문에 결국 Linux 가상머신에 접속해야 찾을 수 있던 것이다. 따라서 경로를 지정하는 저 방식은 사용 할 수 없다. 사용하더라도 프로세스 아이디가 식별하기 어렵고 복잡할 것이다. MacOS에서 Docker를 사용하면 아무 컨테이너를 가동안시켜도 기본적으로 메모리를 엄청 잡아먹고있다. 그 이유는 애초에 VM이 계속 돌아가고 있던것이다.

 

그럼 어떻게 진행 해야 하는가? 

Docker는 이러한 점에서 File sharing이란 기능이 있다. 해당 기능에서 어찌저찌하면 될 것 같지만 시간이 너무 오래 걸린다.

해당 부분에 마지막줄

/var/lib/docker 라는 경로를 추가해보았다. 안된다!! 뭔가 구조가 다르다.