Ubuntu 환경에서 Docker 설치를 조금은 색다르게 해보고자 한다.

 

여러 편한 방법이 있겠지만, 직접 버전을 선택해서 패키지 파일을 내려 받아 설치하는 것이다.

특정 버전을 직접 관리하면서 사용할 수 있다는 장점이 있다.

 

 

1. Ubuntu 버전 확인

  - 지금 사용하고 있는 버전이 어떤 것인지 확인을 해보자.

 

❯ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

 

 

2. Docker 패키지 파일 확인

  - 어떤 버전이 있는지, 그리고 다운로드 주소가 어떻게 되는지 확인 해보자.

    . https://download.docker.com/linux/ubuntu/dists/

 

 

  - 우리가 확인해야할 패키지는 다음의 3 종류이다.

    . containerd

    . docker-ce-cli

    . docker-ce

 

 

3. 패키지 다운로드 및 설치

  - 이제 내려받아서 설치하자.

 

❯ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/containerd.io_1.6.21-1_amd64.deb
❯ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce-cli_23.0.6-1~ubuntu.20.04~focal_amd64.deb
❯ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce_23.0.6-1~ubuntu.20.04~focal_amd64.deb

❯ sudo dpkg --install ./containerd.io_1.6.21-1_amd64.deb
❯ sudo dpkg --install ./docker-ce-cli_23.0.6-1~ubuntu.20.04~focal_amd64.deb
❯ sudo dpkg --install ./docker-ce_23.0.6-1~ubuntu.20.04~focal_amd64.deb

 

 

4. 실행 권한 설정

  - root가 아닌 현재 사용자 계정에서 docker를 사용하기 위해 그룹 설정을 해주자.

 

❯ sudo usermod -aG docker $USER

 

  - 설정한 다음, 재부팅 또는 로그 오프 후 재로그인을 해줘야 한다.

  - 그리고 잘 되는지 확인해보자.

 

❯ docker --version

Docker version 23.0.6, build ef23cbc

 

 

5. 실습을 위한 파일 작성

  - docker build 실습을 위한 파일 2개를 다음과 같이 준비하자.

 

❯ nano index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Kubernetes</title>
</head>
<body>
  <h2>Hello, This is K8s World</h2>
</body>
</html>

 

❯ nano Dockerfile

FROM nginx:latest

COPY ./index.html /usr/share/nginx/html/index.html

 

 

6. docker build

  - 이미지 생성해보자.

  - 마지막에 . 찍어주는 것 잊지 말자 ^^

 

❯ docker build -t webserver .

DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
            Install the buildx component to build images with BuildKit:
            https://docs.docker.com/go/buildx/

Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM nginx:latest
latest: Pulling from library/nginx
9e3ea8720c6d: Pull complete 
bf36b6466679: Pull complete 
15a97cf85bb8: Pull complete 
9c2d6be5a61d: Pull complete 
6b7e4a5c7c7a: Pull complete 
8db4caa19df8: Pull complete 
Digest: sha256:480868e8c8c797794257e2abd88d0f9a8809b2fe956cbfbc05dcc0bca1f7cd43
Status: Downloaded newer image for nginx:latest
 ---> 448a08f1d2f9
Step 2/2 : COPY ./index.html /usr/share/nginx/html/index.html
 ---> 32317f8e7b5c
Successfully built 32317f8e7b5c
Successfully tagged webserver:latest

 

  - 응?! DEPRECATED ?! BuildKit을 사용해야 한단다.

 

 

7. BuildKit 설치

  - docker 패키지 살펴볼 때 눈치 빠르신 분은 이미 찾았을 것이다.

 

 

❯ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-buildx-plugin_0.10.4-1~ubuntu.20.04~focal_amd64.deb

❯ sudo dpkg --install ./docker-buildx-plugin_0.10.4-1~ubuntu.20.04~focal_amd64.deb

 

 

 

8 docker buildx build

  - 이제 새롭게 빌드해보자. 명령어는 크게 다르지 않다.

 

❯ docker buildx build -t webserver2 .

[+] Building 0.4s (7/7) FINISHED                                                                                                                                
 => [internal] load build definition from Dockerfile                                                                                                       0.1s
 => => transferring dockerfile: 107B                                                                                                                            0.0s
 => [internal] load .dockerignore                                                                                                                                  0.1s
 => => transferring context: 2B                                                                                                                                    0.0s
 => [internal] load metadata for docker.io/library/nginx:latest                                                                                      0.0s
 => [internal] load build context                                                                                                                                   0.1s
 => => transferring context: 199B                                                                                                                                0.0s
 => [1/2] FROM docker.io/library/nginx:latest                                                                                                              0.2s
 => [2/2] COPY ./index.html /usr/share/nginx/html/index.html                                                                                     0.1s
 => exporting to image                                                                                                                                                 0.1s
 => => exporting layers                                                                                                                                                0.1s
 => => writing image sha256:3f0130968d1e78db17dc061d1363da5f49c8157a1a73ffb10d923d9d7af16af               0.0s
 => => naming to docker.io/library/webserver2 

 

