이전의 글에서 파이에 우분투를 설치하는 걸 진행했다.

이번에는 Docker를 이용해서 기존의 Tomcat을 운영해보려고 한다.

기존 Pi에서의 환경
구성할 Docker 환경

기존에는 Tomcat 9을 그대로 이용한 웹 서버였지만, 이제는 Docker를 이용해서 간편하게 컨테이너화 시키고자 한다.

컨테이너화의 장점으로는 형상관리의 편리함 뿐만 아니라 문제 발생시 빠른 대처가 가능하다. 또한 개별 컨테이너로 분리가 되어있기에, 다른 서비스까지 영향을 주지 않는다는 부분이다.

 

또한 여기서 Nginx가 추가되었는데, 이건 Reverse Proxy와 Multi Domain을 이용한 서비스 분리를 위한 부분이다.

전체적인 웹 구성을 아래의 그림과 동일하다.

출처 : ibmimedia


1. Docker Network 생성

 

docker create network 명령어로 새로운 브릿지를 만든다.

이후 컨테이너는 이 네트워크 브릿지를 사용해서 서로간의 통신하게 될 것이다.

docker create network -d web-network

 

 

2. Nginx Container 생성

--net으로 앞에서 만든 web-network 브릿지에 연결하고, 이후 컨테이너간의 dns 요청을 위한 --net-alias도 지정해준다.

-p 옵션으로 80번과 443번을 호스트(pi)와 연결해준다.

이후 pi ip의 모든 http 요청은 이 nginx 컨테이너가 담당하게 될 것이다.

-v 옵션은 호스트와 컨테이너간의 공유영역으로, /home/pi/docker/nginx/html 폴더의 내용물은 컨테이너가 /usr/share/nginx/html에서 접근가능하다.

docker run -d --name nginx \
-p 80:80 -p 443:443 \
--net web-network \
--net-alias nginx \
-v /home/pi/docker/nginx/html:/usr/share/nginx/html \
nginx

 

 

3. MariaDB Container 생성

 

포트 옵션은 하지 않아도 되지만, 외부와 연결하게 될 일이 있을 수도 있을거 같아서 미리 열어둔다.

docker run -d --name db \
-t 13306:3306 \
--net web-network \
--net-alias web-db \
mariadb

 

 

4. Tomcat Container 생성

 

여기서 포트 옵션은 하지 않아도 되지만, 디버깅을 목적으로 열어두었다.

container의 이미지가 ubuntu로 되어있는데,

이건 필자가 tomcat 이미지로 계속 시도를 해봤지만, 제대로 실행되지를 않아서 그냥 ubuntu로 이미지를 변경했다.

docker run -d --name tomcat \
-p 8080:8080 \
--net web-network \
--net-alias tomcat \
ubuntu

 

5. 컨테이너 간 연결 확인

 

docker exec -it tomcat bash

tomcat 컨테이너를 터미널과 연결한 후에 telnet으로 연결을 테스트 해본다.

기본적으로 깔려있지 않을테니 apt update && apt install telnet으로 명령어를 넣어주어야 한다.

 

telnet db 3306

성공 케이스

아래처럼 접속되었다는 말이 뜨면 잘 진행된 것이다.

만약 아래와 같이 결과가 나온다면, 브릿지 설정은 제대로 되었는지, 별칭 지정이 다르진 않은지 체크해보길 바란다.

실패 케이스

 

 

6. WAS 설정

 

tomcat에서는 db를 연결하도록 설정파일을 변경해주고, nginx에서는 리버스 프록시와 ssl 설정을 변경해준다.

리버스 프록시와 ssl 설정에 대한 자세한 내용은 추후에 글을 올릴 생각이다.

 

 

7. 실제 테스트

 

 

https://mon0mon.duckdns.org/ 으로 접속 했을 때는 Nginx의 기본 html이 뜬다.

 

https://lovedata.duckdns.org/ 으로 접속 했을 때는 tomcat의 웹화면이 뜨는 걸 확인할 수 있다.

 


