MINIWIKI
CareerSideProjectBook&Study
  • ⚡README
  • 😃ME
    • Review
      • 2025 OKR & 회고 - 회사 없이도 먹고살 수 있는 상태가 된다
        • 2025년 19주차
        • 2025년 18주차
        • 2025년 17주차
        • 소설쓰기의 쓸모
        • 2025년 15주차
        • 2025년 14주차
        • 요즘 회사생활
        • 첫 페이지 작성!
        • 큰 코 다쳤다
        • 오랜만에 좋았던 하루
        • 악순환과 반복실패
        • 2025년 12주차
        • 2025년 11주차
        • 2025년 3월 6일
        • 2025년 3월 4일
        • 2025년 3월 1일
        • 2025년 2월 회고
        • 2025년 1-2월 책, 영화, 음악
        • 2025년 1-2월 회고 (PM)
        • 2025년 1-2월 회고 (콘제품)
          • (Merged) 2025 비즈니스
        • 2025년 1-2월 회고 (삶/사람)
        • 2025년 1-2월 회고 (기본)
        • (25.02) 고객 피드백 받기
        • 다시 전략 수정
        • 머리 속 복잡한 것들 끄적끄적
        • 변하지 않는 핵심 철학
        • 개별화 능력을 이용하는 방법
        • 파고들기
        • 예술가와 사업가
        • 강점
        • PM으로서의 전문성
        • 부동시
        • 이게 다 무슨 소용인가
        • 내가 가장 잘 전할 수 있는 메시지
        • 연말인사 타이밍
        • Attitude는 옷부터
        • 다시 시작
      • 2024 회고
        • 2024년 12월 4주차 (52/52)
        • 원한다고 생각했던 것들
        • 2024년 12월 3주차 (51/52)
        • 회사 vs. 퇴사
        • 2024년 12월 2주차 (50/52)
        • 2024년 11월 4주차 (47/52)
        • 2024년 11월 3주차 (46/52)
        • 2024년 11월 1주차 (44/52)
        • 혓바늘
        • 2024년 10월 3주차 (42/52)
        • 그냥, 요즘하고 있는 생각들
        • 2024년 10월 1주차 (40/52)
        • 2024년 9월 4주차 (39/52)
        • 2024년 9월 3주차 (38/52)
        • 2024년 9월 2주차 (37/52)
        • 2024년 9월 1주차 (36/52)
        • 2024년 8월 4주차 (35/52)
        • 잃어버린 보물창고
        • 분기별 프로젝트
        • 강점검사
        • 글쓰기
        • 이상적인 하루
        • 나와 아프리카
        • 한 때 나에게 힘이되었던 문장들
      • 2023 회고
        • 2023년 12월 5주차
        • 2023년 12월 4주차
        • 2023년 12월 3주차
        • 2023년 12월 2주차
        • 2023년 12월 3일
        • 2023년 12월 1주차
        • 2023년 11월 29일
        • 2023년 11월 28일
        • 2023년 11월 27일
        • 2023년 11월 18일
        • 2023년 11월 15일
        • 2023년 11월 12일
        • 2023년 11월 11일
        • 2023년 11월 1주차
        • 2023년 10월 3주차
        • 2023년 9월 4주차
        • 2023년 9월 3주차
        • 2023년 9월 2주차
        • 2023년 9월 1주차
        • 2023년 8월 4주차
        • 2023년 8월 2주차
        • 2023년 8월 1주차
        • 2023년 7월 4주차
        • 2023년 7월 3주차
        • 2023년 7월 2주차
        • 2023년 상반기 회고
        • 나태하고 욕심많은 인간은 어떻게 살아야 하나
        • 책 <어떻게 살아야 하는가>
        • 책 <당신은 결국 무엇이든 해내는 사람>
        • 복잡계를 살아가는 단순한 사람
        • 책 <모든것이 되는법>
        • 글로 신뢰를 얻었던 경험들
        • 기획은 나를 찾아가는 과정
        • 나는 왜 살아가는가
        • 장항준 감독으로부터 배우는 "삶을 대하는 자세"
        • 개발자가 말하는 감정에도 분석이 필요한 이유
      • 2022년 회고
        • problem map 작성하기
        • 삶에서 내가 해결하고 싶은 문제 (2)
        • 삶에서 내가 해결하고 싶은 문제 (1)
        • <삶의 문제> 지도 다시 꺼내보기
        • 지도 위의 29살
        • 매번 시간계획을 망치는 MBTI 'P형 인간'을 위한 5단계 인생관리법
        • 당신은 왜 프로그래밍을 공부하는가?
        • 아무 것도 아닌 내가 글을 쓰는 이유
        • 책 <여행의 이유>
        • 책 <붕대감기>
      • 2021년 회고
    • Career
      • [미리캔버스] AI 제품 PM
        • 선택과 집중
        • 어쩌면 내가 틀릴 수도 있다는 생각
        • 뾰족한 사람들과의 협업
        • AI기능 PPT로 온보딩
        • AI 제품에서 가장 중요한 것
      • [미리캔버스] 앱 PM
      • [미리캔버스] 소상공인 제품 PM
      • [미리캔버스] 2.0 PM
      • [홀로스탠딩] 백엔드 개발
      • [청년5.5] 안드로이드 개발
      • [가축대출사업] NGO Project PM
    • Insight
    • Interview
    • Public Writing
  • SIDE PROJECT
    • [Youtube] 메이킹필름
      • [Product] 청춘집 프로젝트
        • (v24.11) 청춘집 JTBD
          • (구) 청춘집 실행계획
          • (구) 플레이리스트 기획
            • 데이식스 전곡 타임라인
            • 챕터 구성
        • (v25.01) 청춘집 JTBD
          • 아이돌 굿즈 시장 조사 (공식)
          • 아이돌 굿즈 시장 조사 (비공식)
        • 제작 준비
          • 레퍼런스 - 오프라인 시집
          • a5 책 만들기
    • [Youtube] 마포구타자기
      • [mptw] JTBD
        • IKIGAI
      • [mptw] 채널 설정
        • 채널 이름 후보군
      • 시리즈 [읽는음악]
        • [읽는음악] 백로그
          • 노래 가사 콘텐츠 레퍼런스
        • ep1. 파노라마 - 이찬혁
          • 이찬혁 <ERROR>
        • ep2. 마지막 인사 (feat. 청하) - 이찬혁
        • ep3. 나의 바다에게 - 도영
        • ep4. Dattom - 백예린
        • ep5. REBEL HEART - IVE
        • ep6. Either way - IVE
        • ep7. 너와의 모든 지금 - 재쓰비(JAESSBEE)
        • ep8. 예뻤어 - DAY6
        • 6주차. 데이식스 시리즈
    • [IT] 공적인사적모임 플랫폼
      • 1. 우리 조직의 얼굴을 만들자
      • 2. 내 생에 첫 기획서 만들기 (feat. QA Driven Development)
    • [Meet] 공적인사적모임
    • [Youtube] 이상한나라의 개발자할무니
    • [Study] Disquiet PM 스터디 쿨피스
    • [IT] 서울 빵 맛집 잘알 테스트
    • [Meet] 얼리버드 모닝클럽
      • 홍보를 곁들인 2주일 운영후기
  • 잡학사전
    • 와인 원데이 클래스
    • 소설쓰기
      • <책> 소설쓰기의 모든 것 1 - 플롯과 구조
      • 유튜브 - 소설 쓰는 법
      • 강의들
      • 작가가 되려면 어떻게 해야해
    • AI
      • 생성형 AI
    • ComfyUI
      • Stable Diffusion
      • ComfyUI 준비, 설치, 설정
      • Module 구조에 대해 이해하기
      • ComfyUI
      • Core Node
    • 작사
      • 작사가 되는 법
    • 유튜브
      • 유튜버 스토리님의 부캐 성장기
      • 주언규 유튜브 초보편 (클래스101)
      • 주언규 유튜브 왕초보 편
    • 경제
      • 연금저축펀드
    • ChatGPT
    • 크롤링
      • Automatio
      • Octoparse
    • 노코드
      • 북마크 & 노코드 서비스 목록
  • PRODUCT&BUSINESS
    • Service Planning/Analysis
      • 브런치시리즈 <개발보단 고객개발>
      • baemin mart
        • 1. 시작
        • 2. 우아한형제들 & 배민상회
        • 3-1. [인터뷰] 포항에서 치킨집을 운영하시는 최사장님
        • 3-2. [인터뷰] 부산에서 족발 프렌차이즈를 운영하시는 이사장님
        • 4. <아프니까 사장이다> 커뮤니티 데이터 분석
        • 5. 문제정의 & 개선 가설
        • 6. 결론 - 역기획서
      • careerly
      • meetme
      • 배달의 민족 역기획 사례
      • 당근마켓 역기획 사례
      • 도그냥 님이 말하는 진짜 역기획
      • 도그냥의 역기획 스터디법
      • 책 <현업 기획자 도그냥의 서비스 기획 스쿨>
      • 기획서 작성하기
    • Business/Growth
      • Unsexy Business 뉴스레터에서 얻는 인사이트
      • 책 <원씽>
      • 책 <아프리카 스타트업>
      • 책 <유난한 도전>
      • 책 <함께자라기>
      • 책 <나는 돈 없어도 사업을 한다>
      • 책 <나는 장사의 신 은현장이다>
      • 책 <왜 사업하는가>
      • 책 <왜 일하는가>
      • 이제는 피칭도 유튜브로
      • 세컨드 브레인이 필요한 이유
      • 책 <타이탄의 도구들>
      • 책 <역행자>
        • <역행자> 역행자의 7단계 모델 복습
        • <역행자> 운명을 거스르는 역행자의 7단계 모델
      • 책 <월급쟁이로 시작한 38살 그녀는 어떻게 30억을 벌어 파이어족이 되었을까?>
      • 책 <파리에서 도시락을 파는 여자>
      • 책 <존리의 금융문맹탈출>
      • 책 <돈의 감각을 길러주는 경제 지식 첫걸음>
        • 금리
        • 환율
        • 주식
        • 채권
        • 부동산
        • 연금
        • 경제정책
        • 규제
        • 경제위기
    • Product-Market Fit
      • 브런치 북 <개발보단 고객 개발>
      • 책 <아이디어 불패의 법칙>
      • 고이장례연구소
      • 글쓰기로 PMF 검증하기
      • 연대 송도 캠퍼스의 40%가 사용한 서비스
      • 어웨이크코퍼레이션의 김민준 님
      • 드로우 마이 브랜드
      • 노코드로 PMF 찾는 방법
    • UI/UX
      • UX Writing Workshop
        • 4. 고객과의 관계형성 - 차별점 강화
        • 3. 비즈니스 임팩트를 만드는 글쓰기
        • 2. 후킹한 문장으로 고객 행동 이끌기
        • 1. 쉽고 정확한 문장으로 문제해결
        • What is UX Writing?
        • Reference
      • UX/UI 관련 유용한 사이트 모음
    • PM/PO
      • 책 <프로덕트 매니지먼트>
      • 책 <인스파이어드>
      • PM Wiki
      • 당신과 팀을 성장시킬 PM 직무가이드
      • PO 미신, 파랑새를 찾아서 - CPO 김용훈
      • 개발자가 생각하는 좋은 PM 나쁜 PM
      • 프로덕트 매니저는 뭐하는 사람인가
      • 토스 리더가 말하는 PO가 꼭 알아야할 개념 (2)
      • 토스 리더가 말하는 PO가 꼭 알아야할 개념 (1)
      • 책 <조직을 성공으로 이끄는 프로덕트 오너>
        • <프로덕트 오너> PO의 시간관리법
        • <프로덕트 오너> PO가 데이터 기반으로 일할 수 밖에 없는 이유
  • DATA
    • Database
      • 이 위키를 만드는데 참고한 자료들
      • 데이터 기반 의사결정
      • 데이터베이스의 종류
      • 트랜잭션과 무결성
      • 트랜잭션, 커밋, 롤백, 트랜잭션 전파
      • ERD, entity relationship diagram
      • 기본 3 - 관계, 키
      • 기본 2 - 필드, 레코드, 타입
      • 기본 1 - 엔티티, 릴레이션, 속성, 도메인
    • SQL
      • Sub Query
      • JOIN
      • 데이터 정렬셋과 유니코드
      • 자료형
      • DDL, DML
      • SELECT
      • SQL
    • MySQL
      • MSQL to MySQL Data Migration
      • MySQL Server 다운로드, 로그인
      • helpful commands
      • 문자열 자르기 SUBSTR(column, startIdx, length)
      • 특정 값을 ORDER BY 특정 값 우선 정렬 하기 (ORDER BY FIELD)
      • 이것이 MySQL이다
    • H2
      • ‼️h2 in-memory-db Table not found (this database is empty) 해결방법
  • Dev-General
    • Webmark
    • Open Source
      • 나의 첫 opensource contribution 경험기
    • Dev-Insight
      • Event
        • YOUTHCON 2022
        • INFCON 2022
      • 책 <누워서 읽는 알고리즘>
      • 책 <나는 LINE 개발자입니다>
      • 서비스에 대해 개발자가 가져야할 생각들
      • AI 시대에서 결국 살아남는 것
      • AI 시대에 개발자가 살아남는 방법
      • 주니어를 넘어서, 성장하는 개발자의 길 (인프런)
      • 아마추어와 프로의 차이
      • 개발자의 개발공부에 대하여
      • 서비스에 대해 개발자가 가져야할 생각들
      • 좋은 개발자와 인맥을 만든 노하우
      • 개발자 취업기/이직기 모음
        • 라인게임즈 백엔드 개발자 경선님
        • OKKY 미니세미나 <비전공 학원출신 SI개발자, 유명스타트업 들어간.ssul> 참석 후기
        • 비전공자에서 2억받는 아마존 엔지니어가 되기까지
        • IT 대기업 100% 합격하는 방법
  • 🏗️computer science
    • Algorithm & Data Structure
      • About this page
      • Test Review
        • Page 1
      • Big-O
        • 빅오표기법의 문제풀이
        • 피보나치 수열의 시간복잡도
      • Bit Operation
        • bit masking
      • Math
        • 합공식 / 누적합
        • 피보나치 수
        • 약수찾기
        • 소수찾기
          • 백준 1978 소수찾기
          • 백준4948 베르트랑 공준
          • 백준 8393 합
          • 백준 1929 소수구하기
        • 최대공약수 / 최소공배수
          • 백준 2824 최대공약수, BigInteger
          • 백준 2609 최대공약수, 최소공배수
        • 순열과 조합
          • 백준 15649 N과 M
        • 그 외 개념 정리
      • Recursion
        • N Queens problem
        • counting cells in a blob
        • recursion 응용 - 미로찾기
        • 순환 알고리즘의 설계
        • 순환적으로 사고하기
        • 백준 17478 재귀함수가 뭔가요
        • 백준 10870 피보나치수 5
      • Sort
        • java 에서의 정렬
        • radix sort
        • sorting in linear time
        • comparison sort 에서 최상의 시간복잡도
        • priority queue
        • heap sort
        • quick sort
        • merge sort
      • Array and List
        • 표준 라이브러리
      • Linked list
      • String
      • Stack
        • 백준 1874 스택수열
        • 백준 10828 스택 구현하기
      • Queue
        • 백준 10845 큐 구현하기
      • Heap
        • 백준 11298 절대값힙
        • 백준11279 최대힙
        • 백준1927 최소힙
      • Deque
      • Tree and Binary tree
        • Tries
        • Red-Black Tree
        • Binary Search Tree
      • Search
        • 완전 탐색
        • 이분탐색
      • Graph
        • 최단경로
        • MST 2 - prim 의 알고리즘
        • MST 1 - Kruskal 의 알고리즘
        • MST, minumum spanning tree
        • DAG, Directed Acyclic Graph
        • DFS, Depth First Search
        • BFS, Breadth First Search
      • Dynamic Programming
        • Knapsack problem
        • LCS, Longest Common Subsequence
        • matrix chain
        • 행렬 경로 문제
        • 백준 1003 피보나치 함수
        • 백준 9461 파도반 수열
        • 백준9251 LCS
      • Greedy
      • Implementation
      • LIS, Longest Increasing Subsequence
      • Two Pointer
      • Line Swipping
      • Fenwick tree
      • Backtracking
    • Computer Structure
      • 이 위키를 만드는데 참고한 자료들
      • 그래서 컴퓨터는 어떻게 동작하나요?
      • 컴퓨터의 구성
      • 컴퓨터의 역사
      • 컴퓨터 구성요소의 기능 및 이해
      • 중앙처리장치 - 마이크로 명령 - 입출력과 인터럽트
      • 중앙처리장치 - 기본 컴퓨터 프로그래밍
      • 중앙처리장치 - 프로그래밍 언어와 실행
      • 파이프라인과 벡터처리 - 데이터의 종속성 - 병렬처리와 파이프라인
      • 파이프라인과 벡터처리 - 파이프라인 구조 - 데이터/구조
      • 파이프라인과 백터처리 - 산술&명령어 파이프라인
      • 파이프라인과 벡터처리 - 파이프라인 CPU의 성능분석
      • 메모리 구조 - 메모리 시스템의 이해
      • 메모리 구조 - 효율적인 메모리 관리 정책
      • 메모리 구조 - 컴퓨터 성능 개선을 위한 메모리 관리
      • 입출력구조 - 시스템 BUS 구성 및 제어
      • 입출력 구조 - 입출력(I/O) 연결과 주소 지정
      • 입출력 구조 - 입출력 수행과 인터럽트
      • 병렬컴퓨터 구조와 성능분석 - 멀티 프로세서
      • 병렬 컴퓨터 구조와 성능 분석 - 시스템 성능 분석과 개선
    • This Is Coding Test 2021
      • 1. 출제 경향 & 파이썬 문법 부수기
      • 2. 그리디 알고리즘 & 구현
      • 3. BFS & DFS
      • 4. 정렬 알고리즘
      • 5. 이진탐색
      • 6. 다이나믹 프로그래밍
      • 7. 최단경로 알고리즘
      • 8. 기타 그래프 이론
      • 9. 코딩테스트에서 자주 출제되는 기타 알고리즘
      • 10. 개발형 코딩테스트
    • Operating System
      • 이 위키를 만드는데 참고한 자료들
      • 운영체제란, Introduction to Operating Systems
      • 컴퓨터 시스템의 구조, Structure of Computer System
      • 프로그램의 실행, Program Execution
      • 프로세스, Process
      • 쓰레드, Thread
      • 프로세스의 생성과 종료, Start and End of Process
      • 프로세스 시스템 콜과 프로세스간의 협력, System call and Interprocess Communication
      • CPU Scheduling
      • CPU Scheduling Algorithm
      • Process Synchronization Problem
      • Initial Attempts to Solve Process Synchronization Problem
      • semaphore 와 monitor 로 synchronization 해결하기
      • 데드락, Deadlock
      • 메모리 관리, Memory Management
      • Memory Allocation
      • Virtual Memory
      • Virtual Memory 2
      • File System
      • File Systems Implementation
      • Disk Management & Scheduling
    • Network
      • 이 위키를 만드는데 참고한 자료들
      • 대규모 트래픽으로 인한 서버 과부하 해결방법
      • 유선 LAN과 무선 LAN
      • 네트워크를 이루는 장치 (L1, L2 .. L7)
      • REST API
      • HTTP 매서드
      • HTTP 상태코드
      • 직렬화와 역직렬화
      • 로그인 구현방식 2. 토큰 기반 인증방식
      • 로그인 구현방식 1. 세션 기반 인증방식
      • 웹 브라우저의 캐시 - 공통점과 차이점
      • 웹 브라우저의 캐시 - 쿠키
      • HTTP header
      • 웹 브라우저의 캐시 - 세션 스토리지
      • 웹 브라우저의 캐시 - 로컬스토리지
      • browser rendering
      • HTTPS 와 TLS - TLS 핸드쉐이크
      • HTTPS 와 TLS - 암호화
      • HTTP History
      • www.naver.com 을 주소창에 입력하고 화면에 나타나기까지의 과정
      • IP 주소 - 공인 IP와 사설 IP
      • IP 주소 - Classless,Subnet Mask, Subnetting
      • IP 주소 - Classful IP Addressing
      • IP 주소 - IPv4, IPv6
      • IP 주소 - 이진수 이해하기
      • IP 주소, MAC 주소, ARP, RARP
      • 라우팅
      • TCP 4way handshake and TIME_WAIT
      • TCP 3way handshake
      • TCP/IP - internet layer
      • TCP/IP - Transport Layer
      • TCP/IP - Application Layer
      • TCP/IP - MTU, MSS, PMTUD
      • TCP/IP 4계층, OSI 7 layer
      • 네트워크의 분류 - LAN, MAN, WAN
      • 네트워크 토폴로지와 병목현상
      • 네트워크의 기초 3
      • 네트워크의 기초 2
      • 네트워크의 기초
    • Linux
      • reference
      • sudo apt-get install / uninstall
      • vim
      • linux basic command
    • Design Pattern
      • 이 위키를 만드는데 참고한 자료들
      • static 을 자주 사용하게 되었을 때의 단점
      • 자바스크립트의 class와 static
      • 프로그래밍 컨텍스트
      • 의존성 주입 vs. 전략패턴
      • flux pattern
      • Spring MVC 패턴 적용 사례
      • MVC, MVP, MVVM pattern
      • 프록시 패턴
      • 옵저버 패턴
      • 전략패턴
      • 의존성 주입과 의존 관계 역전 원칙
      • 이터레이션 패턴
      • 추상 팩토리 매소드 패턴
      • 팩토리 메소드 패턴
      • 싱글톤 패턴
      • 디자인 패턴, 라이브러리와 프레임워크의 차이
    • Programming Basic (Go)
      • 이 위키를 만드는데 참고한 자료들
      • 트랜지스터, Trangister
      • 논리소자, Logic Element
      • 튜링과 폰 노이만, Turing and Von Neumann
      • 컴퓨터의 원리, Computer Principle
      • 프로그래밍 언어, Programming Language
      • 컴파일러와 동적언어, Compiler and dynamic language
      • golang
      • hello, world
      • variable
      • variable 2
    • Base Knowledge
      • 이 위키를 만드는데 참고한 자료들
      • 신기술 도입시 고민해야할 점(feat. react.js vs. vue.js)
      • 정적 타입 시스템의 필요성
      • 도커, 컨테이너
      • 클라우드, Saas, IaaS, PaaS
      • SSO
      • RBAC
      • OAuth2.0
      • REST API 사용을 위한 인증 방법 4가지
      • API
      • Data Format - XML
      • Data Format - JSON
  • ☕Java/Spring
    • Java
      • Java Code Convention
      • Java 버전별 특징 (v1-v19)
      • java.lang.Math
      • List 4가지의 초기화 방법
      • HashMap 4가지의 정렬 방법
      • 어노테이션 프로세서 정리하기
      • Annotation Processor 로 없는 소스코드 생성하기
      • lombok 은 어떻게 동작하는 것일까?
      • 다이내믹 프록시 정리하기
      • 클래스의 프록시
      • 다이내믹 프록시
      • 프록시 패턴은 무엇인가
      • Spring Data JPA 는 어떻게 동작할까?
      • reflection api 정리
      • reflection api 이용하여 spring ioc container 만들기
      • reflection api
      • spring dependency injection 은 어떻게 동작할까
      • 바이트 코드 조작하기
      • java bytecode 를 조작해 테스트 코드 커버리지 확인하기 (feat.jacoco)
      • Class Loader
      • JVM 의 구조
      • java, jvm, jdk and jre
      • synchronized
      • java string.split(".") 오류
    • Java 8
      • 이 위키를 만드는데 참고한 자료들
      • Metaspace
      • Parallel 정렬
      • Annotation
      • CompletableFuture
      • Date and Time
      • Optional
      • Stream
      • interface의 default 메소드와 static 메소드
      • 인터페이스의 변화
      • 함수형 인터페이스
      • java 8 소개
    • Spring Framework
      • Spring 3.0 준비하기
      • 특정 매소드만 transaction 처리하기
      • 스프링 프로젝트 시작하기
      • 스프링이란 무엇인가
      • 스프링 핵심 기술의 응용
      • AOP 2
      • AOP 1
      • 서비스 추상화 2
      • 서비스 추상화 1
      • 예외
      • 템플릿
      • 테스트
      • 오브젝트와 의존관계
      • 스프링이란
    • Spring Boot
      • [Gradle]UncheckedIOException
      • java19 + spring 3.0.5 + gradle 7.4.1 에서 프로젝트 gradle 설정하기
      • [리뷰] Gradle 멀티 프로젝트 관리
      • [리뷰] 멀티모듈 설계 이야기 with Spring, Gradle
    • JPA/QueryDSL
      • querydsl 을 쓰는 이유
      • JPA querydsl에서 json array 로 된 컬럼에 조건 적용하기
      • querydsl 에서 mysql order by field() 사용하기
  • 🏰Infrastructure
    • InfraWorkshop
      • 이 위키를 만드는데 참고한 자료들
      • aws로 안정적인 인프라 만들기 2
      • aws로 안정적인 인프라 만들기 1
      • 어플리케이션 진단하기
      • 서버 진단하기
      • 부하 테스트
      • 웹 성능 개선하기
      • 웹 성능 진단하기
      • <aws로 그럴듯한 인프라 만들기> 회고와 피드백
      • aws로 그럴듯한 인프라 만들기 3 - 배포스크립트
      • aws로 그럴듯한 인프라 만들기 2 - 배포하기
      • aws로 그럴듯한 인프라 만들기 1 - 네트워크 망 구성
      • docker container
      • connection check
      • network segmentation
      • cloud 서비스를 사용한다는 것
    • AWS
      • AWS IAM
      • AWS CodePipeline 으로 배포 자동화하기 (1)
      • AWS CodePipeline 으로 배포 자동화하기 (2)
  • 🪄Test
    • TDD
      • 이 위키를 만드는데 참고한 자료들
      • [2주차] 로또 과제 강의를 듣고나서
      • [1주차] 자동차 경주 과제 강의를 듣고나서
      • TDD, 리팩토링이란?
      • 가장 쉽게 TDD 시작하는 방법
      • 의식적인 연습과 학습 테스트
      • TDD 에 집착해야하는 이유
      • 공부하는 자세
    • AssertJ
      • 이 위키를 만드는데 참고한 자료들
    • JUnit
      • 이 위키를 만드는데 참고한 자료들
      • Junit 기본 개념
  • 😎OTHERS
    • Helpful Command
      • Mac 에서 특정 포트 검색, 종료
      • crontab
    • Llibrary
    • IntelliJ
      • 내가 좋아하는 커스텀 세팅
    • GIT
      • Github ID/Token 한번 입력 후 저장하기
      • Github Actions
      • github organization private repository push 안될 때 (not found issue)
      • commands
      • git commit convention
    • Logging
      • logback + webfilter 로 로그설정
      • ‼️log4j 보안 이슈
    • Postman
      • postman 의 header에서 언더바(_) 변수 인식 안되는 현상