여기까지~

 

 

간만에 docker build 해봤다가 명령어가 deprecated 되었다고 해서 깜짝 놀라 급히 정리해봤다 ^^

 

 

반응형

 

간단한 웹을 만들어야 하는데,

간단하게 데이터를 다뤄야 할 때 종종 언급이 되는 Redis에 대해서 살펴보려고 한다.

 

"Key-Value 형식의 in-memory 데이터베이스"

 

기존에 내가 알고 있는 Redis에 대한 정보인데

공식 홈페이지에서 다시 한 번 확인해봤다.

 

- https://redis.io/

 

redis.io

 

"The opensource, in-memory data store used by millions ..."

어?! 'database'라고 하지 않고 'data store'라고 설명을 하네?! 라고 느끼는 순간! 사이트 중간에 다시 설명을 해주고 있다.

 

"A vibrant, open source database"

 

뭐, 결국은 내가 알고 있던 "key-value 형식의 in-memory databse"가 맞기는 하지만

스스로는 "data store"라는 정체성을 더 소중히 여기는 것이 아닌가 싶다.

 

서론이 너무 길었는데,

Redis에 대해서 너무나 잘 설명해주고 있는 좋은 아티클 링크 공유하면서 서두를 마치고자 한다.

 

- 6편의 아티클로 Redis에 대해서 심도있게 다루고 있음

  . https://insanelysimple.tistory.com/343

 

- Redis에 대해 소개하면서 "Redis vs Memcached" 비교

  . https://kdhyo98.tistory.com/89

 

 

이제 본론으로 들어가봅시다~!!

 

 

[ Redis 맛보기 ]

 

0. Background

개인적인 취향일 수도 있겠지만,

S/W 개발을 위한 기본적인 환경은 Linux 기반이 좋다고 생각하기 때문에

이번 실습 역시 Linux 배포판 中 Ubuntu 운영체제에서 진행한다.

 

또한, 최근 유행하고 있는 MSA 기조에 맞춰서

Application의 구성은 Container를 기반으로 하며

가장 대중적인 Docker를 활용하도록 하겠다.

 

- 테스트 환경 (필자가 이하 내용을 진행한 환경)

  . Host OS : Windows 10 Pro 21H1

  . VM : VirtualBox v6.1.34 r150636 (Qt5.6.2)

  . Guest OS : Ubuntu 18.04.6 LTS

  . Docker version 20.10.17, build 100c701

 

역시 개인적인 취향이 듬뿍 들어 있는 방식이긴 한데,

Server를 운영할 때 패키지의 버전관리 측면과 더불어 폐쇄망에서의 제약으로 인해

패키지들을 설치 할 때 직접 다운로드 받아서 진행하는 것을 선호한다.

 

- Docker 설치

  . Ubuntu 16.04 / 18.04 : https://www.whatwant.com/entry/Docker-Install-Ubuntu-16041804-64bit-using-Download

  . Ubuntu 20.04 : https://www.whatwant.com/entry/Docker-Install-Ubuntu-Server-2004

 

 

위와 같이 환경을 제시하긴했지만,

Windows/macOS 환경에서도 docker를 사용하기 때문에 비슷하게 동작하지 않을까 한다.

 

 

1. Persistent Volume

Redis가 in-memory data-store 솔루션이지만,

안정적 운영을 위해 메모리에 있는 데이터를 디스크에 쓰는 2가지 옵션을 제공한다.

 

① RDB (Redis Database) : 지정된 시간 간격으로 스냅샷을 파일로 저장

② AOF (Append Only File) : 모든 작업을 기록, 서버가 시작할 때 이 기록을 읽어서 데이터 재구성

 

어떤 옵션을 사용하더라도 데이터 저장이 되는 곳이 필요하고

보다 수월한 백업 등의 작업을 위해 docker volume 공간을 따로 구성하도록 하겠다.

 

# 리스트 확인
$ docker volume ls

# 생성
$ docker volume create [name]

# 상세 조회
$ docker volume inspect [name]

volume

 

2. Redis Config

접근 가능한 IP를 지정하고, 인증을 위한 패스워드를 넣는 등의 환경 설정을 위한 config 파일을 작성해보자.

또한 config 파일은 host에서 관리할 수 있도록 하겠다.

 

