반응형

Docker Compose 사용 에러

Docker compose Error

docker compose를 통해 docker hub에 올라가 있는 리액트 빌드 이미지를 다운받고 해당 이미지를 실행시켜주는 명령어를 구성하였다.

docker-compose.yml

version: '3.6'

services:
  my_app:
    image: myHubName/my_app:ver1.0.0
    container_name: my_app
    restart: always
    ports:
      - 80:80
    environment:
      TZ: Asia/Seoul

서버의 환경이 mac mini로 구성되어 있었는데,
docker-compose up명령어를 통해 실행 후 아래와 같은 오류를 만났다.

security -v unlock-keychain ~/Library/Keychains/login.keychain-db  
unlock-keychain "/Users/dawin-server/Library/Keychains/login.keychain-db"  
password to unlock /Users/dawin-server/Library/Keychains/login.keychain-db:  
security: SecKeychainUnlock /Users/dawin-server/Library/Keychains/login.keychain-db: The user name or passphrase you entered is not correct.

Mac 환경 서버 Security에러 해결

서버에서 보안관련 설정을 직접해줘도 되지만, ssh를 통해 작업을 하고 있었기때문에, 아래와 같이 허용 명령어를 입력하고 계정 비밀번호를 한번 더 입력해서 해결하였다.

security -v unlock-keychain ~/Library/Keychains/login.keychain-db

반응형
반응형

Docker Platform 오류

🚫 오류 현상

새로운 네이버 클라우드 서버 환경에 리액트 어플리케이션을 임시로 구성해야 하는 상황이 발생했다.
리액트 배포 관리도 도커 허브를 통해 관리를 하고 있었기때문에, 몇가지 설정값만 바꾸고 빌드하여 서버쪽에서 허브를 통해 PULL처리 후 run을 해보니 아래와 같은 오류를 만났다.

WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested

개발 PC의 경우 맥북 m1과 네이버클라우드 서버의 CPU 아키텍처 달라서 발생한 오류였다.

✅ 오류 해결

도커 허브에 이미지를 올리기전에 CPU 아키텍처를 맞춰서 빌드하여 올려주면 해결이 된다.
(멀티플랫폼을 적용하는 방식도 있다고 하는데, 이 방법은 차차 확인해보고 적용방법을 포스팅해보겠다.)

🔹 빌드 옵션에 platform키워드 사용하기

빌드 옵션에서 --platform 아키텍처를 통해 이미지를 재업로드를 진행했다.

// 예시의 경우 오류 메시지 아키텍처로 맞췄습니다.
// docker build --platform linux/amd64 -t [DockerHubName/Repository/TagName] --push .
docker build --platform linux/amd64 -t myHub/reactPrj/ver1.0.0 --push .

정상적으로 동작이되면 이미지를 생성해서 도커허브로 바로 올라가는걸 볼 수 있다.

🟢 동작 결과

서버로 다시 돌아와서 생성한 이미지를 다운받고 실행시키면 정상적으로 동작하는걸 볼 수 있다.

반응형
반응형

.env파일을 통해 환경이나 특정 상황에 따라 변경될 환경 변수값 정의하고 자주 사용하는데, 뒤에 붙는 확장자에 따라서 개발용과 배포용으로 나눠서 사용할수가 있다.

환경변수 사용하기

Vite에서는 약간 사용법이 다른데, cra같은 경우 아래와 같은 명명 규칙을 지키면서 사용한다.
REACT_APP_변수명=값

사용법 예시(환경변수처리)

REACT_APP_BASE_URL=http://localhost:8080.com
REACT_APP_TEST=TEST

사용법 예시(가져오기)

{process.env.REACT_APP_변수명}

환경에 따른 환경변수 적용

.env.local, .env.development, .env.production, .env.test등 개발환경이나거 배포환경에 따라 구분하여 사용할 수 있다.

🎲 .env.local

로컬 개발시 사용한다. test환경 외 모든 환경에서 로딩된다.

🎲 .env.development(Start)

개발 환경에서 사용되며, 아래 명령어로 실행시 동작한다.

$ npm run start
$ yarn start

아래 순서로 동작된다. env.development.local파일이 가장 우선순위가 높다.

.env.development.local > .env.development > .env.local > .env

🎲 .env.production(Build)

서버 배포시 사용되며, 아래 명령어로 실행시 동작한다.

$ npm run build
$ yarn build

아래 순서로 동작된다. env.production.local파일이 가장 우선순위가 높다.

