728x90

 

이 글에서는 Emscripten을 사용하여 C 코드를 WebAssembly(WASM)로 변환하는 방법을 설명합니다.

1️⃣ Emscripten 설치

Emscripten을 설치하려면 다음 명령어를 사용하세요.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

2️⃣ C 코드 작성

아래는 간단한 C 코드 예제입니다.

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

3️⃣ WASM으로 컴파일

다음 명령어를 실행하여 C 코드를 WebAssembly로 변환하세요.

emcc example.c -o example.js -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -s MODULARIZE=1

4️⃣ HTML에서 실행

생성된 example.jsexample.wasm 파일을 웹에서 로드하여 실행할 수 있습니다.

<script src="example.js"></script>
<script>
    Module().then((module) => {
        console.log("2 + 3 =", module._add(2, 3));
    });
</script>

🎉 마무리

이제 C 코드를 WebAssembly로 변환하여 웹에서 사용할 수 있습니다!

728x90
728x90

웹서버가 설치된 리눅스 컨테이너(록키리눅스1)와 Nginx를 설치할 리눅스 컨테이너(록키리눅스2)가 각각임.
CPU 2코어, 램 2GB, 저장장치 20GB를 할당해서 생성.
웹서버(록키리눅스1)의 서비스 IP는 192.168.1.100:3000, Nginx서버(록키리눅스2)의 IP는 192.168.1.200

1. 리버스 프록시 설정이란?

리버스 프록시(reverse proxy)는 클라이언트의 요청을 받아 실제 서버로 요청을 전달하고, 그 결과를 클라이언트에 반환하는 역할을 하는 서버입니다. 이 방식은 보안, 로드 밸런싱, 캐싱 등 여러 가지 이점을 제공합니다.

2. Nginx를 사용한 리버스 프록시 설정

여기서는 Nginx를 사용하여 리버스 프록시를 설정하는 방법을 소개합니다. Nginx는 요청을 다른 서버로 전달하는 매우 효율적인 웹 서버로, 여러 웹 서버를 관리하는 데 유용합니다.

설정 파일 구조