위와 같이 구성한 이유는 매번 웹 사이트를 개발할 때마다 다른 ip의 서버를 새롭게 구성해야하는데,

매번 그렇게 할 수 없을 뿐더러, 관리가 쉽지가 않을 거 같아서 고민하다 이 방안을 생각하게 되었다.

 

사용자가 느끼기에는 개별의 서비스이지만, 운영하는 입장에서는 실질적으로 단일 환경인 셈이다.

더군다나 다른 서비스에 영향을 미치지 않는다는 점에서 더욱 마음에 든다.

이전에는 웹서버가 아닌 다른 것들 때문에 모든 서비스가 먹통이 되었던 것때문에 제법 고생한 적이 있었는데, 

이제는 그럴 일이 없을 것이다.

 

글 작성으로 봤을 때는 엄청 단순해 보이지만, 막상 해보니까 만만치 않았다.

도커 자체의 어려움보다는 tomcat을 실행하고, 이후에 제대로 작동하지 않는 것 때문에 3일 정도를 계속 허비했다.

 

그래도 막상 만들고 나니 뿌듯하기도 하고, 도커를 배우고 있는 입장에서 책을 읽고 예제만 따라하는 것보다

조금더 잘 이해하게된 거 같다.

 


P.S. 

위의 그림을 정정하기위해 내용을 추가

OMV는 구동에 실제 물리적 환경이 필요하므로, docker에서는 구동이 안된다고 함...

따라서 OMV를 구동하고 싶다면, OMV image를 이용해서 설치를 하거나 패키지 형태로 설치하는 것을 권장함

 

OMV포럼

'Pi' 카테고리의 다른 글

[PI] 라즈베리 파이 4 Ubuntu 설치  (0) 2022.08.15

필자는 라즈베리 파이4로 구현한 웹 서버가 있다.

라즈비안 os를 설치하고 그 위에 db, tomcat을 설치하여 실행하는 식으로 구성했었다.

 

파이 구성도

 

웹서버만 사용하는 것이 아닌, OpenMediaVault도 설치해보고 여러가지 많이 하게되다 보니,

점점 느려지기도 하고 한번 오류가 나면 다른 서비스를 전부 이용하지 못하게 되는 문제가 생겼다.

 

그러다가 얼마전 웹서버가 제대로 돌아가지 않고, 기존에 등록했던 ssl 인증서도 만료된다는 메일이 날아왔다.

그래서 여러가지 설정은 건드려보고, 프로그램도 지우던 도중에 돌이킬 수 없는 문제가 발생하는데,

OpenMediaVault를 지우자, 파이에서 재실행을 해도 터미널에 접속이 되질 않았다.

 

결국 직접 모니터를 연결해서 상태를 확인해보니

No Wireless interface Found라는 메시지가 뜨고, 와이파이 연결이 되질 않았다.

해당 문제는 OpenMediaVault에서 시스템의 설정을 건드리는데, 삭제하는 과정에서 이게 제대로 해결되지 않은 거라고 생각이 들었다. (stackoverflow)

 

어차피 지금도 문제가 있는 데, 이참에 한번 싹 갈아버리는게 나을거 같다는 생각이 들어서,

기존의 웹서버 파일, db, ssl 인증서만 백업한 채 완전히 포맷해버렸다.

 


 

1. 우분투 이미지 다운로드

 

우분투 홈페이지에 들어가보면 Download 탭에 Ubuntu for IoT 항목이 있는데, 여기에 라즈베리 파이 다운로드가 있다.

여길 눌러주자

 

이동을 하고 나면, 여러가지 버전이 있을 텐데, 나는 나중에 라즈베리 파이로 원격접속을 할 수 도 있다고 생각해서 Desktop 버전을 다운로드 하였다.

다운로드가 완료되면 아래처럼 img.xz 파일이 생기게 된다.

 

 

 

2. 이미지를 sd 카드에 옮기기 위한 PI Imager 설치

 

RasberryPi OS로 구글에 검색하면 홈페이지가 나오게되는데, 여기서 PI Imager를 다운로드 할 수 있다.

