(22.06.24) 이제와서 다시 보니 처음에는 docker를 쓸 줄 몰라 참 신기한 방법으로 만들었던 적이 있었습니다.
이 글에서 설명하는 방법은 너무 무식한 방법이니 가능한 따라하지 않으시길 권장드립니다.
정석대로 폴더 하나 만드신 뒤 그곳에 "dockerfile"이라는 이름으로 docker를 설명하는 파일을 만드신 뒤 해당 폴더에서 docker build 태그명 으로 매우 쉽고 편하고 정상적으로 만드실 수 있습니다.
dockerfile에는 검색해보시면 많이 나오겠지만,
FROM 태그명 으로 기존 베이스가 되는 이미지를 불러오고
WORKDIR 위치(컨테이너 내) 으로 working directory를 설정하시고
COPY 원본 컨테이너내위치 로 필요한 파일들을 복사하신 뒤
RUN 커맨드 로 python moulde 설치(pip -r requirements.txt)나 apt-get install xxx 등 원하는 명령어를 실행시켜놓은 컨테이너를 생성할 수 있습니다.
ENTRYPOINT ["명령어", "arg"] 로 컨테이너 시작 시 수행할 명령어를 지정하고
ENV 환경변수이름 값 으로 필요한 환경변수들을 미리 지정할 수 있습니다.
Docker를 처음 써보는 탓에 좀 삽질 했습니다.
따라서 저도 기억할 겸 누군가 저랑 비슷한 분께 도움되고자 글로 남겨 놓습니다.
일단 CentOS 같은 OS image에서부터 시작하면 python도 직접 깔아줘야할테고 갈 길이 너무 멀어보여
python 이미지를 받아 거기서부터 python 필요 module 설치하도록 제작하고자 했습니다.
1. Python 이미지 준비
저는 복잡한 프로그램을 돌릴 예정이 아니기 때문에 python 3.9 slim 이미지를 받아 사용했습니다.
2. 컨테이너 생성
Base가 되는 이미지로부터 [실행]을 선택하면 새로운 컨테이너를 만들 수 있습니다.
컨테이너 이름을 원하시는 대로 설정한 뒤 그냥 생성하면 되는데,
혹시 만들고자 하는 컨테이너가 실행하게 할 명령어 등을 이미 생각해 놓으셨다면 [고급설정]에서 [환경] 탭에 명령어를 넣어 줄 수 있습니다.
위 스크린 샷의 경우 /app/web_bot.py 라는 폴더와 파일이 아직 컨테이너 내에 만들어지지 않았을테지만 나중에 명령어 수정하는게 귀찮기 때문에 먼저 써주는 것 입니다.
(그냥 기본인 python3 로 놔두는 것이 더 나을 수 있습니다. 왜냐하면 경로에 파일 넣어주기 전까지는 컨테이너가 구동 시키자마자 오류로 꺼져버리기 때문입니다.)
필요한 환경변수등도 넣어주면 좋은데, 저는 "date" 명령어 사용을 위해 TZ (timezone)을 넣어주고 있습니다.
2.5 컨테이너 실행 명령어 변경
앞서 컨테이너 생성 시 실행 명령을 넣어주지 않았거나, 실행해야할 명령어가 변경된 경우 실행 명령을 변경하는 방법입니다.
일단 Synology의 docker 앱 내에서는 이미 만들어져 있는 컨테이너의 실행 명령을 바꾸는 메뉴가 없습니다.
아마 2번 방법으로 파일 추가한 뒤 cmd 창에서 이 컨테이너를 comit 해 이미지로 만들고 다시 그것을 컨테이너로 실행할 때 명령어를 주고, 이를 push하기 위해서는 다시 이 컨테이너를 comit해 이미지로 저장해야 할 것으로 보입니다.
제가 적어놓은 방법은 이미 존재하는 컨테이너의 실행 명령어를 변경하는 방법입니다. (저처럼 아까 2번에서 명령어를 올바르게 설정하신 분들은 하실 필요 없습니다.)
1.일단 혹시 컨테이너가 실행중이면 중지를 누르고 자동시작도 꺼주시기 바랍니다.
2. [설정]->[내보내기]로 컨테이너의 설정을 내보냅니다.
내보내신 경로에 가시면 컨테이너명.json 파일이 있습니다.
3. 그 파일 내에 "cmd"라는 항목을 바꿔주시면 됩니다.
4. [설정]->[가져오기]로 수정한 json을 불러와 새로운 컨테이너를 만듭니다.
이 때 컨테이너 이름은 중복되지 않아야 하기에 원본컨테이너를 지우거나 다른 이름으로 설정하셔야 합니다.
+ 설정만 가져오는 메뉴이기에 혹시 이미지로부터 파일 수정이 있었을 경우 반영되지 않습니다.
3. 컨테이너 파일(스트립트 등) 복사
이렇게 컨테이너를 생성 한 뒤 저는 위에서 기술한 /app/web_bot.py와 module 설치에 필요한 /app/requirments.txt를 컨테이너안에 복사해 줍니다.
저의 경우 컨테이너 내에 폴더를 만들어주기보다는 NAS에서 필요한 파일들을 넣어 app 폴더를 준비한 뒤 폴더를 통째로 복사해주는 방법을 사용했습니다.
***아래 docker 명령어 들은 NAS에 ssh 접속한 뒤 "sudo -i"로 root로 변경한 뒤 실행하였습니다.
docker container cp 복사원본 컨테이너이름:/경로
의 방법으로 특정 컨테이너의 특정 위치에 원하는 파일이나 폴더를 복사할 수 있습니다.
(원본과 경로를 반대로 사용하여 컨테이너 속 파일/폴더를 밖으로 복사할 수도 있습니다.)
docker container diff 컨테이너이름
을 통해 제대로 파일이 들어가 있는지 확인할 수 있습니다.
diff로 확인하는 내역 중 A가 추가된 내역이 C가 변경된 내역인 것으로 알고 있습니다.
4. Python 모듈 설치
이 부분이 저도 나름 힘들었던 부분입니다.
위에서 저처럼 이미 실행 명령을 python3 /app/블라블라.py 로 변경해 놓으신 분들의 경우 경로에 파일이 없으면 컨테이너가 바로 종료 되는 것을 겪었을 것입니다.
경로에 넣어준 지금도 추가로 필요한 python module이 설치되어 있지 않아 바로 종료되어 버립니다.
pip 명령어를 실행해줄 틈도 없이 말이죠.
그럼 명령어를 먼저 설정해주지 않고 기본명령어(python3)로 놔두면 pip 설치할 수 있지 않냐.
맞습니다. 다만 제가 사용하는 방법에서는 그렇게 pip설치하고 파일 복사 완료된 뒤 명령어 변경하면 [가져오기]하면서 컨테이너를 새로 만들어버리기에 파일들이 유지가 안됩니다.
그래서 제가 처음 사용한 방법은 [내보내기]에서 컨테이너의 설정과 파일도 함께 내보내기를 하는 방법입니다.
기본명령어 상태로 컨테이너를 생성 후 파일 복사, pip설치 등 완료 후 내보내기를 하고,
이렇게 나온 txz 압축파일을 풀어보면 json 파일이 있으니 거기에서 명령어 수정 후 다시 txz파일로 압축한 뒤 [가져오기]로 txz 파일을 통째로 가지고 오는 방법입니다.
( + txz 내부에 tar 파일이 있는데 파일 복사 등은 여기 tar 파일 내부에 파일을 직접 넣어줘도 됩니다.)
이 경우 압축을 풀었다 다시 압축했다 좀 귀찮다고 생각됩니다.
제가 최근에 사용하는 방법은 위에서 부터 쭉 내려온 대로 명렁어를 완성해서 넣어준 채 파일을 복사하고
pip 설치를 위해 임시 파일을 사용하는 방법입니다.
제가 임시로 올릴 python 스크립트입니다. 별도의 module 설치 없이 수행되며 아무것도 하지 않습니다. 단지 컨테이너가 꺼지지 않도록 하기 위함입니다. 저는 이 파일을 temp.py에 저장했습니다.
그리고 앞서 사용한 파일 복사 명령어를 이용해 세팅된 명령어에 의해 실행될 파일을 덮어썼습니다.
docker container cp 임시파일 컨테이너명:/명령어실행파일
이제 컨테이너를 실행시키고 pip로 필요 모듈을 설치해줍니다. (terminal 상에서 진행하는 방법으로 되어있지만, synology web 상에서도 실행 후 [세부사항]->[터미널]->[실행]->bash 에서 "pip install ~~~~~" 이런 식으로 진행하셔도 됩니다.
docker container start 컨테이너명
docker exec 컨테이너명 pip install -r requirments파일
물론 이렇게 설치 완료하신 뒤 아까 올려놓은 임시 파일을 다시 원래 파일 목적한 실행 파일로 꼭 다시 변경하셔야 합니다.
docker container cp 원본파일 컨테이너명:/경로/파일
5. 컨테이너 실행하여 이상여부 확인 후 이미지로(commit)
web상에서 혹은 cmd창에서 완성한 컨테이너를 동작시켜 이상여부를 확인합니다.
docker container restart 컨테이너명
이상이 없을경우 이제 이 "컨테이너"를 "이미지"로 만드는 commit을 수행합니다.
docker commit 컨테이너명 이미지명:태그
"docker images"를 통해 이미지 목록을 확인할 수 있습니다.
이제 image가 완성되었기 때문에, 이미지를 기준으로 컨테이너를 다시 만드셔도 변경한 파일과 실행명령어 등이 유지됩니다.
6. Docker허브에 업로드(push)
docker 허브에 올려놓는 경우 docker login 으로 로그인 하신 후 push 명령어를 통해 올리실 수 있습니다.
docker push 아이디/이미지이름:태그
제가 설명한 방법 중 잘 못된 방법이나 비효율적인 방법 등이 있을 수 있습니다.
저도 docker로 뭔가를 만들어본게 처음이기에 여기저기 검색해서 try and error로 열심히 시도해보면서 찾은 방법들이고,
docker에 대해 아직도 모르는 내용이 너무 많습니다.
혹시 보시고 comment 주실 내용, 조언이 있으신 경우 언제든 댓글 부탁드립니다.
'PC > Linux' 카테고리의 다른 글
lmstat, command not found 해결 (0) | 2020.11.25 |
---|---|
undefined symbol: FT_Done_MM_Var 오류 해결 (0) | 2020.11.25 |
Raspberry pi Zero W - Hotspot 만들기 (0) | 2019.10.15 |
Cshell rc설정 (0) | 2017.03.26 |
메모리 정리 (0) | 2017.03.25 |
댓글