[TOC]
개요
회사에서 방화벽 때문에 집 서버(?) 또는 AWS 서버 접근을 위해 아이폰, 아이패드를 쓰면서 구글 클라우드 웹베이스 (http 80) 터미널 서비스 사용할 수 있으면 좋겠다 생각에 찾아보다 포기했는데 오늘(`18. 10/05) 혹시나 하고 검색할 하니 딱 그래서 기존 NextCloud 컨테이너 HTTPS 서비스를 엮어서 만들어 보기로 함
참고 :
Setup Web Terminal using Wetty Docker Image – Chairat.me – Medium,
krishnasrinivas/wetty - Docker Hub
What is Wetty? Web + tty
Wetty = Web + tty.
Terminal over HTTP and HTTPS. Wetty uses ChromeOS’ terminal emulator (hterm) which is a full fledged implementation of terminal emulation written entirely in Javascript. Also it uses websockets instead of Ajax and hence better response time.
Source: https://github.com/krishnasrinivas/wetty
git clone
- 복제 (Clone) Wetty repository on GitHub.
bori@BorilikeGame:/media/usbhdd1$ git clone git@github.com:krishnasrinivas/wetty.git
'wetty'에 복제합니다...
The authenticity of host 'github.com (192.30.255.113)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.255.113' (RSA) to the list of known hosts.
git@github.com: Permission denied (publickey).
fatal: 리모트 저장소에서 읽을 수 없습니다
올바른 접근 권한이 있는지, 그리고 저장소가 있는지
확인하십시오.
bori@BorilikeGame:/media/usbhdd1$ git clone https://github.com/krishnasrinivas/wetty.git
'wetty'에 복제합니다...
remote: Enumerating objects: 214, done.
remote: Total 214 (delta 0), reused 0 (delta 0), pack-reused 214
오브젝트를 받는 중: 100% (214/214), 381.18 KiB | 587.00 KiB/s, 완료.
델타를 알아내는 중: 100% (102/102), 완료.
Dockerfile 설정 및 이미지 생성
- 원본 Dockerfile
FROM node:0.10.38
MAINTAINER Nathan LeClaire <nathan@docker.com>
ADD . /app
WORKDIR /app
RUN npm install
RUN apt-get update
RUN apt-get install -y vim
RUN useradd -d /home/term -m -s /bin/bash term
RUN echo 'term:term' | chpasswd
EXPOSE 3000
ENTRYPOINT ["node"]
CMD ["app.js", "-p", "3000"]
This tells us that:
- Wetty is a Node.js application.
- It creates a new user
term
which we can use to logon. - The web interface is exposed at port 3000
host User vs Docker container User
user term > bori (term은 docker 컨테이너 user, bori는 host user)
plex의 경우 환경 변수로 UID/GID을 전달 하여 권한을 동일하게 생성, host에서 볼경우 host UID와 동일한 User 명으로 보임
Dockerfile :
version: '2'
services:
plex:
container_name: plex
image: plexinc/pms-docker:public
restart: unless-stopped
environment:
- TZ=Asia/Seoul
- PLEX_CLAIM=claim-RzsUttmeYHj5T9EBk44F
- PLEX_UID=123 # host user deluge's UID
- PLEX_GID=33 # host group www-data UID
network_mode: host
volumes:
- /var/lib/deluge/config:/config
- /var/lib/deluge/transcode:/transcode
- /media/usbhdd1/shares:/data
- /media/usbhdd2:/media/data2
실행 프로세스 :
bori@BorilikeGame:/media/usbhdd1/plex/pms-docker$ ps -ef|grep plex
root 7188 5731 0 20:08 ? 00:00:00 s6-supervise plex
deluge 7190 7188 0 20:08 ? 00:00:00 /bin/sh -c LD_LIBRARY_PATH=/usr/lib/plexmediaserver /usr/lib/plexmediaserver/Plex\ Media\ Server
deluge 7199 7190 0 20:08 ? 00:00:24 /usr/lib/plexmediaserver/Plex Media Server
deluge 7301 7199 0 20:08 ? 00:00:28 Plex Plug-in [com.plexapp.system] /usr/lib/plexmediaserver/Resources/Plug-ins-10d48da0d/Framework.bundle/Contents/Resources/Versions/2/Python/bootstrap.py --server-version 1.13.8.5395-10d48da0d /usr/lib/plexmediaserver/Resources/Plug-ins-10d48da0d/System.bundle
deluge 7410 7199 0 20:08 ? 00:00:52 /usr/lib/plexmediaserver/Plex DLNA Server
deluge 7413 7199 0 20:08 ? 00:00:00 /usr/lib/plexmediaserver/Plex Tuner Service /usr/lib/plexmediaserver/Resources/Tuner/Private /usr/lib/plexmediaserver/Resources/Tuner/Shared 1.13.8.5395-10d48da0d 32600 /waitmutex
동일하게 안해주면 term 어떤 user의 권한을 갖게 될까? term vs root ? Root 정답
bori@BorilikeGame:/media/usbhdd1/wetty$ ps -ef |grep node
root 854 1 0 10월05 ? 00:00:12 /sbin/mount.ntfs-3g /dev/sdb1 /media/usbhdd1 -o rw,noexec,nosuid,nodev,permissions,users
root 25295 25276 0 01:03 ? 00:00:00 node app.js -p 300
원본 Dockerfile로 local 이미지 생성
- node.js (0.10.38) docker 이미지 pull
- 이미지 관리자 등록
- Host ./app 디렉토리는 docker 이미지에 추가
- docker 실행 디렉토리를 /app로 설정
- npm 설치 및 wetty 설치 (pty.js@0.3.1 install /app/node_modules/pty.js)
- RUN apt-get update
- RUN apt-get install -y vim
- RUN useradd -d /home/term -m -s /bin/bash term
- RUN echo 'term:term' | chpasswd
- EXPOSE 3000
- ENTRYPOINT ["node"]
- CMD ["app.js", "-p", "3000"]
bori@BorilikeGame:/media/usbhdd1/wetty$ docker build -t test1/wetty .
Sending build context to Docker daemon 1.04MB
Step 1/12 : FROM node:0.10.38
0.10.38: Pulling from library/node
df22f9f3e4ec: Pull complete
a3ed95caeb02: Pull complete
cd3f33f3eac9: Pull complete
29b84dd39cd5: Pull complete
a85bd624bab4: Pull complete
505aadf959ef: Pull complete
8eedbbe23e7b: Pull complete
Digest: sha256:e2a5045398e7f867e51c73eee2b3e6ec64716d1907c4c37acb5dee0493154d95
Status: Downloaded newer image for node:0.10.38
---> 82073591bd0c
Step 2/12 : MAINTAINER Nathan LeClaire <nathan@docker.com>
---> Running in 14c453cdcae0
Removing intermediate container 14c453cdcae0
---> 172721b4b00e
Step 3/12 : ADD . /app
---> a71bb11bc69b
Step 4/12 : WORKDIR /app
---> Running in 520a73b4fcf5
Removing intermediate container 520a73b4fcf5
---> ebd355bb28bd
Step 5/12 : RUN npm install
---> Running in 9f7b6e51b0e8
npm WARN deprecated minimatch@0.2.14: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated coffee-script@1.3.3: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN deprecated connect@2.14.1: connect 2.x series is deprecated
npm WARN deprecated graceful-fs@1.2.3: please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js
> pty.js@0.3.1 install /app/node_modules/pty.js
> node-gyp rebuild
make: Entering directory '/app/node_modules/pty.js/build'
CXX(target) Release/obj.target/pty/src/unix/pty.o
SOLINK_MODULE(target) Release/obj.target/pty.node
COPY Release/pty.node
make: Leaving directory '/app/node_modules/pty.js/build'
npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated static-favicon@1.0.0: use serve-favicon module
grunt-mkdir@0.1.3 node_modules/grunt-mkdir
grunt-contrib-clean@0.6.0 node_modules/grunt-contrib-clean
└── rimraf@2.2.8
optimist@0.6.1 node_modules/optimist
├── wordwrap@0.0.3
└── minimist@0.0.10
grunt-shell@1.3.1 node_modules/grunt-shell
├── object-assign@4.1.1
├── npm-run-path@1.0.0 (path-key@1.0.0)
└── chalk@1.1.3 (escape-string-regexp@1.0.5, supports-color@2.0.0, ansi-styles@2.2.1, has-ansi@2.0.0, strip-ansi@3.0.1)
load-grunt-tasks@3.5.2 node_modules/load-grunt-tasks
├── arrify@1.0.1
├── resolve-pkg@0.1.0 (resolve-from@2.0.0)
├── pkg-up@1.0.0 (find-up@1.1.2)
└── multimatch@2.1.0 (array-differ@1.0.0, array-union@1.0.2, minimatch@3.0.4)
grunt-git@0.3.7 node_modules/grunt-git
└── flopmang@0.0.1 (underscore.string@2.4.0, underscore@1.9.1)
grunt@0.4.5 node_modules/grunt
├── dateformat@1.0.2-1.2.3
├── which@1.0.9
├── getobject@0.1.0
├── eventemitter2@0.4.14
├── rimraf@2.2.8
├── colors@0.6.2
├── async@0.1.22
├── grunt-legacy-util@0.2.0
├── hooker@0.2.3
├── exit@0.1.2
├── nopt@1.0.10 (abbrev@1.1.1)
├── glob@3.1.21 (inherits@1.0.2, graceful-fs@1.2.3)
├── lodash@0.9.2
├── minimatch@0.2.14 (sigmund@1.0.1, lru-cache@2.7.3)
├── coffee-script@1.3.3
├── underscore.string@2.2.1
├── iconv-lite@0.2.11
├── findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.2)
├── grunt-legacy-log@0.1.3 (grunt-legacy-log-utils@0.1.1, underscore.string@2.3.3, lodash@2.4.2)
└── js-yaml@2.0.5 (argparse@0.1.16, esprima@1.0.4)
socket.io@1.7.4 node_modules/socket.io
├── object-assign@4.1.0
├── socket.io-adapter@0.5.0
├── has-binary@0.1.7 (isarray@0.0.1)
├── debug@2.3.3 (ms@0.7.2)
├── socket.io-parser@2.3.1 (isarray@0.0.1, component-emitter@1.1.2, json3@3.3.2, debug@2.2.0)
├── engine.io@1.8.5 (base64id@1.0.0, cookie@0.3.1, engine.io-parser@1.3.2, ws@1.1.5, accepts@1.3.3)
└── socket.io-client@1.7.4 (to-array@0.1.4, indexof@0.0.1, component-emitter@1.2.1, object-component@0.0.3, component-bind@1.0.0, backo2@1.0.2, parseuri@0.0.5, engine.io-client@1.8.5)
express@3.5.1 node_modules/express
├── methods@0.1.0
├── merge-descriptors@0.0.2
├── debug@0.8.1
├── cookie-signature@1.0.3
├── range-parser@1.0.0
├── fresh@0.2.2
├── buffer-crc32@0.2.1
├── cookie@0.1.1
├── mkdirp@0.3.5
├── commander@1.3.2 (keypress@0.1.0)
├── send@0.2.0 (mime@1.2.11)
└── connect@2.14.1 (response-time@1.0.0, pause@0.0.1, method-override@1.0.0, vhost@1.0.0, connect-timeout@1.0.0, static-favicon@1.0.0, qs@0.6.6, serve-static@1.0.2, basic-auth-connect@1.0.0, morgan@1.0.0, bytes@0.2.1, raw-body@1.1.3, errorhandler@1.0.0, csurf@1.0.0, cookie-parser@1.0.1, compression@1.0.0, express-session@1.0.2, serve-index@1.0.1, multiparty@2.2.0)
pty.js@0.3.1 node_modules/pty.js
├── extend@1.2.1
└── nan@2.3.5
Removing intermediate container 9f7b6e51b0e8
---> 58bae3cbe0cb
Step 6/12 : RUN apt-get update
---> Running in 0ddf84411480
Get:1 http://security.debian.org jessie/updates InRelease [44.9 kB]
Get:2 http://security.debian.org jessie/updates/main amd64 Packages [676 kB]
Ign http://httpredir.debian.org jessie InRelease
Get:3 http://httpredir.debian.org jessie-updates InRelease [145 kB]
Get:4 http://httpredir.debian.org jessie Release.gpg [2420 B]
Get:5 http://httpredir.debian.org jessie Release [148 kB]
Get:6 http://httpredir.debian.org jessie-updates/main amd64 Packages [23.0 kB]
Get:7 http://httpredir.debian.org jessie/main amd64 Packages [9098 kB]
Fetched 10.1 MB in 14s (697 kB/s)
Reading package lists...
Removing intermediate container 0ddf84411480
---> 1911c80f38fb
Step 7/12 : RUN apt-get install -y vim
---> Running in e39beccd561e
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
libgpm2 vim-common vim-runtime
Suggested packages:
gpm ctags vim-doc vim-scripts
The following NEW packages will be installed:
libgpm2 vim vim-common vim-runtime
0 upgraded, 4 newly installed, 0 to remove and 207 not upgraded.
Need to get 6219 kB of archives.
After this operation, 28.9 MB of additional disk space will be used.
Get:1 http://httpredir.debian.org/debian/ jessie/main libgpm2 amd64 1.20.4-6.1+b2 [34.0 kB]
Get:2 http://httpredir.debian.org/debian/ jessie/main vim-common amd64 2:7.4.488-7+deb8u3 [185 kB]
Get:3 http://httpredir.debian.org/debian/ jessie/main vim-runtime all 2:7.4.488-7+deb8u3 [5048 kB]
Get:4 http://httpredir.debian.org/debian/ jessie/main vim amd64 2:7.4.488-7+deb8u3 [953 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 6219 kB in 8s (715 kB/s)
Selecting previously unselected package libgpm2:amd64.
(Reading database ... 27882 files and directories currently installed.)
Preparing to unpack .../libgpm2_1.20.4-6.1+b2_amd64.deb ...
Unpacking libgpm2:amd64 (1.20.4-6.1+b2) ...
Selecting previously unselected package vim-common.
Preparing to unpack .../vim-common_2%3a7.4.488-7+deb8u3_amd64.deb ...
Unpacking vim-common (2:7.4.488-7+deb8u3) ...
Selecting previously unselected package vim-runtime.
Preparing to unpack .../vim-runtime_2%3a7.4.488-7+deb8u3_all.deb ...
Adding 'diversion of /usr/share/vim/vim74/doc/help.txt to /usr/share/vim/vim74/doc/help.txt.vim-tiny by vim-runtime'
Adding 'diversion of /usr/share/vim/vim74/doc/tags to /usr/share/vim/vim74/doc/tags.vim-tiny by vim-runtime'
Unpacking vim-runtime (2:7.4.488-7+deb8u3) ...
Selecting previously unselected package vim.
Preparing to unpack .../vim_2%3a7.4.488-7+deb8u3_amd64.deb ...
Unpacking vim (2:7.4.488-7+deb8u3) ...
Processing triggers for mime-support (3.58) ...
Processing triggers for hicolor-icon-theme (0.13-1) ...
Setting up libgpm2:amd64 (1.20.4-6.1+b2) ...
Setting up vim-common (2:7.4.488-7+deb8u3) ...
Setting up vim-runtime (2:7.4.488-7+deb8u3) ...
Processing /usr/share/vim/addons/doc
Setting up vim (2:7.4.488-7+deb8u3) ...
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rvim (rvim) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rview (rview) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vi (vi) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/view (view) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/ex (ex) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode
Processing triggers for libc-bin (2.19-18) ...
Removing intermediate container e39beccd561e
---> c60d37c468ed
Step 8/12 : RUN useradd -d /home/term -m -s /bin/bash term
---> Running in f82a2f83d110
Removing intermediate container f82a2f83d110
---> c56b63b3269b
Step 9/12 : RUN echo 'term:term' | chpasswd
---> Running in 15a67f045d1c
Removing intermediate container 15a67f045d1c
---> 0cdc1b15fa91
Step 10/12 : EXPOSE 3000
---> Running in 0346033eb953
Removing intermediate container 0346033eb953
---> 5e8ec625fb12
Step 11/12 : ENTRYPOINT ["node"]
---> Running in 5b0afc0f4aee
Removing intermediate container 5b0afc0f4aee
---> 8c971e854126
Step 12/12 : CMD ["app.js", "-p", "3000"]
---> Running in b78782e4c09b
Removing intermediate container b78782e4c09b
---> bd1510e14524
Successfully built bd1510e14524
Successfully tagged test1/wetty:latest
bori@BorilikeGame:/media/usbhdd1/wetty$ docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
test1/wetty latest bd1510e14524 About a minute ago 786MB
컨테이너 생성
docker-compose.yml 파일 생성
- 기존 nginx-proxy 및 SSL 컨테이너 활용 - 환경 변수 및 docker bridge NW apache_porxy-tier 연결
- 공식 도메인으로 wty.igotoo.pw 사용
version: '3'
services:
webtty:
container_name: webtty
image: test1/wetty
restart: always
environment:
- VIRTUAL_HOST=wty.igotoo.pw
- LETSENCRYPT_HOST=wty.igotoo.pw
- LETSENCRYPT_EMAIL=igotoo@gmail.com
networks:
default:
external:
name: apache_proxy-tier
문제 및 해결
문제 : 문법 오류 , 원인 및 해결 : docker-compose 파일 생성시 tab 아닌 space로 간격 조정 ---> yml 파일 작성 문번 공부 필요
문제 : 기존 nextcloud 컨테이너의 내부 네트워크 proxy-tier에 연결 안됨, 원인 및 해결 : porxy-tier는 wetty 컨테이너에게는 외부 네트워크이므로 externl 로 연결 해주어야 함. docker-compose는 하나 이상의 컨테이너를 묶어 별도의 공간(?) 을 만드는 것 같은 --> 공부 (참고 : Networking in Compose | Docker Documentation)
docker NW
bori@BorilikeGame:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
d323e7509923 apache_default bridge local
347d9a3ffcfb apache_proxy-tier bridge local
9d76205ec57f bridge bridge local
3b89db5f0168 composetest_default bridge local
204769fe9090 docker-gen_default bridge local
a0615c56eae4 docker-proxy_default bridge local
ad7188507811 host host local
c9b78c272179 none null local
wty.igotoo.pw DNS 등록
구글 도메인에서 DNS에 wty.igotoo.pw 등록
CNAME으로 추가
항상 헤갈리는 CNAME 이란?
출처 : 인터넷의 주소록 DNS 서비스 ─ 기반기술에 대해서... | the Great World Meson


인터넷 주소의 해석; 구매하는 도메인은 domain name. top-level domain 이 조합된 주소를 구매한다.
- 하나의 domain name(ex : igotoo.pw) 으로 여러가지 서비스(ex : plexmediaserver, nextcloud, webtty 등) 를 제공할 경우 subdomain으로 분리 이때 subdomain 명을 CNAME 이라고 함
- A record(Public IP 매핑와 domain name)와 1:1 매핑 되며 IP로 매핑 하면 안됨
A Canonical Name record (abbreviated as CNAME record) is a type of resource record in the Domain Name System (DNS) which maps one domain name to another, referred to as the Canonical Name.
This can prove convenient when running multiple services (like an FTP server and a webserver; each running on different ports) from a single IP address. One can, for example, pointftp.example.com
andwww.example.com
to the DNS entry forexample.com
, which in turn has an A record which points to the IP address. Then, if the IP address ever changes, one only has to record the change in one place within the network: in the DNS A record forexample.com
.
CNAME records must always point to another domain name, never directly to an IP address.
출처 : CNAME record - Wikipedia
컨테이너 실행
docker-compose up -d
- chrome 브라우저로 접속 결과
- Host 접근하기를 원했는데 webtty를 설치하면서 생성된 컨테이너에 접근하는 게 됬었음. 이거슨 Docker의 개념을 모르는 무식한 짓이었음 Doker 컨테이너는 Host와 분리된 독립된 환경인데 이 컨테이너에 접속해서 호스트를 제어하겠다고 했으니 ....
- 기존 proxy-ssl 도커 서비스를 이용해서 아니 좀더 심플하게 도커 컨테이너 nginx 컨네이너 proxy를 활용 할 수 있는 방법이 없을까? nginx 설정에 호스트 웹서버를 reverse proxy 할 수 있도록 해주면 될 거 같음
- 컨테이너에서 host를 ssh로 연결이 더 쉬운 방법 참고한 사이트에서도 이방법을 사용했는데 건성으로 보아서 미처 모르고 있었음
Docker 이미지 및 컨테이너 재 생성
Dockerfile 수정
User 변경 : term --> igotoo
기본 linux 명령어 실행을 위해 busybox 설치
Host ssh 접속을 위한 Host의 bori user id_rsa 복사/권한(600) 설정
FROM node:0.10.38
MAINTAINER igotoo@gmail.com
ADD . /app
WORKDIR /app
RUN npm install
RUN apt-get update
RUN apt-get install -y vim
RUN apt-get install -y busybox
RUN useradd -d /home/igotoo -m -s /bin/bash igotoo
RUN echo 'igotoo:xxxx' | chpasswd
RUN mkdir /home/igotoo/.ssh
COPY id_rsa /home/igotoo/.ssh/id_rsa
RUN chmod 600 /home/igotoo/.ssh/id_rsa && chown -Rf igotoo /home/igotoo/.ssh
EXPOSE 3000
ENTRYPOINT ["node"]
CMD ["app.js", "-p", "3000"]
이미지 생성
docker build -t test2/wetyy .
문제 및 해결
문제 : COPY 오류
원인 : Host 경로(/home/bori/.ssh/id_rsa)로 설정 해주어서 파일 not found 에러 발생
The<src>
path must be inside the context of the build; you cannotCOPY ../something /something
, because the first step of adocker build
is to send the context directory (and subdirectories) to the docker daemon.
해결 : id_rsa를 docker pjt context 내부 즉 docker-compose 실행 디렉토리(/media/usbhdd1/wetty)에 복사 후 경로 설정 없이 id_rsa 컨테이너로 복사
문제 : ssh 접속 불가
- 원인 : host user bori private key를 컨테이너에 복사 해주었으나 정작 호스트 접속시 public key 등록 안된것으로 판단 오류 발생
- 해결 : host authorized_key에 bori's public key 복사.
- ssh 오류 발생 매번 헤갈림 접속 클라이언트 비밀키(id_rsa)를 가지고 있어야 하며 서버는 클라이언트 공개키(id_rsa.pub)를 서버 authorized_keys 에 저장하고 있어야 하며 권한은 600 이어야 함
chrome 브라우저 접속결과 : 성공 !!!