다운로드를 눌러서, 설치를 진행해주자

 

 

 

3. 이미지 굽기

 

설치된 Imager를 실행하면 다음과 같은 화면이 나오는데, 여기서 운영체제 OS 선택 -> 사용자 정의 사용을 눌러서 우리가 다운로드 한 Ubuntu img.xz 파일로 지정해주자.

이후 저장소 선택에서는 연결된 sd 카드로 경로를 지정해준 이후에 쓰기 작업을 진행하면 된다.

쓰기 작업시 기존에 데이터는 전부 지워질 수 있으니 만약을 대비해서 Win32DiskImager 등을 이용해서 백업을 진행해주는 걸 권장한다.

 

 

4. 라즈베리 파이에 설치

 

쓰기 작업이 완료된 이후에 sd 카드를 라즈베리 파이에 꼽고 설치를 진행하면 된다.

'Pi' 카테고리의 다른 글

[PI] Docker를 이용한 WebServer 구성  (0) 2022.08.15

파이썬에서는 배열을 선언할 때 여러가지 방법들이 있다.

 

list_1 = []
list_2 = [] * 5
list_3 = [] for _ in range(5)

등등 여러가지가 있는데, 그중에서도 오늘은 for 문과 * 연산자를 이용한 배열 선언의 차이에 대해서 적어보고자 한다.

 

2차원 배열을 선언할 때는 3가지 방법을 쓸 수 있다.

 

 

첫 번째로 빈 리스트 생성 후 append로 더하기이다.

# 아예 빈 리스트를 생성 후 append로 더하기

list_1 = []
list_1.append([0, 0, 0])

print(list_1)

# [[0, 0, 0]]

다만 이 방법은 추후 코드를 통해서 append 해야하기 때문에, 실질적으로 append 하기 전까진 1차원 배열이라고 할 수 있다.

따라서 다음과 같은 코드를 실행하는 데 문제가 발생한다.

# Index Error 발생

list_1 = []

# IndexError: list index out of range
print(list_1[0][1])

list_1.append([0, 0, 0])

따라서 위와 같은 문제를 해결하기 위해 2가지 방법을 더 생각해 볼 수 있다.

 

 

두 번째로 * 연산자를 이용한 선언이다.

# * 연산자를 이용한 선언

list_1 = [[0] * 3] * 5

print(list_1[0][1])

list_1.append([1, 1, 1])

# 0

 

 

세 번째로는 for문을 이용한 선언이다.

# for문을 이용한 선언

list_1 = [[0 for col in range(3)] for row in range(5)]

print(list_1[0][1])

list_1.append([1, 1, 1])

# 0

 

두 번째와 세 번째를 모두 실행해보면 같은 결과를 출력하는 걸 볼 수 있다.

그렇기에 둘 다 같은 거라는 생각이 들 수 있다.

하지만 둘은 엄연히 다르다.

 

 

이걸 설명하기 위해서는 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)에 대해서 알아야한다.

우선 깊은 복사는 변수나 객체가 가지고 있는 값을 그대로 복사하여, 다른 변수나 객체가 동일한 값을 가지게 하는 것이고,

얕은 복사는 변수나 객체를 참조하는 것이다.

 

즉 깊은 복사는 원본 객체와 복사된 객체는 별개의 객체이지만, 얕은 복사는 복사된 객체가 원본 객체를 참조하기 때문에 둘간의 연결성이 있다.

 

# 세로 길이가 3, 가로 길이가 2인 행렬이 있다고 했을 때,
# 이를 2차원 배열로 바꾸는 2가지 방법의 차이점

# 얕은 복사
list_1 = [[False] * 2] * 3
# 깊은 복사
list_2 = [[False for col in range(2)] for row in range(3)]

print(list_1)
print(list_2)
# [[False, False], [False, False], [False, False]]
# [[False, False], [False, False], [False, False]]

list_1[0][0] = True
list_2[1][1] = True

print(list_1)
print(list_2)
# [[True, False], [True, False], [True, False]]
# [[False, False], [False, True], [False, False]]