.env.production.local > .env.production > .env.local > .env

🎲 .env.test(Test)

테스트 환경시 사용되며, 아래 명령어로 실행시 동작한다.

$ npm run test
$ yarn test

아래 순서로 동작된다. env.test.local파일이 가장 우선순위가 높다.

.env.test.local > .env.test > .env.local > .env

👀 실행 결과

반응형
반응형

🐳 Docker

Docker는 컨테이너화된 어플리케이션을 개발하고 배포, 실행시키는 오픈 소스 플랫폼이다.
Docker의 실행 동작은 격리된 환경에서 어플리케이션을 패키징하고 실행하는 기능을 제공하는데, 서버의 OS에 영향을 받지 않고 도커 내부의 별도의 환경에서 구동되기에 Docker를 사용하게 되면 어떤 인프라 환경에서 분리되어 빠르게 배포하고 구동시킬 수 있게된다.

📝 Docker Architecture

Docker는 서버-클라이언트 아키텍처를 사용하는데, Docker Client는 컨테이너를 구축, 실행 및 배포하는 무거운 작업을 수행하는 Docker Daemon과 통신한다. 도커 클라이언트와 데몬은 동일한 시스템에서 구동될수도 있고 원격으로 연결될 수도 있으며 소켓 또는 Rest API를 통해 통신한다. Docker Compose로 어플리케이션을 구성하여 컨테이너를 작업할 수도 있다.

🖊️ Docker Daemon

도커 데몬은 Docker API요청을 수신하고 이미지, 컨테이너, 네트워크와 같은 도커 객체를 관리한다.

🖊️ Docker Client

도커 명령을 보내는 사용자들로 docker run과 같은 명령을 보내면 dockerd가 수행한다. docker명령은 Docker API를 사용하며 도커 클라이언트는 2개 이상의 데몬과 통신할수 있다.

🖥️ Docker Desktop

Mac, Windows, Linux환경에서 컨테이너화된 어플리케이션을 구축하고 공유할 수 있도록 도와주는 GUI어플리케이션으로 Docker Daemon, Docker Compose, Kubernetes등이 포함되어 있다.

🛠️ Docker Object

Docker를 사용하게 되면 컨테이너, 이미지, 네트워크, 볼륨, 플러그인 등의 객체들을 사용하게 되는데, 해당 객체들에 대한 내용을 확인해본다.

📦 Container

실행 가능한 이미지 인스턴스를 말하며, 어플리케이션을 실행하거나 생성, 중지, 이동 등을 할 수 있다.
도커 컨테이너는 자체 파일 시스템과 환경을 가지고 있으며 다른 컨테이너로부터 독립적인 환경으로 동작하는데, 각각의 어플리케이션이 서로에게 영향을 주지 않고 독립적으로 실행할 수 있다.

🏞️ Image

도커 이미지는 도커 컨테이너를 생성하기 위한 읽기 전용 템플릿이다. 한마디로 생성하고자 하는 어플리케이션을 뜻한다. Apache Tomcat이 될 수도 있고 Java Nginx 등등 어플리케이션을 이미지로 생성하고 사용할 수 있는데, 자신만의 이미지도 생성이 가능해서 사용하고자 하는 어플리케이션의 설정을 미리 처리해둔 상태로 이미지를 생성해서 사용할 수도 있다.
예를 들면, 기본 Tomcat의 기본포트를 처음부터 80으로 세팅해두어서 매번 배포시마다 굳이 포트부분의 설정을 바꿀필요가 없어진다.
이런 경우에는 Dockerfile을 통해 이미지를 빌드하고 생성할 수 있다.


참고 url: https://docs.docker.com/get-started/overview/

반응형
반응형

이번에 개발이 완료된 제품들을 윈도우 OS인 서버에 도커를 통해 처리하였다.
문제없이 셋업은 되었지만 혹시 모를 상황으로 서버가 재기동되면 알아서 컨테이너가 구동되도록 설정하고 싶어졌다.

🐳 서버 재기동시 도커 컨테이너 자동 시작처리하기

⭐️ docker-compose를 사용하는 경우

restart: always옵션을 도커 컴포즈에 추가한다.

docker-compose.yml

version: "3"