Powered by GitBook
On this page
  • 1. 외부망에 웹 어플리케이션 배포
  • 1-1. git, java 설치하기
  • 1-2. 소스코드 배포, 빌드 및 실행
  • 1-3. 로그 확인하기
  • 1-4. 어플리케이션 프로세스 종료하기
  • 1-5. 실행된 명령어 이력 확인
  • 2. DNS 설정
  • 3. 웹 애플리케이션 앞단에 Nginx 로 Reverse Proxy 구성하기
  • 3-1. Reverse Proxy?
  • 3-2. 도커로 Nginx 띄우기
  • 4. Reverse Proxy에 TLS 설정
  • 4-1. letsencrypt 를 활용하여 무료로 TLS 인증서 받기
  • 4-2. 생성된 인증서를 활용하여 Reverse Proxy 에 TLS 설정하기
  • 5. 운영 데이터베이스 구성하기
  • 6. 로컬/운영 설정 파일 나누기
  • 7. Trouble Shooting
  • 7-1. letsencrypt 에서는 도메인과 서브도메인은 같은 인증서로 취급하지 않는다.
  • 7-2. nginx에 TLS 관련 설정을 추가한 후, docker 컨테이너가 제대로 실행되지 않는다.
  • 8. 추가적으로 읽어보면 좋을 글들
  • 9. 추가적으로 하면 좋은 것들
  • 9-1. [추가] 데이터베이스 테이블 스키마 버전관리
  • 9-2. [추가] 설정 별도로 관리하기
  • 9-3. [추가] 정적테스트(SonarLint)
  • 9-4. [추가] 로컬테스트(MultiRun)