위와 같이 list_1은 [False] * 2로 각각의 요소들을 얕은 복사를 했기에,

[0][0]뿐만 아니라 [1][0], [2][0]까지도 값이 변경된 것을 확인 할 수 있다.

 

반대로 list_2는 for문을 통한 깊은 복사를 했기에,

[1][1] 요소만 변경되고, 나머지 요소에는 영향을 주지 않은 것을 볼 수 있다.

 

 

간혹 함수에 매개변수 값을 전달할 때 자주 나오는 pass by reference, pass by value도 이와 비슷한 맥락이라 볼 수 있다.

둘이 완전히 동일하진 않지만, 값을 전달 할 것인가, 참조할 것인가의 차이인 점에서는 같다.

 

 

 

파이썬에 익숙하지 않다보니, 얕은 복사인지도 모르고 쓰다가 수십 분을 허비한 경험으로 글을 쓰게 되었다.

다들 쉽다고 하는데, 왜 나는 이렇게 파이썬이 어려운지 잘 모르겠다

차근차근 시간을 두고 익혀봐야겠다.

'Language > Python' 카테고리의 다른 글

[Python] List Slicing  (0) 2022.08.09
# Created by ARA on 2022-08-09.

# 이것이 코딩테스트다
# Ch05-DFS/BFS-꼭 필요한 자료구조 기초

stack = []

# 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제()
stack.append(5)
stack.append(2)
stack.append(3)
stack.append(7)
stack.pop()
stack.append(4)
stack.pop()

print(stack)
print(stack[::-1])

# Expected Output
# [5, 2, 3]
# [3, 2, 5]

코딩테스트 책을 보는데, 18번 줄에서의 stack[::-1]이 무엇을 의미하는지 이해가 안됐다.

그래서 인터넷을 찾아보고 알아본 걸 정리해본다.

 

일단 우선 python [] 연산자에 대해서 찾아봤다.

c++ 에서 검색했던 것과는 다르게 별 다른 내용이 나오질 않았다.

 

어쩌다보니 slicing이라는 키워드를 찾게 되었는데, 거기에 해당하는 내용이 있었다.

(막상 정식 문서 가서 찾아보려니 위와 같은 예제는 찾질 못하겠다... 혹시라도 나중에 찾게 되면 추가하겠다.)

 

이 사이트에서 문법을 설명하는데, 내가 알고 있는 것과 동일했다.

다만 뒤에 Step이 있는 지 몰랐다.

자세히 읽어보니 다음 요소(element)를 선택할 때 기준을 말하는 거 같았다.

 

# Return every 2nd item between position 2 to 7
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
print(L[2:7:2])
# Prints ['c', 'e', 'g']

예제 코드를 해석해 봤을 때, L 리스트에 있는 요소 중에서 2번 인덱스 부터 7번 미만 인덱스 까지 2의 간격으로 요소를 출력하라고 해석해볼 수 있다.

그림으로 표현하면 다음과 같다

'Language > Python' 카테고리의 다른 글

[Python] 2차원 배열을 선언할 때 주의할 점  (0) 2022.08.10

 

https://forthebadge.com/

 

For the Badge

About For the Badge is a Grassroots Movement Scientific Endeavor Humanitarian Society Literary Masterpiece Knitting Club Complete Joke. We don’t develop for the money, power, fame, or codebabes. We do it For the Badge. It all started because of an obsess

forthebadge.com

 

해당 사이트에서 무료로 이미지 제공

이런 느낌?

'Tips' 카테고리의 다른 글

클립보드에 있는 파일 저장하기  (0) 2023.03.31

우선 간단하게 Binary Log에 대해서 알아보고 가자

Binary Log는 MariaDB가 CREATE, ALTER, DROP, INSERT, UPDATE, DELETE 등의 데이터를 수정하는 쿼리를 실행할 때마다 발생한다.

일반적으로 데이터에 수정이 발생하지 않는 SELECT나 SHOW는 로깅되지 않지만, 옵션을 설정한다면 같이 로깅할 수 있다. (다만 성능에 악영향을 줄 수 있다.)