services:
  product_name:
    image: 제품명
    container_name: 컨테이너명
    ports:
      - 8080:8080
    volumes:
      - ./logs:/code/logs
    environment:
      TZ: Asia/Seoul
    depends_on:
      - maria_db
    command:
      - "sh"
      - "-c"
      - >
        python server/init/init_data.py &
        gunicorn -c /code/server/app/config/gunicorn_config.py server.app.main:app
    restart: always

  maria_db:
    image: mariadb
    container_name: maria_db
    ports:
      - 3306:3306
    volumes:
      - ./mariadb/conf.d:/etc/mysql/conf.d
      - ./mariadb/data:/var/lib/mysql
      - ./mariadb/initdb.d:/docker-entrypoint-initdb.d
    env_file: mariadb/.env
    environment:
      TZ: Asia/Seoul
    restart: always

⭐️ 명령어를 통한 설정

이미 컨테이너 설정이 끝나고 사용중이라면 아래 명령어를 통해 처리가 가능하다.

C:\Users\cloud> docker update --restart=always 컨테이너ID값

컨테이너 ID값은 Docker Desktop이 있다면 해당 프로그램을 실행시키고 컨테이너의 각 ID값을 가져오거나 아래 명령을 통해서도 확인이 가능하다.

C:\Users\cloud> docker ps -a

반응형
반응형

먼저 알아야 할 개념

웹 프론트개발을 시작했다면 먼저 알아야할 지식과 개념들을 먼저 정리한다.

😶‍🌫️CRA(create-react-app)

프론트엔드를 시작해보겠다고 Get Start문서부터 많은 동영상 강의와 책을 보면 항상 cra를 통해 React프로젝트를 작성한다.
cra없이 React프로젝트를 구성하려면 꽤나 많은 의존 모듈 설치와 설정이 필요하기에 너무나도 용이하게 npx create-react-app my-app 한 줄로 설치하면 프로젝트를 작성을 시작할 수 있었다.

🤔모듈 시스템

갑자기 모듈 시스템?... 그래도 알아보자
자바나 C#, C++같은 언어들은 import와 같은 구문을 통해 모듈 시스템을 구축하지만 과거 자바스크립트에는 모듈 시스템이라는 개념이 없었다.
script태그로 필요한 javascript 파일을 작성하거나 연결하고, 그러다보니 컨텍스트가 섞이거나 전역변수가 남발하고 더욱 레거시한 환경으로 넘어가면 let, const도 없으니 var로만 구성된곳에선 변수가 다른 값으로 대입되게 되고... 많은 문제가 있었다.
이런 문제를 해결하고자 처음 나온 개념이 CommonJS의 require, module.export문법이다.
현대의 브라우저는 ESM(ES Modules)덕에 네이티브 모듈 시스템이 생겼다.

  • ESM: import, export와 같은 ES6 표준 모듈 시스템을 말한다.

🔥번들러

이런 문제를 해결하기 위해 Bundler라는 개념이 나오기 시작한다. 기존에는 script형태로 넣다보니 모든 것들을 다 가져오게 되면서 용량문제도 발생하고, 여러 개의 파일이 아닌 한개의 JS파일이 만들어지기 때문에 모듈의 순서와 언제 불러와야 할 지에 대한 순서 문제도 있었는데, 번들러덕에 이런 것들이 해소되기 시작한다.
번들러 개념이 잘 없는 개발자들도 종종 들어본 번들러가 있다. 바로 Webpack으로 cra에도 도입된 번들러이기도 하다.
Webpack덕분에 위에서 발생하던 문제들은 해결되었지만, 속도의 문제가 있었다. JS파일을 하나로 만들어주기 위해 코드 수정이 이루어질때마다 새롭게 빌드를 하게되고 규모가 커질수록 파일이 많아지게되니 시간이 오래걸리면 대기시간이 길어지는 개발자들의 피로도가 엄청나게 늘어났다.

🍬ES Build의 등장

이번엔 ES Build이다.
기존 번들러(Webpack)의 문제를 해결하기 위해 나왔다. 대략 100배 이상 빠르다고 한다.
JS를 기반으로 작성된 번들러와 달리 Go라는 언어로 작성되어 빠른 빌드가 가능하게 되었다.
다만 WebpackHMR외에도 code splitting과 같은 기능을 종합적으로 제공했기에 복잡한 앱에서 ES Build가 대체할 수는 없었다.

⚡이제는 Vite를 씁시다!