Was this helpful?

  1. Infrastructure
  2. InfraWorkshop

aws로 그럴듯한 인프라 만들기 2 - 배포하기

2. 배포하기

Previousaws로 그럴듯한 인프라 만들기 3 - 배포스크립트Nextaws로 그럴듯한 인프라 만들기 1 - 네트워크 망 구성

Last updated 2 years ago

Was this helpful?

이번 시리즈는 아래와 같이 진행된다. 이 글에서는 3번에 대해서 다룰 것이다.

1. 외부망에 웹 어플리케이션 배포

1-1. git, java 설치하기

# git 은 ubuntu 에는 기본으로 설치되어있다. 설치 루트를 확인하자. 
which git 

# java 설치하기 
sudo apt update && upgrade 
sudo apt install default-jdk

1-2. 소스코드 배포, 빌드 및 실행

# git repository 를 clone 
git clone https://github.com/next-step/infra-subway-deploy.git
# 특정 브랜치만 클론하기 
git clone -b miniminis --single-branch https://github.com/next-step/infra-subway-deploy.git

# 가져온 프로젝트 빌드
$ ./gradlew clean build
# 테스트 없이 빌드
$ ./gradlew clean build -x test

# 빌드된 jar파일을 찾아보기
$ find ./* -name "*jar"

# jar file 실행하기
$ java -jar [jar파일명] & 

# 어플리케이션이 정상적으로 실행되었는지 확인하기 
$ curl http://localhost:8080
  • -Dserver.port=8000 옵션을 활용하면 port를 변경할 수 있다.

  • -Djava.security.egd 옵션을 확용하면, 서버 시작 시간을 줄일 수 있다.

    $ java -Djava.security.egd=file:/dev/./urandom -jar [jar파일명] &
  • $  nohup java -jar [jar파일명] 1> [로그파일명] 2>&1  &

1-3. 로그 확인하기

# java applicaion이 남기는 로그를 확인합니다.
$ tail -f [로그파일명]

# 파일을 압축하고 파일 소유자와 모드를 변경해봅니다.
$ tar -cvf [파일명] [압축할파일 또는 디렉터리]
$ sudo chown [소유자계정명]:[소유그룹명] [file이름] 
$ chmod [옵션] [파일명]

> https://ko.wikipedia.org/wiki/Chmod
  • 브라우저에서 http://{서버 ip}:{port}로 접근해본다.

1-4. 어플리케이션 프로세스 종료하기

# 프로세스 pid를 찾는 명령어
$ ps -ef | grep java
$ pgrep -f java

# 프로세스를 종료하는 명령어
$ kill -2 [PID]
  • SIGKILL 명령어는 쓰지 않는 것이 권장된다.

1-5. 실행된 명령어 이력 확인

  • 그동안 터미널에서 실행된 모든 명령어 목록을 확인해볼 수 있다.

$ history

2. DNS 설정

  • 어플리케이션을 배포한 public server 의 public ip 를 매핑한다.

3. 웹 애플리케이션 앞단에 Nginx 로 Reverse Proxy 구성하기

3-1. Reverse Proxy?

일반적으로 Proxy 서버는 LAN -> WAN 으로의 요청을 대리하여 처리해준다. 예를 들어 내가 집에서 와이파이로 특정 국가의 서비스를 이용하려고 하는데, 해당 서비스에서 한국의 IP를 막아두었다면, 나는 VPN 등의 서비스를 통해서 다른 국가의 IP로 우회하여 해당 서비스에 접근하게 된다.

Reverse Proxy의 경우는 그 반대라고 할 수 있다. WAN -> LAN 으로의 요청을 대리하여 처리해준다. 클라이언트로부터 어플리케이션 서버로 요청이 들어올 때, 중간에서 reverse proxy server 가 개입하여 다양한 전후처리를 해준다. 요청을 처리한 뒤, 어플리케이션 서버 역시 응답을 클라이언트로 바로 전달하지 않고, reverse proxy server 로 전달한다. 요청을 받은 reverse proxy server 는 서버 대신 클라이언트에게 응답을 전달한다.

Reverse Proxy 를 사용하면 결국 클라이언트와 어플리케이션 서버 사이에서 필요한 다양한 전후처리를 할 수 있다. 어플리케이션 서버는 정말 비즈니스 로직, 그 자체에만 집중하면 된다.

Reverse Proxy vs. Load Balancer

  • reverse proxy 는

    • TLS 암호화 등을 맡아 보안성을 향상시키거나,

    • 확장성을 향상시키거나,

    • 압축, SSL 처리로 인한 백엔드 리소스 확보, 캐싱처리 등을 통해 웹의 속도를 향상시키는 역할을 한다.

  • 반면, load balancer 는

    • 부하를 분산하고

    • 서버 상태를 체크하며

    • 세션을 관리하는 등의 역할을 수행한다.

하지만 Nginx의 경우는 두 가지의 역할을 모두 수행한다.

3-2. 도커로 Nginx 띄우기

도커를 이용하여 nginx를 proxy server로 세워보자.

# 1. 우선 도커를 설치한다. 
$ sudo apt-get update && \
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo apt-key fingerprint 0EBFCD88 && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce && \
sudo usermod -aG docker ubuntu && \
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose


# 2. 아래와 같은 내용으로 Dockerfile 을 생성한다. 
FROM nginx

COPY nginx.conf /etc/nginx/nginx.conf  


# 3. nginx.conf 파일을 아래와 같이 작성한다. 
events {}

http {
  upstream app {
    server 172.17.0.1:8080;
  }

  server {
    listen 80;

    location / {
      proxy_pass http://app;
    }
  }
}

# 4. nextstep/reverse-proxy 라는 이름으로 도커 이미지를 빌드한 뒤, 80포트로 실행한다.  
$ docker build -t nextstep/reverse-proxy .
$ docker run -d -p 80:80 nextstep/reverse-proxy

4. Reverse Proxy에 TLS 설정

클라이언트 - 서버 간의 통신은 언제나 해킹의 위험에 노출되어있다. 그냥 평문으로 통신할 경우, 패킷이 가로채질 수 있으므로, 반드시 TLS 암호화를 하여 통신하도록 한다.

4-1. letsencrypt 를 활용하여 무료로 TLS 인증서 받기

# 1. docker 명령어를 통해서 내 도메인인 "subway-mhson.kro.kr"에 대한 인증서를 요청한다.  
docker run -it --rm --name certbot \
  -v '/etc/letsencrypt:/etc/letsencrypt' \
  -v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
  certbot/certbot certonly -d 'subway-mhson.kro.kr' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
# 2. 위의 명령어를 실행하면, 아래와 같은 결과가 나온다. 
# 도메인 구입한 사이트에서 DNS TXT 레코드에 안내된 값을 추가해준다. 
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for subway-mhson.kro.kr

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.infra.subway-mhson.kro.kr.

with the following value:

jiRlP5PscTZ9f_kh1GfNbmBl6YiSt4i3MKo2irIHmgQ

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.subway-mhson.kro.kr.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
# 3. 아래와 같은 결과가 나오면 성공! 
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/subway-mhson.kro.kr/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/subway-mhson.kro.kr/privkey.pem
This certificate expires on 2023-06-03.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

DNS를 설정하는 사이트에서 DNS TXT 레코드를 추가한 후, 제대로 반영되었는지 dig 명령어로 확인한 후에 인증서 설정 진행을 계속한다.

$ dig -t txt _acme-challenge.example.com +short

4-2. 생성된 인증서를 활용하여 Reverse Proxy 에 TLS 설정하기

# 1. 우선 인증서 현재 경로로 옮기기 
$ cp /etc/letsencrypt/live/[도메인주소]/fullchain.pem ./
$ cp /etc/letsencrypt/live/[도메인주소]/privkey.pem ./


# 2. 위에서 생성했던 Dockerfile 을 아래와 같이 수정한다. 
FROM nginx

COPY nginx.conf /etc/nginx/nginx.conf 
COPY fullchain.pem /etc/letsencrypt/live/[도메인주소]/fullchain.pem
COPY privkey.pem /etc/letsencrypt/live/[도메인주소]/privkey.pem


# 3. nginx.conf 도 아래와 같이 수정한다. 
events {}

http {       
  upstream app {
    server 172.17.0.1:8080;
  }
  
  # Redirect all traffic to HTTPS
  server {
    listen 80;
    return 301 https://$host$request_uri;
  }

  server {
    listen 443 ssl;  
    ssl_certificate /etc/letsencrypt/live/[도메인주소]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[도메인주소]/privkey.pem;

    # Disable SSL
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # 통신과정에서 사용할 암호화 알고리즘
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

    # Enable HSTS
    # client의 browser에게 http로 어떠한 것도 load 하지 말라고 규제합니다.
    # 이를 통해 http에서 https로 redirect 되는 request를 minimize 할 수 있습니다.
    add_header Strict-Transport-Security "max-age=31536000" always;

    # SSL sessions
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;      

    location / {
      proxy_pass http://app;    
    }
  }
}


# 4. 방금 전에 띄웠던 도커 컨테이너를 중지 + 삭제하고, 새로운 설정을 반영하여 다시 띄운다. 
$ docker stop proxy && docker rm proxy
$ docker build -t nextstep/reverse-proxy:0.0.2 .
$ docker run -d -p 80:80 -p 443:443 --name proxy nextstep/reverse-proxy:0.0.2

5. 운영 데이터베이스 구성하기

일반적으로 데이터베이스를 컨테이너로 다루지는 않는다. 컨테이너는 사라지면 그만이니, 데이터베이스처럼 영속성을 가진 데이터를 다루기에는 적절하지 않은 면이 있다. 하지만, 지금은 데이터베이스가 중요한 것이 아니라 인프라 구축에 대한 실습을 하고 있는 것이므로, 도커를 이용해 빠르게 데이터베이스를 구축해보자.

# 1. 데이터베이스 실행하기 
$ docker run -d -p 3306:3306 brainbackdoor/data-subway:0.0.1

# 2. 데이터베이스 내부 접속하기  
$ docker ps -al 
$ docker exec -it [container id] /bin/bash

# 3. mysql 실행하여 데이터 확인하기 
mysql -u [id] -p 
(password 입력)

show databases;
use subway;

show tables;
select * from line;

6. 로컬/운영 설정 파일 나누기

지금까지의 실습에서는 데이터베이스의 데이터를 조회하지는 않았다. 이제 로컬 개발환경과 운영 환경이 구분되었으므로 application.properties 설정파일을 통해 운영 환경별로 데이터베이스 설정을 분리해본다.

---
# local

spring:
  config:
    activate:
      on-profile: local
  datasource:
    url: jdbc:mysql://localhost:3306/subway?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: root
    password: masterpw
    driver-class-name: com.mysql.cj.jdbc.Driver

---
# prod

spring:
  config:
    activate:
      on-profile: prod
  datasource:
    url: jdbc:mysql://192.168.11.151:3306/subway?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: root
    password: masterpw
    driver-class-name: com.mysql.cj.jdbc.Driver

어플리케이션 서버를 실행할 때에는 운영 환경 설정을 적용할 수 있도록 옵션을 추가한다.

$ java -jar -Dspring.profiles.active=prod [jar파일명] 

7. Trouble Shooting

7-1. letsencrypt 에서는 도메인과 서브도메인은 같은 인증서로 취급하지 않는다.

  1. 최초로 인증을 받을 때, 도메인을 입력하라고 되어 있어서 subway-mhson.kro.kr 주소로 TLS 인증서를 받았다.

  2. 그런데, 나는 서브도메인인 infra.subway-mhson.kro.kr 을 이용해서 서비스를 하고 있었다. 서브도메인까지 인증서가 적용될 것으로 기대했으나, 그렇지 않았다.

  3. 결국 서브 도메인인 infra.subway-mhson.kro.kr 로 인증서를 다시 받아서 TLS 암호화를 적용했다.

7-2. nginx에 TLS 관련 설정을 추가한 후, docker 컨테이너가 제대로 실행되지 않는다.

문제상황은 다음과 같았다.

  1. TLS 인증서를 발급받은 뒤, Dockerfile 과 nginx.conf 를 수정하였다.

  2. 수정된 버전으로 다시 docker 이미지를 빌드한 뒤, 컨테이너를 실행시켰더니, 자꾸 상태가 Exit 으로 표시되었다.

해결과정

  1. docker logs [container id] 명령어를 통해서 우선 어떤 문제가 있는지 원인을 파악하였다.

  2. 맨 마지막 줄의 메시지가 수상했다.

    1. nginx: [emerg] cannot load certificate key "/etc/letsencrypt/live/subway-mhson.kro.kr/privkey.pem": PEM_read_bio_PrivateKey() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: ANY PRIVATE KEY)

    2. 해석해보자면 TLS 인증서의 private key 를 로드할 수 없다는 것으로 보인다.

  3. 한참을 이리저리 방법을 찾다가 혹시 권한이 없나 싶어서 private key 에 권한을 주었다.

# docker logs [container] 
"nginx.conf" 40L, 1028B                                                                                                                   1,1           All
... [중략] ...
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/03/05 21:51:14 [emerg] 1#1: cannot load certificate key "/etc/letsencrypt/live/subway-mhson.kro.kr/privkey.pem": PEM_read_bio_PrivateKey() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: ANY PRIVATE KEY)
nginx: [emerg] cannot load certificate key "/etc/letsencrypt/live/subway-mhson.kro.kr/privkey.pem": PEM_read_bio_PrivateKey() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: ANY PRIVATE KEY)
# privkey.pem 의 권한 확인 결과 
-rw-rw-r-- 1 ubuntu ubuntu   54 Sep 27 22:09 Dockerfile
-rw-r--r-- 1 root   root   5599 Sep 27 22:27 fullchain.pem
-rw-rw-r-- 1 ubuntu ubuntu  155 Sep 27 22:10 nginx.conf
-rw------- 1 root   root   1704 Sep 27 22:28 privkey.pem     # 권한을 부여한다.

결과는? 정상적으로 동작된다.

PUBLIC-2a:~$ docker ps -a
CONTAINER ID   IMAGE                          COMMAND                  CREATED         STATUS         PORTS                                                                      NAMES
bc1885093f7d   nextstep/reverse-proxy:0.0.2   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   proxy

8. 추가적으로 읽어보면 좋을 글들

이번 과제를 진행하면서 읽어보았던 블로그 글들이다. 좋은 내용이 많다.

    • 인증서 내부의 구조를 자세하게 설명해준다.

9. 추가적으로 하면 좋은 것들

비록 나는 시간이 없어서 적용해보지 못했지만, 아래와 같은 설정들을 추가해보면 개발시나 운영시에 편리해진다.

9-1. [추가] 데이터베이스 테이블 스키마 버전관리

보통 운영 데이터베이스는 JPA등과 같은 ORM 을 사용하여 기존의 테이블을 변경하지 않는다. 데이터가 유실되거나 참조 무결성 제약 등으로 인해 어려움이 있기 때문이다. 그래서 보통은 로컬에서는 H2 와 같은 in-memory 데이터베이스를 이용하여 빠르게 개발을 하고, 운영 데이터베이스는 점진적으로 migration 을 해나간다.

이때, 운영 데이터베이스의 테이블 스키마에 대해서도 버전관리를 하는 것이 필요한데, 이때 사용하는 것이 바로 Flyway 이다.

flyway 를 연습하고자 한다면 아래를 따라 진행해본다.

    • docker/db/mysql/init에 dump 파일을 넣은 상태로 실행하면 자동으로 초기 데이터를 INSERT할 수 있다.

    • flyway는 V__[변경이력].sql의 형태로 resources/db/migration/ 경로에서 괸라한다.

    • 그리고 flyway_schema_history 테이블에 버전별로 checksum 값을 관리하므로 기존 sql 문을 수정해서는 안된다.

# 터미널에서 docker-compose.yml이 있는 위치로 이동한다.
$ cd docker
$ docker-compose up -d

* 기존 Database 존재시 flyway 적용 방법

# application.properties
spring.flyway.baseline-on-migrate=true
spring.flyway.baseline-version=2

이전에 database가 존재할 경우 baseline 옵션을 활용하면 특정 버전(V2__xx.sql 파일) 내용부터 적용이 가능하다.

9-2. [추가] 설정 별도로 관리하기

키, 계정정보, 접속 URL 등 설정 정보를 소스코드와 함께 형상관리를 하게 되면, 보안상 이슈가 발생할 수 있다.

보통의 경우는 어떻게 하는가?

  • Jenkins, Travis CI 등 배포 서버에 파라미터를 지정하거나, Spring Cloud Config, AWS service manager 등의 외부 서비스를 활용한다.

우리는 어떻게 할 것인가?

  • 우리는 private repository 를 활용하여 설정을 관리해보도록 한다.

  1. 우선, github private 저장소를 생성한 뒤, application.properties 와 같은 설정 파일을 올린다.

  2. $ git submodule add [자신의 private 저장소] ./src/main/resources/config
  3. 이후에 소스코드를 받을 때는 서브모듈까지 clone 해야한다.

    $ git clone --recurse-submodules [자신의 프로젝트 저장소]
  4. 설정 파일의 내용이 변경된 경우

    git submodule foreach git pull origin main
    
    git submodule foreach git add .
    
    git submodule foreach git commit -m "commit message"
    
    git submodule foreach git push origin main

9-3. [추가] 정적테스트(SonarLint)

  • Sonarqube / ESLint 등 정적 테스트, Maven / Gradle 등을 활용한 Build, JUnit 등을 활용한 동적 테스트 등을 통해 Code로 인해 발생하는 문제를 조기에 발견할 수 있습니다. 어떻게 하면 테스트 비용을 줄일 수 있을지 늘 고민해보자.

    • 정적 테스트를 통해 Coding Convention, 중복코드, 소스코드의 복잡도, 잠재적으로 버그 발생 가능성이 있는 코드, 테스트 커버리지 등을 파악할 수 있다.

9-4. [추가] 로컬테스트(MultiRun)

  • Multi Run 설정

    • IntelliJ -> Run -> Edit Configurations...

이 옵션을 붙이는 이유가 궁금하다면 참고

터미널 세션이 끊어질 경우, background로 돌던 프로세스에 hang-up signal이 발생해 죽는 경우가 종종 있다. 이 경우 명령어를 활용하여 실행하면 터미널 세션이 끊어져도 어플리케이션이 정상적으로 운영된다.

들을 활용하여 DNS 설정을 해본다.

혹시 도커가 익숙하지 않다면, 에서 간단한 명령어를 연습할 수 있다.

을 보고 docker log 을 읽는 방법을 배웠다.

를 통해 데이터베이스 스키마 관리 전략을 확인한다.

예제코드를 실행하기에 앞서, 를 다운로드한다.

를 통해 더 자세한 내용을 확인할 수 있다.

git의 을 활용하여 특정 경로에 private repository를 참조하도록 설정한다.

를 활용하면 정적테스트 구축비용을 줄일 수 있습니다.

로컬에서 서버를 띄울 때, IntelliJ의 플러그인을 활용하면 보다 손 쉽게 서버를 띄울 수 있다.

Multi Run 플러그인 설치

Docker 설정

NPM 설정

Multi Run 설정

🏰
tomcat 구동 시 /dev/random 블로킹 이슈
nohup
https://stackoverflow.com/questions/2541475/capture-sigint-in-java
무료 도메인 사이트
http://subway-mhson.kro.kr
도커 플레이그라운드
이 글
Let’s encrypt로 만든 인증서 살펴보기
[라인 개발블로그] 안전한 SSL/TLS를 운영하기 위해 알아야 하는 것들
예제 코드
도커
발표자님의 블로그
서브모듈 기능
SonarLint
Multirun
망 구성하기
배포하기
배포 스크립트 작성하기
PEM 키 생성하기
https://youtube.com/watch?v=4NB0NDtOwIQ&feature=shares