# 어떤 네트위크 인터페이스로부터 연결할 수 있도록 할 것인지 관리 (여기에서는 Anywhere)
bind 0.0.0.0

# 사용 포트 관리
port 6379

# Master 노드의 기본 사용자(default user)의 비밀번호 설정
requirepass [사용하고자 하는 비밀번호]

# Redis 에서 사용할 수 있는 최대 메모리 용량. 지정하지 않으면 시스템 전체 용량
maxmemory 2gb

# maxmemory 에 설정된 용량을 초과했을때 삭제할 데이터 선정 방식
# - noeviction : 쓰기 동작에 대해 error 반환 (Default)
# - volatile-lru : expire 가 설정된 key 들중에서 LRU algorithm 에 의해서 선택된 key 제거
# - allkeys-lru : 모든 key 들 중 LRU algorithm에 의해서 선택된 key 제거
# - volatile-random : expire 가 설정된 key 들 중 임의의 key 제거
# - allkeys-random : 모든 key 들 중 임의의 key 제거
# - volatile-ttl : expire time(TTL)이 가장 적게 남은 key 제거 (minor TTL)
maxmemory-policy volatile-ttl

# DB 데이터를 주기적으로 파일로 백업하기 위한 설정입니다.
# Redis 가 재시작되면 이 백업을 통해 DB 를 복구합니다.

save 900 1      # 15분 안에 최소 1개 이상의 key 가 변경 되었을 때
save 300 10     # 5분 안에 최소 10개 이상의 key 가 변경 되었을 때
save 60 10000   # 60초 안에 최소 10000 개 이상의 key 가 변경 되었을 때

 

redis.conf

 

redis.conf

 

3. Redis Image

Redis의 공식 Image 중에서 사용하고자 하는 버전을 찾아보자

- https://hub.docker.com/_/redis?tab=tag

 

Redis Image

 

현재 시점에서는 v7.0.2 가 최신이다.

 

 

4. Run

이제 Redis를 실행시켜 보자.

 

$ docker run \
-d \
--restart=always \
--name=redis \
-p 6379:6379 \
-e TZ=Asia/Seoul \
-v /srv/workspace/redis/redis.conf:/etc/redis/redis.conf \
-v redis_data:/data \
redis:7.0.2 redis-server /etc/redis/redis.conf

 

docker run

 

잘 실행이 되었는지도 확인해 보자.

 

docker logs

 

 

5. Redis Client

Redis에서 실제 값을 입력 해보자.

Redis Client의 실행 명령어는 'redis-cli' 이다.

 

$ docker exec -it redis redis-cli

 

NO AUTH

 

어?! 키 값 저장이 안된다.

redis.conf 작성할 때 명시한 패스워드를 사용하지 않았기 때문이다.

 

패스워드를 넣어서 client를 실행하면 정상 동작 한다.

 

AUTH

 

키 값 저장 및 조회가 잘 되는 것을 볼 수 있다.

 

여기까지~

 

반응형

 

PostgreSQL을 시스템에 직접 붙어서 `psql`을 이용해서 다루는 것도 좋지만,

개인적으로 Web Interface를 통해서 database의 현황을 살펴보는 것을 좋아하기에

PostgreSQL을 설치하고 난 다음에 바로 찾아본 것이 바로 `pgAdmin4`이다.

 

깔끔한 설치를 위해 Docker로 한 번 설치해봤다.

 

 