Vite(바이트가 아니다 빗!!! 이다.) 페이지만 들어가도 빠르다라는 키워드를 자주 접할 수 있다.
현대의 브라우저는ESM(ES Modules)가 추가되었고, 위에서 언급한 ES Build를 활용하여 Webpack을 대체한다.
기존의 번들러는 소스 코드가 변경되면 전체적으로 번들링 과정을 다시 거쳐야하다 보니 서비스가 거대해질수록 빌드시간이 늘어나게 된다.
ViteHMR방식을 지원하는데, 여기서 포인트는 ESM을 활용하여 수정해야 할 부분만 소스 코드만 반영할 수 있게 처리했다.

  • HMR: 앱을 종료하지 않고 갱신된 파일만 교체하는 방식

dependenciessource code로 구분하고 개발시 내용이 바뀌지 않는 부분들은 ES Build로 번들링하고 수정하는 부분만 ESM으로 소스 코드를 반영한다. ESM은 요청받은 모듈만 전달하기 때문에 훨씬 빠르게 서버에 반영이 된다.

  • dependencies: 개발시 내용이 바뀌지 않을 JS코드로 기존에는 매우 비효율적인 시간으로 번들링이 이루어졌지만 Vite는 ESBuild를 통해 10~100배 가까이 빠른 속도를 제공한다.
  • source code: JSX, CSS와 같이 컴파일링이 필요하고 수정이 잦은 부분들을 말한다. Vite는 브라우저가 요청하는 대로 소스 코드를 변환하고 제공한다.

⚙️Vite으로 React 프로젝트 구성하기

  1. npm create vite@latest 빗을 생성한다.
  2. 프로젝트 명을 작성하라고 나온다.(원하는 프로젝트 이름을 입력)
  3. 프로젝트 명을 입력하면 원하는 개발 프레임워크를 물어본다. 원하는 개발로 선택한다.
  4. 다음은 타입스크립트로 개발할 것인지 SWC를 도입할 것인지 물어본다.
  5. 프로젝트 위치로 이동한다. cd 프로젝트명
  6. 바로 플젝 시작하면 오류가 난다!!!. npm i를 입력하고 기본 라이브러리 의존 설치를 진행한다.
  7. npm run dev입력하고 프로젝트를 열어본다! 개발 시작!!!
  • SWC: Rust라는 언어로 제작된 빌드 툴로, JS프로젝트의 컴파일, 번들링을 제공하는 웹 컴파일러 툴이다.
반응형
반응형

ESLint, Prettier 설정하기

🔹ESLint

ESLint는 코딩 컨벤션에 위배되는 코드를 작성하거나 잘 못된 코드를 검출해주는 도구다.
해당 도구를 연결하는 것만으로 잘못된 코드 습관을 고치는데 크게 도움이 된다.
쓸데없이 import나 선언해두고 사용하지 않는 변수를 잡아주는 것은 시작에 불과하다.
미리 잘못된 코드들을 잡아주다보니 추후 버그가 나올 가능성이 현저히 줄어드게 된다.(그렇다고 만능은 아니지만 많은 부분에서 크게 도움이 된다. ts와 ESLint의 조합이란....)

🔹Prettier

Prettier는 코드 포맷터이다. 다양한 언어와 도구에서 지원이 되는데, 일관된 코드를 작성할 수 있게 도와주어 코드를 짜는데 있어서 가독성을 높여준다.
특히 협업을 할때, 누구는 2개의 탭을 넣고 누구는 4개의 탭을 넣게되어 쓸데없는 깃의 꼬이는 현상도 막아주고 일관된 코드를 작성해준다.
코드 스타일의 규칙을 초반에 정해놓고 설정만 해두면 prettier가 전담해서 코드를 일관성 있게 작성해주니 이후부터 코드 작성 스타일에 대한 스트레스와 시간을 절약해주는 좋은 도구이다.

🔹VSCode에서 사용법

VSCode에서 플러그인 설치 후 설정을 통해 연결할 수 있다.
ESLint를 검색하고 설치하면 된다.

Prettier도 마찬가지로 검색하면 바로 나오므로 설치해서 사용하면 된다.

🔹프로젝트별 ESLint설정법

프로젝트 최상단에 .eslintrc.cjs 또는 .eslintrc.json형태로 파일을 생성한다.
아래는 vite에서 react개발을 하면서 사용한 옵션들이다.

.eslintrc.cjs

module.exports = {
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:react-hooks/recommended',
  ],
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  settings: { react: { version: '18.2' } },
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': 'warn',
  },
};