자세한 내용은 MariaDB 문서를 참고하면 될 거 같다.

 

일단 Binary Log를 생성하기 위해서는 환경설정을 해야하는데, 저번에 작성한 설치 및 환경설정 글에 백업을 위한 로깅부분에서 설명해두었으니, 해당 글을 참고하면 될 거 같다.

 

우선 테스트를 위해 간단하게 binlog_test 스키마와 user_info 테이블을 만들었다.

-- 스키마 생성
CREATE DATABASE binlog_test;
USE binlog_test;

-- 테이블 생성
CREATE TABLE user_info (
	id int not null auto_increment primary key,
    name varchar(20) not null,
    reg_date timestamp default '0000-00-00 00:00:00',
    update_date timestamp not null on update current_timestamp
);

-- 데이터 삽입
INSERT INTO user_info(name) VALUES('mon0mon');

-- 데이터 변경
UPDATE user_info SET name='mon0mon_mod' WHERE name='mon0mon';

 

이제 데이터를 넣고, 조회해본다.

 

이후 update로 데이터를 변경해본다.

 

 

마지막으로 데이터를 완전히 지워본다.

 

 

이후에 자신이 설정해둔 binlog 파일 저장 경로로 이동해준다.

 

설정을 제대로 해두었다면, mysql-bin.# 형식으로 파일들이 생성된 것을 볼 수 있다.

이제 이 파일을 cat으로 확인해보자

뭔가 출력이 되긴 했는데, 여기저기 글자가 제대로 인코딩되지 않아서 깨지는게 보인다.

이 상태로는 로그를 읽을 수 없으므로 mysqlbinlog을 이용해서 sql 파일로 변환이 필요하다.

 

mysqlbinlog --no-defaults {로그} > {저장위치 및 형식}

 

mysqlbinlog로 바로 실행 할 때 mysqlbinlog: unknown variable 'default-character-set=utf8mb4' 에러가 발생한다.

이는 예전 mysql에 존재하던 default-character-set 이란 환경변수가 현재는 없기 때문인데, 이를 해결하기 위해서 가장 간단한 방법인 --no-default로 옵션파일을 제외하고 실행하면 정상적으로 작동한다.

자세한 내용은 정식문서이 글을 참고하길 바란다.

 

생성된 sql 파일을 vscode로 열어봤다.

아까 생성한 binlog_test 스키마와 유저 생성 테이블이 있는 것을 볼 수 있다.

 

좀더 자세한 내용은 이 링크를 참고하면 좋을거 같다.

 

'DB > MariaDB' 카테고리의 다른 글

리눅스 MariaDB 설치 및 환경설정  (0) 2022.08.04

ls 명령어를 치면 아래와 같이 투박하게 텍스트로만 나온다.

이미지에서는 ohmyzsh에서 파일과 디렉토리를 색으로 구분해주어서 괜찮지만,

cli 환경이 익숙하지 않은 상태에서는 아이콘이 있는 편이 훨씬 직관적일 것이다.

일반 리눅스 ls 명령어
colorls를 이용한 디렉토리 뷰

 

 

이러한 ls 명령어를 좀더 보기 편하고 예쁘게 만들어주는 colorls라는 프로그램이 있다.

colorls 리포에서 설치를 참고해서 진행해보자.

 

우선 루비를 설치해야한다.

되도록 2.6 버전 이상을 권장한다.

여기서 ruby-dev를 제외하면, ruby gem으로 colorls를 설치하는 과정에서 에러가 발생할 수 있으니,

같이 설치해주자.

sudo apt update
sudo apt install ruby ruby-dev

 

 

루비를 설치하고, 아래 명령어를 이용해서 colorls를 설치한다.

sudo gem install colorls

 

 

설치가 완료된 이후에는 colorls의 경로를 복사해서, ~/.zshrc에 추가 해주면 된다.

# colorls 경로 복사
sudo gem which colorls
# ~/.zshrc
# zsh에서 colorls 자동완성
source {colorls 경로}/tab_complete.sh
# colorls를 ls로 별칭지정
alias ls='colorls'

 