0. PostgreSQL 설치

  - [PostgreSQL을 Docker로 설치하자](https://www.whatwant.com/entry/PostgreSQL-Docker)

 

 

1. pgAdmin4 설치

  - 그냥 바로 실행하자.

  - email 주소와 password는 각자 취향에 다라 지정해주면 된다.

 

❯ sudo docker run -p 5050:80 -e 'PGADMIN_DEFAULT_EMAIL=abc@email.com' \
                        -e 'PGADMIN_DEFAULT_PASSWORD=password' -d dpage/pgadmin4

Unable to find image 'dpage/pgadmin4:latest' locally
latest: Pulling from dpage/pgadmin4
59bf1c3509f3: Pull complete 
6e9ec7ad2b67: Pull complete 
a0e18fcb2977: Pull complete 
fd2b27e2842d: Pull complete 
51136bc64bc0: Pull complete 
f64eecb587f3: Pull complete 
9cb5237d6528: Pull complete 
facb2de54b7c: Pull complete 
2c30d334d2ee: Pull complete 
27b8ff406ea1: Pull complete 
b87dab9776e7: Pull complete 
3e9a234b4839: Pull complete 
160949aa8885: Pull complete 
02526e9b4604: Pull complete 
Digest: sha256:3a2f4533b0e33baa09260ce02d0912058881c55cef800b73219e19b0a9d75658
Status: Downloaded newer image for dpage/pgadmin4:latest
4fb11f1a591ed35244b6db9045b844cae781ca3b59c54006b172805567dd1326

 

 

2. Connect

  - http://127.0.0.1:5050/

  - 실행할 때 입력한 email 주소와 password를 이용해서 로그인 하면 된다.

 

 

 

3. Add New Server

  - PostgreSQL 서버를 등록해주자.

 

 

  - name 하나 지어주고,

 

 

  - Connection 정보를 입력해주자.

  - `localhost`, `127.0.0.1`로 지정하면 연결이 안된다. IP 적어주자.

  - `Username`과 `Password` 제대로 입력하고 Save 하면 된다.

 

 

  - 이제 짠~

 

 

 

일단 여기까지~

 

반응형

 

개발을 하는 중에 PostgreSQL을 개발PC에 설치할 필요가 생겼는데

그냥 설치하기에는 개발PC가 지저분해질까봐 Docker를 이용해서 설치하려고 한다.

 

[ 개발PC 환경 ]

  - 운영체제: Ubuntu 18.04.6 LTS

  - docker: Docker version 20.10.12, build e91ed57

 

 

사실 포스팅을 굳이 해야할까 싶을 정도로 너무 간단하게 설치가 된다.

 

 

1. Docker Volume 생성

  - 데이터를 조금이라도 안전하게 보관하기 위해서 별도 volume으로 관리하자.

  - 실제 저장 위치도 확인해 볼 수 있다.

 

❯ docker volume create postgres_data

postgres_data


❯ sudo ls -al /var/lib/docker/volumes/

합계 40
drwx-----x  4 root root  4096  3월 21 21:14 .
drwx--x--- 13 root root  4096  3월 21 20:12 ..
brw-------  1 root root  8, 1  3월 21 20:12 backingFsBlockDev
-rw-------  1 root root 32768  3월 21 21:14 metadata.db
drwx-----x  3 root root  4096  2월 13 03:22 portainer_data
drwx-----x  3 root root  4096  3월 21 21:14 postgres_data

 

 

2. run PostgreSQL

  - 실행은 한 줄이면 된다 ^^

  - password는 각자 취향에 맞게 작성하면 된다.

 

❯ docker run -d -p 5432:5432 --name postgres -e POSTGRES_PASSWORD=password \
                 -v postgres_data:/var/lib/postgresql/data postgres

Unable to find image 'postgres:latest' locally
latest: Pulling from library/postgres
ae13dd578326: Pull complete 
723e40c35aaf: Pull complete 
bf97ae6a09b4: Pull complete 
2c965b3c8cbd: Pull complete 
c3cefa46a015: Pull complete 
64a7315fc25c: Pull complete 
b9846b279f7d: Pull complete 
ed988fb8e7d9: Pull complete 
ed4bb4fd8bb5: Pull complete 
ead27f1733c8: Pull complete 
7d493bacd383: Pull complete 
0920535e8417: Pull complete 
db76d5bdbf2c: Pull complete 
Digest: sha256:d1db54eade17ebfaa6cfdca90c83f8cb0d54bcceb1270a0848e0b216d50c325c
Status: Downloaded newer image for postgres:latest
d0b1fa1bb2b1b580e96e1790b6f7bebfcfdc88c885c35e1af57d82379e5df7b7

 

 

3. psql

  - 이대로 끝내면 서운하니까 psql 까지만 접속해보자.

 

❯ docker exec -it postgres /bin/bash

root@d0b1fa1bb2b1:/# psql -U postgres

psql (14.2 (Debian 14.2-1.pgdg110+1))
Type "help" for help.

postgres=# 

 

 

 

여기까지~

반응형

 

# Portainer ?

  - `Docker 관리를 위한 GUI 도구`로 시작해서 지금은 K8s, Azure ACI에 대한 지원까지 확장되고 있다.

  - https://www.portainer.io/

 

 

# 설치 환경

  - Ubuntu 20.04, Docker 20.10.12

❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal

❯ docker --version
Docker version 20.10.12, build e91ed57

 

 

# Install Portainer with Docker on Linux

  - Reference: https://docs.portainer.io/v/ce-2.11/start/install/server/docker/linux

 

① create volume

  - portainer에서 사용할 volume을 생성하고 잘 생성되었는지 확인해보자

❯ docker volume create portainer_data
portainer_data

❯ docker volume ls
DRIVER    VOLUME NAME
local     portainer_data

 

② install portainer

  - docker를 이용해 portainer를 설치하고 결과까지 확인해보자

❯ docker run -d -p 8000:8000 -p 9443:9443 --name portainer \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v portainer_data:/data \
    portainer/portainer-ce:2.11.0
Unable to find image 'portainer/portainer-ce:2.11.0' locally
2.11.0: Pulling from portainer/portainer-ce
0ea73420e2bb: Pull complete 
c367f59be2e1: Pull complete 
b71b88d796e2: Pull complete 
Digest: sha256:4f126c5114b63e9d1bceb4b368944d14323329a9a0d4e7bb7eb53c9b7435d498
Status: Downloaded newer image for portainer/portainer-ce:2.11.0
92f2bb51b10e3eb9bb09dd7f1731abd8796a8e1611cd42ef1d30b472472d7e13

❯ docker ps
CONTAINER ID   IMAGE                           COMMAND        CREATED          STATUS          PORTS                                                                                            NAMES
92f2bb51b10e   portainer/portainer-ce:2.11.0   "/portainer"   39 seconds ago   Up 25 seconds   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp   portainer

 

③ login

   - `https://localhost:9443` 또는 `https://IP:9443` 주소를 통해 웹 접근 해보자

비공개

  - 인증서 문제로 위와 같은 화면이 나오는데, `고급` 버튼을 누르고 `192.168.100.100(안전하지 않음)` 클릭!

passwd

  - 그리고, 관리자 패스워드 설정을 진행하면 된다

Get Started

  - 다른 서버도 같이 관리할 수 있지만, 지금 우리는 local만 관리할 것이기 때문에 `Get Started`를 클릭하면 된다

Home

  - local 밖에 없으니 하나 밖에 보이지 않는 것이 당연하고, `local`을 클릭해보자

local

 

너무나 깔끔하고 좋다~

 

반응형

 

Docker 또는 Kubernetes 환경에서 Linux를 가지고는 많이 놀아봤지만

Windows를 띄워볼 생각을 해보지는 못했다.

 

Windows 환경에서 Linux를 container로 실행하는 것도 신기하게 여겨졌지만

Windows 자체를 container로 실행하는 것은 생각해보지도 못했다.

 

그러던 중 우연히 찾게된 github.com repository 하나!

 

https://github.com/hectorm/docker-qemu-win2000

 

https://github.com/hectorm/docker-qemu-win2000

 

그렇다! Windows2000을 container로 띄워준다 !!!

 

Windows 2000 on Docker

 

테스트 환경은 다음과 같다.

 

- Host OS

      : Windows 10 Professional

- VM S/W

      : VirtualBox

- Guest OS

      : Ubuntu 18.04 64bit

 

VirtualBox를 이용해서 Ubuntu 환경을 구축한 뒤, Docker 까지 설치했다.

 

Ubuntu in VirtualBox

 

KVM을 사용하기 위해서 VirtualBox 설정을 좀 봐줘야 한다.

 

CPU Core 값도 2 이상 주고,

`네스티드 VT-x/AMD-V 사용하기`를 선택해야 한다.

 

설정

 

제대로 되어 있으면 다음과 같이 확인되어야 한다.

 

vmx / svm

 

`cpu cores` 값도 2 이상이 잡혀 있는지 잘 보고,

`flasg`에 `vmx` 또는 `svm` 값이 보이는지도 잘 확인하자. (안보이면 안된다)

 

 

이걸로 준비 끝이다!

 

docker run --detach \
  --name qemu-win2000 \
  --device /dev/kvm \
  --publish 127.0.0.1:3389:3389/tcp \
  --publish 127.0.0.1:5900:5900/tcp \
  --publish 127.0.0.1:6080:6080/tcp \
  docker.io/hectormolinero/qemu-win2000:latest

 

publish 옵션을 보면 알겠지만,

그리고 README.md에도 잘 설명이 되어있듯이 4가지 방법으로 접근할 수 있다.

 

- RDP (3389/TCP)

      : any RDP client, login with Administrator / password.

- VNC (5900/TCP)

      : any VNC client, without credentials.

- noVNC (6080/TCP)

      : http://127.0.0.1:6080/vnc.html

- Shell

      : docker exec -it qemu-win2000 vmshell

 

 

제일 편한 방법은 `noVNC`

크롬으로 접속만 하면 된다.

 

http://127.0.0.1:6080/vnc.html

 

noVNC

 

noVNC

 

진짜다!

Win2K SP4 !!!

정말이다!

 

 

졸려서 여기까지~ ^^

 

반응형

VSCode를 웹으로 접근해서 사용할 수 있도록 해주는 code-server를 소개한 적이 있다.

- Web based Visual Studio Code (Online VSCode)

 

공식적으로 제공해주는 docker image가 있긴 하지만,

이번에는 Kubernetes에 올려서 사용하기 위한 나만의 docker image를 만들어보려고 한다.

 

0. 작업 환경

  - 이하 과정을 진행한 환경은 다음과 같다.

    . OS: Ubuntu 18.04 Desktop

    . Docker: Docker version 20.10.7, build f0df350

 

  - Docker 설치는 다음 포스팅을 참고하기 바란다.

    . Docker Install (Ubuntu Server 20.04 - 64bit) - using Download

  - 지금 포스팅을 작성하는 시점에서의 최신 버전은 다음과 같다.

    . containerd.io_1.4.8-1_amd64.deb

    . docker-ce-cli_20.10.7~3-0~ubuntu-focal_amd64.deb

    . docker-ce_20.10.7~3-0~ubuntu-focal_amd64.deb

 

 

1. Dockerfile & Scripts

  - 아래 내용은 다음 링크를 참조했다.

    . https://git.nofla.me/k8s-projects/codekube

  - 위 내용 중 필요한 부분만 뽑아내고 재구성을 한 내용을 전체 공유하면 아래와 같다.

 

    . Dockerfile

 

FROM ubuntu:20.04

RUN apt-get update && apt-get upgrade -y
RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y \
    wget \
    vim \
    curl \
    dumb-init \
    zsh \
    htop \
    locales \
    man \
    nano \
    git \
    procps \
    openssh-client \
    sudo \
    jq \
    openssl \
    bash-completion \
    dnsutils \
    lsb-release

RUN apt-get install -y python3 python3-pip python3-dev build-essential

RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1
RUN update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

RUN apt-get install -y apt-utils locales
RUN locale-gen ko_KR.UTF-8
ENV LC_ALL ko_KR.UTF-8


RUN addgroup --gid 1000 code && \
    adduser --uid 1000 --ingroup code --home /home/code --shell /bin/bash --disabled-password --gecos "" code && \
    adduser code sudo
RUN chmod g+rw /home && \
    mkdir -p /home/code/workspace && \
    chown code:code /home/code/workspace -R


RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers;


RUN USER=code && \
    GROUP=code
RUN curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.5/fixuid-0.5-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \
    chown root:root /usr/local/bin/fixuid && \
    chmod 4755 /usr/local/bin/fixuid && \
    mkdir -p /etc/fixuid && \
    printf "user: $USER\ngroup: $GROUP\n" > /etc/fixuid/config.yml


RUN CODE_SERVER_VERSION=3.11.0 && \
    curl -sSOL https://github.com/cdr/code-server/releases/download/v${CODE_SERVER_VERSION}/code-server_${CODE_SERVER_VERSION}_amd64.deb && \
    sudo dpkg -i code-server_${CODE_SERVER_VERSION}_amd64.deb


RUN cat /usr/lib/code-server/lib/vscode/product.json \
    | jq '.extensionAllowedProposedApi[.extensionAllowedProposedApi | length] |= . + "ms-vsliveshare.vsliveshare" \
        | .extensionAllowedProposedApi[.extensionAllowedProposedApi | length] |= . + "ms-vscode.node-debug" \
        | .extensionAllowedProposedApi[.extensionAllowedProposedApi | length] |= . + "ms-vscode.node-debug2"' \
    > /usr/lib/code-server/lib/vscode/product.json_ \
    && mv /usr/lib/code-server/lib/vscode/product.json_ /usr/lib/code-server/lib/vscode/product.json


RUN mkdir /opt/default_home
ADD warehouse/.bashrc /opt/default_home


ENV PASSWORD=${PASSWORD:-password}
EXPOSE 8080

ADD warehouse/restart-codekube.sh /usr/local/bin/restart-codekube
ADD warehouse/code.sh /usr/local/bin/code
ADD warehouse/startup.sh /startup.sh


RUN chmod a+x /usr/local/bin/*

ENTRYPOINT ["/bin/bash", "/startup.sh"]

 

  - 필요한 스크립트 파일은 다음과 같다.

    . .bashrc

 

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

 

    . restart-codekube.sh

 

#!/bin/bash
kubectl get pods "$HOSTNAME" || (
    echo "Use kubens to switch to the namespace of this instance and try again!"
    echo "(we can't do this for you since we don't know the namespace name)"
    exit 1
)
kubectl delete pod "$HOSTNAME"

 

    . code.sh

 

#!/bin/bash
# Script that mimics the open-from-stdin functionality of VSCode
if [ "$1" == "-" ]; then
    TEMP=$(mktemp /tmp/stdin_XXXXXX)
    cat > "$TEMP"
    exec code-server -r "$TEMP"
    exit 0
fi;

# Pass through everything else to `code-server`
# Shellcheck SC2068 = quoting variables to prevent globbing - we want that here.
# shellcheck disable=SC2068
exec code-server $@

 

    . startup.sh

 

#!/bin/bash
[[ -f /home/code/.homedir-initialized ]] || (
    echo "Remove this file to re-copy files from /etc/skel /opt/default_home at next container startup" > /home/code/.homedir-initialized
    # dotglob to catch files like `.bashrc`
    shopt -s dotglob
    cp -r /etc/skel/* /home/code
    cp -r /opt/default_home/* /home/code
    shopt -u dotglob
    # install kubernetes ext
    #su code --login -c "/usr/bin/code-server --install-extension ms-kubernetes-tools.vscode-kubernetes-tools"
)
# make workspace dir if it doesn't exist
[[ -d /home/code/workspace ]] || mkdir /home/code/workspace
# chown stuff to kube:kube
chown code:code /home/code -R
# generate env whitelist from su using.. a blacklist, pretty much.
env_whitelist=$(env | cut -d = -f 1 | grep -v -e HOSTNAME -e PWD -e HOME -e TERM -e SHLVL -e LC_ALL -e ^_$ | tr "\n" "," | head -c -1)
# configure kubectl so vscode's kubernetes extension works
# su code --login -w "$env_whitelist" -c "/usr/local/bin/generate-kubeconfig.sh"
# start code-server
# su code --login -w "$env_whitelist" -c "/usr/bin/code-server --bind-addr 0.0.0.0:8080 /home/code/workspace" # --enable-proposed-api [\"ms-vsliveshare.vsliveshare\",\"ms-vscode.node-debug\",\"ms-vscode.node-debug2\"]
runuser code --login -w "$env_whitelist" -c "/usr/bin/code-server --bind-addr 0.0.0.0:8080 /home/code/workspace" # --enable-proposed-api [\"ms-vsliveshare.vsliveshare\",\"ms-vscode.node-debug\",\"ms-vscode.node-debug2\"]

 

 

2. 설명

  ① Ubuntu 20.04를 기준으로 했다.

    . 18.04도 가능할 것으로 보이지만, `startup.sh` 내용 中 마지막 라인에 있는

    . `su` 또는 `runuser`의 `-w` 옵션이 18.04에서는 적용되지 않아서 지금은 20.04로 했다.

    → 18.04에서도 적용 가능하도록 연구해보겠다 (언제가 될지는...^^)

 

  ② 개발환경으로 사용되기에 기본적인 패키지들을 설치했다.

    . 추후 필요에 따라 추가하면 된다.

    . `DEBIAN_FRONTEND="noninteractive"` 부분이 없으면 설치 중간에 사용자 입력을 기다리기도 한다. (설치 오류)

 

  ③ Python3 설치 (pip 포함)

    . 일단 python3 개발환경으로 맞췄다.

    . 다른 언어 또는 라이브러리가 필요하다고 하면 자유롭게~

 

  ④ 한글 환경 설정 (locale)

    . 이 부분이 없으면 한글 처리에 문제가 발생한다.

    . 참고: 한글 지원되는 Ubuntu Docker Image 만들기

  ⑤ 사용자 계정 만들기 (code)

    . `code`라는 사용자 계정을 생성해서 이를 기준으로 맞추고자 했다.

    . 패스워드 없이 sudo 사용할수 있도록 했다.

    . `fixuid`를 이용해서 `code` 계정의 uid를 전체적으로 맞추도록 했다.

 

  ⑥ code-server 설치

    . 현재 시점의 최신 버전 `3.11.0`이 설치하도록 했다.

 

  ⑦ (예정) LiveShare 적용 준비

    . 지금은 아니지만, 나중에 LiveShare Extension 사용하도록 하기 위해 집어넣은 부분이다.

    . 아직은 분석이 필요한 단계

 

  ⑧ default home 준비

    . `code` 계정을 생성하면서 `/home/code` 디렉토리가 만들어졌는데,

    . 사용 중에 `/home/code` 디렉토리가 사라지면

    . 이를 다시 생성할 때 필요한 `.bashrc` 파일 같은 것을 넣어놓기 위한 과정이다.

 

  ⑨ 패스워드 및 포트 설정

    . `code-server` 접근할 때 필요로 하는 password를 지정하는 부분이다.

    . 외부에 노출되는 포트는 `8080`으로 했다.

 

  ⑩ 스크립트 복사

    . 필요에 따라 만들어진 스크립트들을 복사해 넣는 부분이다.

 

  ⑪ 실행

    . 실행 명령어 지정

 

 

3. build Image

  - 이미지 만들기는 다음과 같다.

    . 당연히 알겠지만, `-f Dockerfile` 부분은 생략 가능하다. (다른 파일명을 사용하는 경우에만 필요)

 

$ docker build -t code-server:v0.1 -f Dockerfile .

 

 

4. run Docker

  - Docker로 실행해 볼 수 있다

 

$ docker run -it -p 8080:8080 --name code -e PASSWORD="0000" code-server:v0.1

 

다행히 잘 동작한다.

 

 

반응형

 

대! 한! 민! 국! 짜자자 짝!짝!

 

기본으로 제공되는 Ubuntu Docker Image는

우리에게 아름다운 한글을 제대로 지원해주지 않는다.

 

그래서 지금부터는 한글을 제대로 지원해주는 Ubuntu Docker Image를 만들어 보고자 한다.

 

 

0. 작업 환경

  - Ubuntu 18.04 Desktop

 

 

1. Docker 설치하기

  - 아래 링크를 참조하면 좋고~ 아니면 아래 과정을 주르륵 따라가도 좋다.

    . https://www.whatwant.com/entry/Docker-Install-Ubuntu-Server-2004

 

$ cd /srv/install
$ mkdir docker
$ cd docker

$ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/containerd.io_1.4.8-1_amd64.deb
$ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce-cli_20.10.7~3-0~ubuntu-focal_amd64.deb
$ wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce_20.10.7~3-0~ubuntu-focal_amd64.deb

$ sudo dpkg --install ./containerd.io_1.4.8-1_amd64.deb
$ sudo dpkg --install ./docker-ce-cli_20.10.7~3-0~ubuntu-focal_amd64.deb
$ sudo dpkg --install ./docker-ce_20.10.7~3-0~ubuntu-focal_amd64.deb

$ sudo usermod -aG docker $USER

로그아웃 후 로그인
(Ubuntu Desktop에서 로그아웃으로 안되어서 재시작해버렸음)

$ docker run hello-world

$ nano ~/.zshrc
plugins=(... docker docker-compose)

 

  - 마지막 부분은 개인적으로 zsh을 사용하고 있기에... 자동 완성 기능을 추가해보았다.

 

 

2. Ubuntu Docker Image - 기본

  - 개인 취향으로 기본 패키지들을 조금 더 추가하는 것으로 Dockerfile을 다음과 같이 만들어 봤다.

 

FROM ubuntu:18.04

RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y \
        nano \
        git \
        curl \
        htop \
        man \
        openssh-client \
        sudo \
        wget \
        procps \
        lsb-release

 

  - 위 내용을 `Dockerfile.default` 파일명으로 저장한 뒤 build 하고 run 해보자.

 

host$ docker build -t ubuntu:default -f Dockerfile.default .

host$ docker run -it ubuntu:default bash

 

  - 텍스트 파일을 하나 만들어서 한글을 입력해보자. (물론 제대로 출력이 안되는 것이 정상이다)

 

default$ cd

default$ nano noname.txt

 

 

3. Ubuntu Docker Image - 한글 지원

  - 이번에는 한글을 지원해줄 수 있는 Dockerfile을 작성해 보자.

 

FROM ubuntu:18.04

RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y \
        nano \
        git \
        curl \
        htop \
        man \
        openssh-client \
        sudo \
        wget \
        procps \
        lsb-release

RUN apt-get install -y apt-utils locales
RUN locale-gen ko_KR.UTF-8
ENV LC_ALL ko_KR.UTF-8

 

  - 아래 부분만 추가해서 `Dockerfile.ko_KR` 파일명으로 저장하고 진행해보자

 

host$ docker build -t ubuntu:ko_KR -f Dockerfile.ko_KR .

host$ docker run -it ubuntu:ko_KR bash

 

  - 똑같이 한글이 써지는지 테스트해보자.

 

ko_KR$ cd

ko_KR$ nano noname.txt

 

  - 이번에는 당연히 한글이 잘 써질 것이다!!!

 

 

Ubuntu 자체가 가벼운 이미지가 아니긴 하지만...

그래도 편한 맛에 사용한다고 하면 한글 지원이 필요할 때 참고하면 좋을 듯 하다.

반응형

'잘난놈되기' 카테고리의 다른 글

NFS Server 설치 (Ubuntu 18.04/20.04)  (3) 2021.09.21
kubectl 설치 (in Ubuntu)  (0) 2021.08.30
bpytop 설치 (Ubuntu 18.04)  (2) 2020.12.31
하드디스크 용량 분석 (SpaceSniffer)  (0) 2020.12.28
Docker Hub 활용  (0) 2020.11.14

+ Recent posts