옵션별 설명

  • env: 코드가 실행되는 개발 환경을 말한다. 브라우저, node서버, 등 목적에 맞게 작성한다. 환경의 설정값을 통해 eslint가 api와 전역변수들을 이해하고 분석해준다.
  • extends: 공개된 설정들을 그대로 가져와서 해당 프로젝트에 적용하는 옵션(airbnb, goggle, facebook등 대기업에서 배포한 기술도 적용 할 수 있다.)
    • react/recommened: React프로젝트에 맞는 권장하는 규칙과 설정을 제공한다.(JSX, React 권장 패턴, 관행 등)
    • react-hooks: React Hook(useState, useEffect, useCallback등)관련된 권장 규칙과 설정을 제공
    • jsx-runtime: jsx의 관련된 규칙이 작성되어 있다.작성 형식, 태그닫기, 명명규칙 등을 도와주고 가독성을 높여준다.
  • plugins: 기본적으로 제공하는 규칙 외에 추가적으로 적용할 규칙에 사용할 플러그인을 작성
  • rules: extends옵션에서 설정된 규칙 외에 덮어쓰고 싶은 규칙을 작성할 때 사용되며, 규칙에 대한 내용을 세세하게 작성하기 위해 사용하는 옵션
  • parserOptions: javascript코드를 이해하기 위해 Eslint에서 사용하는 파서를 구성한다. ECMAScript버전(ecmaVersion), sourceType: 소스유형
  • ignore: eslint의 설정을 무시할 파일이나 디렉토리를 설정할 수 있다.

자세한 설정에 대한 내용은 아래 URL을 참고하자.
[https://eslint.org/docs/latest/use/configure/]

🔹프로젝트별 Prettier설정법

프로젝트별로 협업하는 사람들마다 스타일의 형태가 다양하다. 나만의 방식을 추구하고 싶겠지만, 협업이다보니 다수의 의견을 따라야 하는 경우가 있다. 이런 경우 나만의 VSCode에 설정한 Prettier가 아닌 프로젝트 최상단에 .prettierrc를 추가하고 옵션을 설정하면 된다.

아래는 .prettierrc 예시이다.
.prettierrc

{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80
}

옵션별 설명

  • printWidth: 최대 줄 너비를 지정
  • tabWidth: 각 들여쓰기 수준에 대한 공백 또는 탭의 수를 지정
  • useTabs: true설정시 Prettier는 들여쓰기에 공백 대신 탭을 사용
  • semi: 명령문 끝에 세미콜론을 포함 여부
  • singleQuoute: 문자열 리터럴에 작은땀옴표 또는 큰따옴표 사용여부 결정
  • quouteProps: Javascript또는 JSON에서 개체 키를 처리하는 방법을 지정 "as_needed" 옵션은 필요한 경우에만 따옴표로 변환, "consistent"는 모든 키에 일관된 따옴표를 지정 "preserve"는 원래 따옴표를 유지
  • jsxSingleQuoute: singleQuoute와 유사한 옵션이지만 jsx속성에 해당
  • traillingCommna: 여러 줄 개체 리터럴 및 배열에 후행 쉼표를 포함 여부("all" 모든 여러 줄 배열 및 객체의 후행 쉼표, "es5" 해당 되는 경우 배열 및 객체의 후행 쉼표, "none" 후행 쉼표 없음)
  • bracketSpacing: 개체 리터럴 대괄호({}) 사이에 공백을 포함할지 여부
  • arrowParents: 화살표 함수 매개변수 주위에 괄호를 추가할지 여부("avoid" 매개변수가 하나만 있는 경우 괄호 없음, "always" 항상 괄호 추가)
반응형
반응형

⚡Vite에서 환경 변수 설정하고 호출하기

cra에서 환경변수 사용법과 약간의 차이가 있어서 정리하고자 한다.

⚙️Vite에서 환경 변수 설정하기

먼저 .env파일을 프로젝트 최상단에 생성합니다.

vite에서 호출하는 환경 변수는 VITE_ 라는 접두사를 붙여서 작성합니다.
(문자열이라도 "", ''를 제외한 값만 입력합니다.)
.env

VITE_WHEATHER_KEY=1a2b3c4d5e6f7g8k123456789
HELLO_KEY=HELLO // 동작 안함

😶‍🌫️소스에서 환경변수 호출하기

사용하고자 하는 소스에서 아래의 규칙으로 호출합니다.
import.meta.env.환경변수명

sample.tsx

export default function Title(){
    console.log(import.meta.env.VITE_WHEATER_KEY);
    console.log(import.meta.env.HELLO_KEY);
    return null;
}

🪄출력결과

HELLO_KEY라는 값은 VITE_ 접두사가 없기때문에 출력부분에 undefined처리가 되는 걸 볼 수 있습니다.
반응형