server {
    listen 1010;  # 포트 1010에서 요청을 수신
    server_name 192.168.1.200;  # 서버의 IP 주소

    location / {
        proxy_pass http://192.168.1.100:3000;  # SvelteKit 서버 IP와 포트
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

이 설정에서는 `192.168.1.200`의 IP 주소로 들어오는 요청을 192.168.1.100:3000에서 구동되는 SvelteKit 애플리케이션으로 전달합니다.

3. 여러 웹 서버를 한 서버에서 구동하기

여러 개의 웹 서버를 같은 IP에서 구동하려면, 포트 번호만 다르게 설정하면 됩니다. 아래는 여러 포트에서 각각 다른 웹 서버를 구동하는 예시입니다.

여러 웹 서버 설정 예시

server {
    listen 1010;  # 포트 1010에서 요청을 수신
    server_name 192.168.1.200;  # 서버의 IP 주소

    location / {
        proxy_pass http://192.168.1.100:3000;  # SvelteKit 애플리케이션
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 1020;  # 포트 1020에서 요청을 수신
    server_name 192.168.1.200;

    location / {
        proxy_pass http://192.168.1.101:3000;  # 다른 애플리케이션
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

위 설정에서는 포트 1010에서 SvelteKit 애플리케이션을, 포트 1020에서 다른 애플리케이션을 처리하도록 설정합니다.

4. 설정 파일 분리 방법

각 웹 서버마다 개별 설정 파일을 생성하여 관리하는 것이 효율적입니다. Nginx에서는 conf.d 디렉토리나 include 지시어를 사용하여 여러 설정 파일을 분리할 수 있습니다.

개별 설정 파일 생성

각각의 웹 서버에 대해 별도의 설정 파일을 생성할 수 있습니다. 예를 들어:

/etc/nginx/conf.d/webserver_1.conf
/etc/nginx/conf.d/webserver_2.conf

설정 파일에 `include` 사용

`nginx.conf` 파일에 여러 개의 설정 파일을 포함시키는 방법:

include /etc/nginx/conf.d/*.conf;

이렇게 하면 여러 설정 파일을 각각 관리할 수 있습니다.

5. Nginx 설정 재시작

설정을 변경한 후에는 Nginx를 재시작해야 합니다. 아래 명령어로 설정 파일을 테스트하고 Nginx를 재시작할 수 있습니다:

sudo nginx -t  # 설정 파일 테스트
sudo systemctl restart nginx  # Nginx 재시작

이 포스트는 Nginx를 이용한 리버스 프록시 설정 방법과 여러 웹 서버를 동일한 IP에서 구동하는 방법에 대해 다루었습니다. 더 많은 정보를 원하시면 공식 Nginx 문서나 관련 자료를 참고하세요.

 

 이 방법을 사용하면 여러가지 이점이 있지만 그 중에서 하나의 도메인 네임에 여러개의 하부 도메인을 생성할 수 있는 기능이 있습니다.

main.com이란 도메인을 가지고 있다고 가정하면 blog.main.com, test.main.com, coding.main.com 등등 생성하여 각각의 서비스를 제공할 수 있습니다.

기본 Proxmox에서 이뤄지는 세팅이긴 하지만 여기에서 다루는 내용은 그냥 웹서버 설정이 주가 되기 때문에 Web카테고리로 설정합니다.

728x90
728x90

웹서버가 설치된 리눅스 컨테이너(록키리눅스1)와 Nginx를 설치할 리눅스 컨테이너(록키리눅스2)가 각각임.

CPU 2코어, 램 2GB, 저장장치 20GB를 할당해서 생성.

웹서버(록키리눅스1)의 서비스 IP는 192.168.1.100:3000, Nginx서버(록키리눅스2)의 IP는 192.168.1.200:80

1. Nginx 설치하기

록키리눅스에서 Nginx를 설치하는 방법을 설명합니다. Nginx는 고성능 웹 서버로 리버스 프록시, 로드 밸런서 등 다양한 기능을 제공하는 소프트웨어입니다.

1.1. EPEL 저장소 활성화

먼저, Nginx를 설치하려면 EPEL(Extra Packages for Enterprise Linux) 저장소를 활성화해야 합니다. EPEL은 RHEL 기반의 시스템에서 사용할 수 있는 추가 패키지를 제공합니다.

sudo dnf install epel-release

1.2. Nginx 설치

EPEL 저장소를 활성화한 후, Nginx를 설치합니다.

sudo dnf install nginx

1.3. Nginx 서비스 시작

설치가 완료되면 Nginx 서비스를 시작하고, 시스템 부팅 시 자동으로 시작되도록 설정합니다.

sudo systemctl start nginx
sudo systemctl enable nginx

1.4. 방화벽 설정

방화벽에서 HTTP(80)와 HTTPS(443) 포트를 열어줍니다.

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

2. Nginx 기본 설정 확인

설치 후, 웹 브라우저에서 서버의 IP 주소로 접속하여 Nginx의 기본 환영 페이지가 나타나는지 확인할 수 있습니다.

2.1. 웹 브라우저에서 확인

웹 브라우저를 열고, 서버의 IP 주소(예: http://192.168.1.200)로 접속합니다. Nginx의 기본 페이지가 보이면 설치가 정상적으로 완료된 것입니다.

3. Nginx 설정 파일 수정하기

이제 Nginx의 기본 설정을 수정하여 리버스 프록시를 설정하거나 다른 기능을 추가할 수 있습니다.

3.1. 설정 파일 열기

Nginx의 기본 설정 파일은 /etc/nginx/nginx.conf입니다. 이 파일을 수정하여 웹 서버의 동작을 변경할 수 있습니다.

sudo nano /etc/nginx/nginx.conf

3.2. 서버 블록 설정

여기서는 기본적인 리버스 프록시 설정을 예로 들겠습니다. 예를 들어, 포트 3000에서 구동 중인 SvelteKit 서버에 리버스 프록시를 설정하려면 다음과 같이 설정합니다.

server {
    listen 80;
    server_name 192.168.1.200;

    location / {
        proxy_pass http://192.168.1.100:3000;  # SvelteKit 서버
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

3.3. 설정 파일 재시작

설정을 변경한 후에는 Nginx를 재시작해야 합니다. 아래 명령어로 설정 파일을 테스트하고, Nginx를 재시작합니다.

sudo nginx -t  # 설정 파일 테스트
sudo systemctl restart nginx  # Nginx 재시작

4. Nginx 설정 파일 분리하기

여러 개의 웹 서버 설정을 관리할 때, 설정 파일을 개별적으로 분리하여 관리하는 것이 유리합니다. Nginx는 include 지시어를 사용하여 여러 설정 파일을 포함시킬 수 있습니다.

4.1. 설정 파일 나누기

Nginx 설정을 /etc/nginx/conf.d/ 디렉토리에 여러 개의 파일로 나누어 저장할 수 있습니다. 예를 들어, 웹 서버마다 webserver_1.conf, webserver_2.conf와 같이 설정 파일을 나누면 관리하기 더 쉽습니다.

4.2. `nginx.conf`에 `include` 사용

주 설정 파일인 nginx.conf에서 `include` 지시어를 사용하여 설정 파일들을 포함시킬 수 있습니다.

include /etc/nginx/conf.d/*.conf;

4.3. Nginx 재시작

설정을 변경한 후에는 아래 명령어로 Nginx를 재시작하여 적용합니다.

sudo nginx -t  # 설정 파일 테스트
sudo systemctl restart nginx  # Nginx 재시작

이 포스트는 록키리눅스에 Nginx를 설치하고, 기본적인 리버스 프록시 설정을 하는 방법을 설명했습니다. 추가적으로 설정을 더 하고 싶다면, Nginx 공식 문서나 다양한 튜토리얼을 참고하세요.

728x90
728x90

Podman 이미지 크기를 줄이는 방법

Podman에서 이미지 크기를 줄이는 방법은 Docker에서 이미지를 최적화하는 방법과 매우 유사합니다. Dockerfile을 최적화하여 더 작은 이미지를 만들 수 있는 주요 방법은 다음과 같습니다.

1. 멀티스테이지 빌드 사용

멀티스테이지 빌드는 빌드 과정에서 필요한 종속성만 포함된 작은 이미지를 생성할 수 있게 도와줍니다. 빌드 단계에서 필요하지 않은 파일이나 패키지는 최종 이미지에 포함되지 않기 때문에 크기를 크게 줄일 수 있습니다.

 
# 빌드 단계
FROM node:16 AS build
WORKDIR /app
COPY . .
RUN npm install

# 최종 이미지 단계
FROM node:16-slim
WORKDIR /app
COPY --from=build /app /app
RUN npm install --production
CMD ["node", "index.js"]
        

2. 불필요한 파일을 .dockerignore로 제외

.dockerignore 파일을 사용하여 빌드에 불필요한 파일을 제외하면 이미지 크기를 줄일 수 있습니다. 예를 들어, node_modules, 로그 파일, 테스트 코드 등을 .dockerignore에 추가하세요.


# .dockerignore 예시
node_modules/
*.log
*.md
test/
        

3. 최소화된 베이스 이미지 사용

가능한 경우 최소화된 이미지를 사용하세요. 예를 들어, alpine 이미지는 다른 배포판보다 훨씬 작은 이미지입니다. alpine을 사용할 때 필요한 라이브러리나 패키지들만 추가하면 이미지 크기를 크게 줄일 수 있습니다.


FROM python:3.9-alpine
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
        

4. 이미지 레이어 최소화

RUN 명령어를 여러 번 사용하면 각 명령어가 새로운 레이어를 생성하므로 이미지 크기가 커질 수 있습니다. 여러 명령어를 하나로 합쳐서 레이어 수를 줄여보세요.


# 비효율적인 예
RUN apt-get update
RUN apt-get install -y build-essential

# 최적화된 예
RUN apt-get update && apt-get install -y build-essential
        

5. 캐시를 사용한 최적화

캐시를 사용하여 이미지 빌드를 빠르게 만들 수 있지만, 때때로 캐시가 너무 많이 쌓여 이미지 크기가 커질 수 있습니다. 불필요한 캐시를 지우는 것도 중요합니다.


RUN apt-get update && \
    apt-get install -y build-essential && \
    apt-get clean
        

6. 작은 라이브러리 또는 프레임워크 사용

이미지에서 사용하는 라이브러리나 프레임워크가 불필요하게 크다면, 더 작은 대체품을 고려해보세요. 예를 들어, nginxnginx:alpine을 사용하는 것처럼, 가능한 경량화된 버전의 소프트웨어를 선택하는 것이 좋습니다.

결론

위의 방법들을 적용하면 Podman으로 생성되는 이미지의 크기를 줄이는 데 도움이 될 것입니다. Docker와 Podman은 이미지 빌드 방식에서 큰 차이가 없기 때문에, 이러한 최적화는 Podman에서도 동일하게 적용됩니다. 이미지를 최적화하여 더 빠르고 효율적인 컨테이너 환경을 구축해 보세요!

728x90
728x90

1.

뭔가를 하려다 블록체인을 접목시키면 좋지않을까 해서 그간 막연하게 생각해왔던 블록체인에 대해 이거저거 좀 알아봤다.

 

2.

이전에 알던 얕은 지식은 가상화폐나 NFT같은 것들이 전부였다.

가상화폐는 그렇다쳐도 사실상 사기나 다름없던 NFT를 봐오며 '이건 대체 왜 생겨난 거야?' 란 의문이 떠나지 않았다.

그리고 조금 더 깊지만, 역시나 얕게 파 본 결과 그냥 그게 맞다는 결론에 이르렀다.

 

3.

탈중앙화, 암호화, 수정안됨 등등이 이점이라고 가장 먼저 나온다.

수정못하는 것까진 확인을 안했는데 사실 앞의 두 개만 봐도 이미 이건 아니라는 답이 나왔다.

우선 탈중앙화, 얼핏보면 그런 것 같아 보인다. 하지만 사실상 기득권의 이동일 뿐 중앙화는 계속 존재한다.

'채굴자', 혹은 '검증자'라 불리는 자들에 의해 시스템이 돌아간다.

그리고 그러기 위해 발생하는 모든 컴퓨팅 자원의 소모를 '가스비'라는 명목으로 가져간다.

 

4.

대충 알고는 있었는데 각잡고 파다보니 이 부분이 굉장히 거슬렸다.

연산이 복잡할수록, 연산해야할 사항이 많을 수록 많은 가스비를 청구한다.

너무 추상적인거 같으니 현실의 예로 은행을 들면, 은행 업무를 볼 때 발생하는 수수료는 기본으로 있는데 여기에 은행원이 무슨 업무를 처리하느냐에 따라, 복잡도나 난이도에 따라 수수료를 더 받는 거나 마찬가지다.

 

5.

이쯤되면 이미 멀쩡히 잘 돌아가는 금융시스템을 이따위 뜬구름 잡는 헛것으로 대체하겠다고 일을 이렇게까지 크게 벌인 인간은 대체 무슨 생각으로 그랬을까 하는 생각이 들었다.

 

6.

우선 지금 당장은 몇몇 특수한 상황에서라면 유용할 것 같긴하다.

계약이나 보험이나 정책이나, 한 번 정하고나서 수정이 되면 안되는 부분이 있다면 비용을 좀 더 들여서라도 써볼만 할거 같긴하다.

하지만 일반적인 다른 모든 상황에선 쓸데없는 비용만 발생시키고 전력 낭비에 자연파괴만 일삼고 있는거다.

당장 은행만 봐도 실제 대체가 어찌어찌 된다 하더라도 은행이 받던 비용을 강력한 컴퓨팅 파워를 가진 채굴자나 검증자가 가져갈 것이고, 사용하기는 더 복잡해 질 것이다.

거기에 과연 중앙화의 대상이던 각국 정부나 은행이 채굴자나 검증자의 위치에서 벗어날 보장은 없고, 오히려 그들의 강력한 자본을 생각하면 이름만 바뀌는 결과가 나올거란 상상에서 벗어나기 힘들다.

아마 블록체인 기술을 이용한 가상화폐가 실생활에서 널리 쓰인다고 하면 그들이 이름만 바꿔서 활동할 상황이 모두 갖춰졌을 때가 아닐까 싶다.

 

7.

암호화는 한동안 시끌시끌 했고 점점 더 시끄러워질 양자컴퓨터 나오면 지금 시스템은 그냥 끝이다.

뭐 양자 대응 암호 만든다는데 그게 언제 나올지도 모를 일이고 만약 나왔다고 하면 결국 가스비만 올라갈 것 같다.

그리고 궁극적인 취약점이 있는데 우선 인터넷에 장애라도 생기면 그냥 끝이다.

이건 정말 너무 심각한 문제로 딱 사이버 세계에서만 통용된다는 한계를 명확히 보여준다.

 

8.

지금 보면 굉장히 화난 사람같이 보일 것이다.

왜냐하면 화가 무척 났기 때문이다.

아, 짜증난다.

728x90
728x90

1. PostgreSQL의 알림 시스템 설정

PostgreSQL에서는 LISTENNOTIFY 명령어를 사용하여 데이터베이스의 변경 사항을 애플리케이션에 실시간으로 전달할 수 있습니다. 먼저 PostgreSQL에서 알림을 보낼 수 있도록 트리거를 설정합니다.

    -- 데이터 변경 후 알림을 보내는 함수 생성
    CREATE OR REPLACE FUNCTION notify_cache_update() RETURNS trigger AS $$
    BEGIN
      -- pg_notify를 사용해 알림을 보냄
      PERFORM pg_notify('cache_update_channel', NEW.id::TEXT);
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;

    -- 트리거 생성: 데이터베이스 업데이트 시 알림을 보냄
    CREATE TRIGGER trigger_cache_update
    AFTER INSERT OR UPDATE ON your_table
    FOR EACH ROW EXECUTE FUNCTION notify_cache_update();
  

위의 SQL 코드는 your_table에 데이터가 삽입되거나 수정될 때마다 pg_notify를 사용하여 'cache_update_channel' 채널로 알림을 보냅니다.

2. Node.js에서 PostgreSQL 알림 받기

Node.js 서버에서 pg 라이브러리를 사용하여 PostgreSQL의 알림을 수신하고 처리할 수 있습니다. 아래 코드는 PostgreSQL에서 알림을 수신하는 예시입니다.

    const { Client } = require('pg');

    // PostgreSQL 연결 설정
    const client = new Client({
      user: 'your_user',
      host: 'localhost',
      database: 'your_db',
      password: 'your_password',
      port: 5432,
    });

    client.connect();

    // 알림 채널을 리스닝
    client.query('LISTEN cache_update_channel');

    // 알림 받기
    client.on('notification', (msg) => {
      console.log('Received notification:', msg);
      // 알림을 받으면 캐시 갱신 등의 처리를 할 수 있습니다.
    });

    // 에러 처리
    client.on('error', (err) => {
      console.error('Error in PostgreSQL client:', err);
    });
  

이 코드에서 LISTEN 명령어로 'cache_update_channel' 채널에서 발생한 알림을 기다리고, notification 이벤트가 발생하면 알림을 처리합니다.

3. WebSocket 서버 구현

알림을 실시간으로 클라이언트에 전달하기 위해 Node.js에서 WebSocket 서버를 설정합니다. WebSocket은 클라이언트와 서버 간의 실시간 통신을 가능하게 해줍니다.

    const WebSocket = require('ws');

    // WebSocket 서버 설정
    const wss = new WebSocket.Server({ port: 8080 });

    wss.on('connection', (ws) => {
      console.log('A client connected');
      
      // PostgreSQL에서 알림을 받을 준비
      client.query('LISTEN cache_update_channel');
      
      client.on('notification', (msg) => {
        console.log('Received notification:', msg);
        ws.send(msg.payload);  // WebSocket 클라이언트로 알림 전송
      });
    });

    console.log('WebSocket server is running on ws://localhost:8080');
  

위 코드에서 WebSocket 서버를 설정하고, 클라이언트가 연결되면 PostgreSQL 알림을 받아 해당 알림을 클라이언트에 실시간으로 전달합니다.

4. SvelteKit에서 WebSocket 연결

SvelteKit에서는 클라이언트에서 WebSocket을 통해 실시간으로 서버와 통신할 수 있습니다. 아래 코드는 SvelteKit 클라이언트에서 WebSocket을 연결하고 알림을 수신하는 예시입니다.


      import { onMount } from 'svelte';

      let data: string;

      onMount(() => {
        const ws = new WebSocket('ws://localhost:8080'); // WebSocket 서버 연결

        ws.onopen = () => {
          console.log('WebSocket connected');
        };

        ws.onmessage = (event) => {
          console.log('Received message:', event.data);
          data = event.data; // 알림 데이터를 UI에 반영
        };

        ws.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
      });
     <main>
       <h1>Real-time Notifications</h1>
       <p>{data}</p> <!-- 실시간 알림 데이터 표시 -->
     </main>

위 SvelteKit 코드는 WebSocket 서버에 연결하고, 알림을 받을 때마다 페이지에 표시합니다.

결론

PostgreSQL의 pg_notify를 사용하여 데이터베이스에서 실시간으로 알림을 보내고, 이를 Node.js 서버에서 WebSocket을 통해 SvelteKit 클라이언트에 전달하는 방법을 살펴보았습니다. 이 방식은 데이터베이스의 변경 사항을 실시간으로 클라이언트에게 반영할 수 있어, 사용자 경험을 향상시키는 데 유용합니다.

728x90

+ Recent posts