이제 명령어에서 colorls가 자동완성 되는 것을 볼 수 있다.

여기다 필자는 colorls를 ls 대신 사용할 예정이라 ls로 별칭을 지정했다.

 

 

옵션도 여러가지가 있는데

-a는 기존의 ls -a와 동일하고, -A는 현재 디렉토리(.)과 상위 디렉토리(..)을 제외한다.

-d는 디렉토리만 출력하고, -f는 파일만 출력한다.

-1 옵션으로 가로가 아닌 수직 정렬도 가능하다.

--tree 옵션은 트리 형식으로 보여주는데 =[깊이]를 붙여주면 얼마나 깊이까지 보여줄 지 정할 수 있다.

옵션을 주지 않으면 자식노드 끝까지 보여준다.

 

'OS > Linux' 카테고리의 다른 글

[터미널] Oh My Zsh 설치  (0) 2022.08.06
WSL 설치  (0) 2022.08.06

리눅스를 처음 사용할 때 단순하게 검은 바탕에 흰색 글자만 나열되어 있는 것이 너무 지루해보였다.

그래서 이곳저곳 찾아보니 터미널도 엄청나게 다양하게 커스텀해서 쓸 수 있다는 걸 알게되었다.

보기만 좋을 뿐 아니라 여러가지 부가기능이 있는 경우도 있어서 생산성도 나름 도움이 된다고 생각이 들었다.

 

그래서 이번 글에는 보기도 좋고, 자동완성 및 여러가지 인디케이터들로 편하게 만드는 ohmyzsh와

디렉토리와 파일리스트를 컬러와 아이콘으로 출력하게 하는 colorls를 설치해보려고 한다.

 

Oh My Zsh

 

우선 먼저 zsh를 설치해야한다.

 

sudo apt update
sudo apt install zsh

 

 

zsh를 설치했으면 이 글을 참고해서 마저 진행해준다.

wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
sh install.sh

 

 

테마는 기본을 사용해도 좋지만, 더 이쁜 걸 찾고 싶다면 이 사이트를 참고해서 하나를 정해준다.

필자는 powerlevel10k를 설치하기로 했다.

 

powerlevel10k 예시 이미지

 

powerlevel10k 리포에서 Installation-Oh My Zsh 섹션을 참고해서 설치를 진행한다.

가장 먼저 진행할 것은 powerlevel10k가 폰트를 설치하는 것이다.

꼭 하지 않아도 되지만, 위 이미지처럼 아이콘이나 기타 여러가지 요소들을 쓰고 싶다면 설치하는 것이 좋다.

 

폰트도 종류가 여러가지가 있는데, 그 중에서 MesloLGS NF 폰트를 사용하기로 했다.

 

wsl 기준으로는 Windows Terminal - 설정 - Json 파일 열기 이후에

profiles - list 속에서 내가 설치한 리눅스 이미지를 찾아야한다.

 

 

 

이제 이 가운데 아래 글을 복사해서 넣어준다.

 

"font": 
                {
                    "face": "MesloLGS NF"
                }

 

 

이제 터미널을 실행하면 폰트가 정상적으로 바뀐것을 확인할 수 있다.

 

폰트 설치가 완료된 이후에는 powerlevel10k의 깃을 클론해서 저장한다.

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

이제 ~/.zshrc를 vim으로 열어서 zsh 테마를 바꾸어주면 된다.

ZSH_THEME="powerlevel10k/powerlevel10k"

 

 

그 다음 p10k configure 를 입력해서 설정을 진행하면 된다.

 

설치를 전부 진행한 후의 터미널 모습이다.

여기서 추가적으로 원하면 더 커스텀도 가능하므로, powerlevel10k 리포를 참고하면 될거 같다.

'OS > Linux' 카테고리의 다른 글

[유틸리티] ls 명령어를 화려하게 Colorls  (0) 2022.08.06
WSL 설치  (0) 2022.08.06

+ Recent posts