Droid Knights 2018

링크 : https://droidknights.github.io/2018/

일시 : 2018.04.22 09:00 ~ 18:00

장소 : 코엑스 컨퍼런스홀

간단하게 들었던 섹션 정리 및 자료 링크 취합입니다.

01. Track 1. No More Fragment, No More Activity

  • 발표자 : 정승욱 (GrabTaxi 안드로이드 개발자)
  • 발표자료 :

동남아 서비스로 국내보다 단말 저사양 및 파편화 현상이 심함.

해상도 대응이나 안드로이드 버전별 대응 등의 어려움이 있음.

각 국가별 개발팀이 분산되어 있으며, 30여명의 개발자로 팀 구성됨.

Activity나 Fragment 등의 사용없이 단일 Activity로 앱 구성.

서비스 모듈 별 관리를 위해 Router, Node 형태 도입.

Back키 처리나 스킴 처리 등의 대응 필요.

02. Track 1. Next Step Architecture

  • 발표자 : 남상균, 정현지 (NBT/캐시슬라이드 Chief Architect & 안드로이드 개발자)
  • 발표자료 :

오래된 앱을 유지하면서 시스템을 개선하기 위한 노력.

도메인 베이스의 의사결정이 개발 환경 등에도 영향을 미침.

안드로이드 API 최소버전도 최근에 들어서 상향 조정함.

Kotlin 전환 등의 노력들을 함.

03. Track 2. Best Practice on Android Instant Apps

  • 발표자 : 김종식 (원티드 안드로이드 개발자)
  • 발표자료 :

설치 없이 네이티브 앱 사용경험을 제공하는 인스턴트 앱 개발과정

Android Instant App FAQ (https://developer.android.com/topic/instant-apps/faqs.html?hl=ko)

  • 호환되는 기기 : Android 4.1(API 16) 이상 & Google Play서비스가 설치된 기기

  • 두 가지 다른 앱을 빌드해야 하나?

    하나의 프로젝트만 유지하면 가능. 두 가지 빌드 아티팩트인 설치 가능 APK와 인스턴트 버전을 생성하도록 프로젝트 구성하면 됨.

  • 어떤 Android API와 기능을 사용할 수 있나?

    Android Instant Apps 기능이 기존 Android 앱을 보완하기는 하나, 대체하지는 않음.

    동일한 Android API, 동일한 프로젝트, 동일한 소스코드를 사용하나 설치되지 않은 앱에 대한 사용자의 기대 사항에 맞지 않을 수 있는 일부 기능은 제한함. 예를 들어 백그라운드 서비스 사용이나 백그라운드 알림, 고유 기기 식별자에 액세스하지 못할 수 있음.

  • 사용자가 앱을 영구적으로 설치하도록 선택할 수 있나?

    Google Play 스토어에서 앱 다운로드하도록 허용 가능함. 다운로드 후에는 사용자가 그 환경을 떠난 후에도 앱이 휴대폰에 남아있음.

  • Permission은 어떤식으로 작동?

    Android 6.0 (API 23)에 새로 추가된 런타임 권한 모델을 사용함.

  • Instant Apps 게시는?

    기존의 Android 앱과 유사하게 Google Play Developer Console을 통해 게시 가능

참조 링크 : https://tech.wanted.co.kr/android/2018/01/30/android-instant-app.html

gradle 이나 AndroidManifest 설정은 위 링크를 참조하면 됨.

인스턴트 앱을 위해 InstantApps 라는 클래스가 추가되었으며, isInstantApp(Context context) 메서드로 현재 프로세스를 확인할 수 있음.

배포시 Holdback 설정을 통해 0과 1 사이의 값을 설정하여 인스턴트 앱 출시 비중을 정함.(0일 경우 전체를 인스턴트 앱으로 출시)

프로덕션 출시가 아니라면 10MB 까지 업로드가 가능했으나, 프로덕션 출시시에는 4MB를 넘기면 안됨.

기본 support 라이브러리들도 용량을 먹기 때문에 실제 사용 가능한 용량은 적을 수 있음.

04. Track 2. Kotlin 코루틴은 어떻게 동작하는가?

일반 subroutine

  • 단일 지점에서 시작 -> 특정 지점에서 종료

Coroutine

  • 단일 지점에서 시작 -> 임의 지점에서 멈춤 -> 해당 지점에서 재개 -> 특정 지점에서 종료

Sequencial code를 통해 non-blocking 코드를 작성하기 위한 수단으로 Coroutine 제공

suspend는 중단/재개 지점을 위한 continuation을 매핑하기 위한 키워드

호출한 대상/어디까지 실행했는지/어떤 값들을 가지고 있는지 등에 대한 상태를 Continuation Passing Style로 처리됨.

각 코드 라인은 Labeling되어 switch문을 통해 처리되며, Statemachine, Continuation, 상태 저장/복원 등으로 동작함.

UI 쓰레드에서 실행됨.

05. Track 2. Google Mobile Vision과 OpenCV로 card.io를 확장한 범용 카드번호인식 개발

LINE에서 사용 중인 신용카드 인식 오픈소스인 card.io가 양각되어 있는 신용카드만 인식하는 문제 해결 과정.

LINE 캐릭터 카드 같은 경우들을 인식을 못함.

Google Mobile Vision과 OpenCV를 활용하여 일반 프린팅된 카드 번호 및 멤버쉽 카드 그리고 바코드를 인식하는 라이브러리를 개발함.

card.io 관련 여러가지 이슈들

  • 작은 해상도(바코드 인식에 맞는 사이즈가 안나옴)
  • 양각 문자만 인식(Google Mobile Vision을 활용해보았으나, 너무 많은 문자열이 인지됨.)
  • 카드 스캔시 영역 설정시 퍼포먼스 이슈
  • 문자열 인지 후 카드번호 얻는 방식(여러 문자열이 나열되는 경우들. 예를들어 자동차 번호판 인식같이)
  • Java와 NDK 간 속도차이는 최소 5배 이상은 차이났음.

##06. Track 2. Travis-ci를 이용한 CI/CD와 도커를 이용한 Jenkins for Android 구성하기

CI(Continuous Integration) : Build, Test를 실시하는 프로세스를 상시로 실시해줌. 지속적 통합.

CD(Continuous Delivery or Continuous Deploy) : 소프트웨어를 빠르고 주기적으로 빌드하고 테스트하고 출시하는 것이 목표. 지속적 배포.

이를 수동으로 하는 것은 자동차 스틱을 운전하는 것이나 돌로 탑쌓기와 유사함.

CI툴들을 사용해 피드백을 받고 스크립트로 자동화까지 처리한다면 자율주행같이 사용할 수 있음.

Travis CI를 이용한 CI/CD

Travis-CI : Github에서 진행되는 오픈소스 프로젝트. Private repository는 유료.

  • 장점
    • 손쉬운 프로젝트 설정 및 서비스 연동(Github와 seamless한 통합)
    • 오픈소스 프로젝트시 무료
    • 전용 CI/CD 서버 필요하지 않음.
    • 모든 Job이 독립적 동작
    • 빌드 메트릭스 제공
  • 단점
    • 제한된 옵션 제공 (Site GUI 제한적)
    • 느린 속도
    • Private Repository는 유료

Jenkins for Android using Docker

Jenkins : 다양한 시스템에서 사용 가능. 다양한 플러그인. 다양한 작업 모드 및 조건의 빌드 가능

  • 장점
    • 무료
    • 사용자 정의 옵션
    • 방대한 양의 플러그인
    • 다양한 적용사례 및 풍부한 레퍼런스
    • Remote access API 제공
  • 단점
    • 별도 서버 필요
    • 시스템 구성 및 사용자 정의 시간이 오래 걸릴 수 있음

07. Track 1. Android Test

  • 발표자 : 정경호 (에그번 안드로이드/서버 개발)
  • 발표자료 :

개발자들은 테스트를 피할 수 없음.

유닛 테스트도 작성이 어려운 경우가 많음.

서비스 테스트부터라도 작성을 해야 함.

UI 테스트도 할 수 있음.

패턴도 적용해야 함.

아무튼 해야 함!!!!

08. Track 1. 내가 안드로이드 개발자가 되었을 때 아무도 알려주지 않은 것들

안드로이드 개발자가 걷는 길

초보 모바일 개발자일 때 어려움들

  • Device/version fragmentation
  • 비동기
  • Life Cycle
  • 구글의 신기능

안드로이드 개발자가 되었을때 아무도 알려주지 않았던 것들

  • Clean Architecture
    • 하라는 건 많지만 제대로 쓰는 사람은 별로 안보임.
  • MVVM
    • 쓰면 좋다는데 복잡하고 예제들이 제 각각임.
  • MVP
    • MVVM 보다는 쉬운 것 같지만 진행하다보니 또 다른 컨트롤러를 만드는 기분임.
  • RxJava
    • 어렵고 헷갈리고, 자매품 LiveData는 좀 쉽지만 애매함.
  • Dependency Injection
    • 처음엔 쉬운 것 같은데 끝없는 decision making의 연속. 특정 인스턴스에 대한 injection을 어떻게 해야 효과적인지 헷갈림.
  • TDD (Test-Driven Development)
    • 유닛 테스트 튜토리얼들 중 실제 상용 프로젝트 수준의 유닛 테스트를 만드는 법을 알려주는 건 없음.

위의 것들을 통해 나타나는 전형적 증상

  • 비관주의 : 이 또한 지나가리
  • 팔랑귀 증후군 : 당장 해보자
  • 툴 만능주의 : 툴과 라이브러리 사용능력이 실력이다?
  • Low-hanging fruit : 쉬운 문제에만 집착

중요한 스킬

  • Solution Provider

    • 알고리즘에 대한 깊은 이해
    • 개발 언어의 semantics의 깊은 원리와 언어 설계 철학에 대한 이해
    • Dalvik의 동작 원리 이해
    • Activity/Fragment 중요 동작을 플랫폼 코드 레벨에서의 이해
    • 안드로이드가 화면을 렌더링 하는 매커니즘의 이해
    • 등등등
  • Architect

    • 내 프로젝트를 간단한 README.md 파일 외에 다른 개발자에게 인수인계할 수 있음.

    • 코드를 1년 뒤에 봤을때 바로 이해 가능

    • 큰 규모의 구조 수정도 1~2일 내에 해낼 수 있을 정도로 유연한 구조

    • Jr 엔지니어에게 후속 코딩을 안심하고 몽땅 떠넘겨도 될 수준으로 기본 구조가 견고하게 작성.

      (잘못된 방식으로 구현하기가 매우 어렵도록 구조를 만듬)

중급 개발자를 위한 안내

  • 시작이 반
  • 공유의 힘 (주관이 들어가면 스스로에게도 독자에게도 도움이 됨)
  • 일본의 경우
    • 블로그를 통한 공유가 일상화
    • 주로 지역 단위의 세미나인 공부회
    • Moku-moku meeting(묵묵한 미팅?) : 그냥 각자 코딩 모임. 국내 모각코 같은...
    • Network Party : 자기가 구현한 아키텍처, 테스트 등 구체적인 부분에 대한 지식 교환.

패턴 사용에 따른 경험들

MVP & MVVM

  • MVC is not evil

    • 모바일 환경의 문제 : 비동기 처리, 라이프 사이클 처리
    • 안드로이드의 View-Controller 분리가 애매
    • 그로 인한 총체적 난국 : 최악의 가독성, 각 클래스들의 너무 많은 역할들.
  • MVP

    • 안드로이드 초기부터 구전으로 전해져 왔던 아키텍처
    • 장점
      • Fat activity/fragment 방지
      • 역할 분리로 인해 소스 가독성 및 품질 상승
      • 플랫폼 의존적인 UI 처리는 View쪽으로 분리하여 Presenter는 쉽게 테스트 작성 가능
      • Clean Architecture와 1:1 mapping 가능. CA 그대로 채용하면 설계 관련 노력도 최소화.
  • What is not MVVM?

    • MVVM의 특징이 Life Cycle은 아님.

    • Data Binding : 필수가 아님. 다만 사용하면 생산성에 확실한 도움이 됨.

    • RxMVVM : 역시 필수는 아니지만 없이는 매우 불편함.

    • ViewModel 용어에서 오는 혼란

      • Model과 같이 작은 단위로 쪼개져있지 않음. 통신에다 별게 다 들어간 형태임.
      • View를 위한 Model (Entity) 라는 개념 & 단방향 Presenter라는 두개의 개념임.
      • Presenter와 매우 유사하나 ViewModel은 View를 제어하지 않음.
      • View는 ViewModel을 호출하되, 결과는 Callback/Observable 형태로 받음.

MVVM vs MVP

둘 다 훌륭한 구조이며, 압도적 우위는 없음. 프로젝트 성격에 따라 다르게 받아들여질 수 있음.

MVP의 비교우위

  • 시작이 쉬우며, Legacy Code의 분량이 많거나 구조 개선에 주어진 시간이 짧은 경우 MVP가 유리
  • RxJava를 안 써도 훌륭한 구조를 만들 수 있음.

MVVM

  • 초기 진입장벽은 있음.
  • View 상태 관리가 복잡한 경우 ViewModel에서의 처리가 자연스러움
  • AAC (Android Architecture Component 후광 효과)
  • Cross Platform 구현에 좀 더 유리 (Kotlin을 Swift로 옮기는 것만으로도 View 이외의 소스의 70% 이상을 재사용 가능)

MVVM - MVP 공통의 장점

  • 개발 속도가 몇 배는 빨라짐 (단 개인차가 있으며, 초기 2~3주간 개발 속도는 몇 배는 느려질 수 있음)
  • 코드 변경에 대한 두려움이 거의 없어짐
  • 기획의 급격한 사양 변경에도 대응 가능
  • 1년 뒤에 코드를 다시 봐도 즉시 어디를 고쳐야할지 알 수 있음.
  • 다른 엔지니어에게 코드를 보여줘도 쪽팔리지 않음!!!

MVP/MVVM at Scale

프로젝트 사이즈가 점점 커지면서 위의 기대와는 달리 지저분해짐.

  • Fat Presenter
  • 테스트 케이스 만들기가 어려워짐
  • 코드가 지저분함. Activity Manager 같은 게 하나 늘어나기만 한 느낌
  • 주된 원인 중 하나는 Presenter를 View와 명확히 분리하지 않은 것

해결책

  • View와 Presenter를 잘못 구현하기 어렵도록 하는 장치 필요.
  • View는 이벤트를 발생시키고, UI를 그려주는 역할만 담당, 비즈니스 로직이나 모델이 끼어들 여지를 차단.
  • Presenter가 View의 세부 사항을 알 수 없도록 P는 View를 추상화 시킨 형태로만 참조하도록 만듦

MVP: Contract Pattern

  • View Interface를 통한 분리
  • 필요한 경우 Presenter까지 Interface화 시킴

MVVM Best Practice: Passive View

  • View는 (플랫폼 의존적인) 그리기 이외에는 아무것도 알 수 없도록 함
  • Lighter View, Fatter ViewModel이 되나 더 나은 구조로 가기 위한 중요한 가교

MVVM is not an architecture.

비즈니스 로직의 비대화

  • Presenter나 ViewModel의 도메인 로직이 감당할 수 없는 크기가 되는 상황

  • Single Responsibility Principle 적용

    • 모범 답안 : Clean Architecture!
    • Presenter에서 도메인 로직을 분리 가능
    • Data 계층의 세분화를 통해 더욱 추상화된 형태의 구조 가능

Clean Architecture

기승전CA?

장점

  • Presenter/Domain/Data 계층의 분리로 인해 전체 로직의 흐름이 일목요연해짐. 가독성 급상승.
  • 특정 클래스가 비대해지는 것을 방지
  • 각 Layer 간 구분이 명확하므로, 영향 범위도 명확
  • 단 클래스 량이 급격히 증가 -> 한번에 구현하려 하면 개발속도 저하와 버그 양산 야기
    • CA가 익숙하지 않거나 경험이 없는 경우 모든 걸 따라할 필요는 없음
    • 프리젠테이션 로직의 합리화부터 시작
      • View - ViewModel/Presenter - Repository - Model (Entity)
    • 도메인/데이터 로직은 필요에 의해 점진적으로 하는 것이 합리적
  • 자동 생성 플러그인 : https://github.com/kiuchikeisuke/Android-Studio-CleanArchitecture-template-forKotlin
    • RxJava, Dagger, Retrofit, AAC, Presenter/ViewModel 코드까지 몽땅 만들어 줌
    • Swagger 지원으로 REST API call 인터페이스도 자동으로 만들어 줌

몇 가지 난제들...

구조의 철학적 문제 : Presenter의 비즈니스 로직과 Use Case의 비즈니스 로직의 차이점?

  • 도메인 로직이 Use Case에 들어감
  • 사업부 사람들도 알고 있어야 하는 로직이라면 도메인 로직

RecyclerView in MVP

Presenter로 RecyclerView - Adapter 대하는 것은 까다로운 문제임

  • Activity/Fragment가 (Presenter의 명령을 받아) Adapter를 제어 - 단순한 패턴의 리스트에는 효과적
  • Adapter와 매핑되는 Presenter를 구현
  • 개별 item과 각각 1:1 매핑되는 작은 Presenter를 구현

RecyclerView in MVVM

Presenter에 비해선 단순한 문제. Data binding으로 그대로 ViewModel 연결 가능

  • 복잡한 경우가 아니라면 Adapter에 ViewModel 연결

  • 복잡하다면 각 Item과 매핑되는 작은 ViewModel 구현

    • 이 경우 ViewModel은 View를 위해 가공된 Model이기 때문에 어떤 의미에서 진정한 ViewModel
    • AAC를 이용해 small ViewModel을 생성시 provider에 파라미터를 별도 지정해야 함. 차라리 상위 ViewModel이 생성하는 게 더 좋을 수 있음.

경험

서비스 중인 앱을 단기간 내에 리뉴얼 개발하면서 얻은 결과

  • 비즈니스 관점에선 앱 구조 개선은 큰 가치가 없음. 새로운 기능들을 얼마나 빠른 속도로 넣느냐..
급한 일급하지 않은 일
중요한 일신 기능 구현
버그 수정 + 앱 안정화
Java -> Kotlin 변환
ViewModel or Presenter 전환
오래된 라이브러리 갈아타기
중요하지 않은 일각종 회의 참석이상한 변수명, 메소드명 변경
들여쓰기 변경
기타 스타일 수정

전리품

기본 : 출입태그, 티셔츠, 밀스 그레인, 그래놀라바, 에코백, 뱃지, 물, 스티커

네이버 : 노트 or 펜

쿠팡 : 수첩 커버 및 수첩 세트

하이퍼커넥트 : 티셔츠, 스티커

리멤버 : 샤오미 보조 배터리

참고자료

https://yands11.github.io/droid-knights/

https://blog.naver.com/PostView.nhn?blogId=cenodim&logNo=221258932085&redirect=Dlog&widgetTypeCall=true&directAccess=false

Docker 정리

Docker 란?

2013년에 등장한 새로운 컨테이너 기반 가상화 도구

계층화된 파일 시스템을 사용해 가상화된 컨테이너의 변경사항을 추적 및 관리

컨테이너 특정 상태를 항상 보존해두고, 필요할 때 언제 어디서나 실행할 수 있도록 도와주는 도구


기존 가상머신

가상 머신은 격리된 환경을 구축해준다는 데서 매력적

실제 배포용으로 쓰기에는 성능 면에서 불리한 도구

운영체제 위에서 또 다른 운영체제를 통째로 돌리는 구조라 리소스를 비효율적으로 활용하게 됨

Docker

어느 플랫폼에서나 재현가능한 어플리케이션 컨테이너를 만들어주는 것을 목표함

LXC(리눅스 컨테이너)라는 개념에서 출발함으로써 특정 리눅스 배포판에서 사용 가능

가상 머신이라고 하기보다는 격리된 환경을 만들어주는 도구

컨테이너와 이미지의 차이와 Dockerfile 만든 법 등을 익히는게 중요함

Docker에서 말하는 장점들

  • 유연성 (Flexible) : 가장 복잡한 애플리케이션조차도 컨테이너화할 수 있습니다.
  • 경량 (Lightweight) : 컨테이너는 호스트 커널을 활용하고 공유합니다.
  • 교환 가능 (Interchangeable) : 업데이트 및 업그레이드를 즉시 배포 할 수 있습니다.
  • 휴대성 (Portable) : 로컬로 구축하고, 클라우드에 배치하고, 어디서나 실행할 수 있습니다.
  • 확장성 (Scalable) : 컨테이너 복제본을 늘리고 자동으로 배포 할 수 있습니다.
  • 스태킹 (Stackable) : 서비스를 세로 및 가로로 쌓을 수 있습니다.


Docker 제품군

Community Edition (CE)

Docker를 시작하고 컨테이너 기반 앱을 실험하려는 개발자 및 소규모 팀에 이상적 (무료)

두 가지 업데이트 채널을 가짐

  • Stable : 분기마다 안정적인 업데이트 제공
  • Edge : 매월 새 기능 제공

Enterprise Edition (EE)

업무용 응용 프로그램 제작, 배송 및 실행하는 엔터프라이즈 개발 및 IT팀을 위한 설계 (유료)

Docker CE와 EE 간 비교 이미지 (출처: Docker Docs, https://docs.docker.com/install/)

지원 플랫폼

Desktop

Cloud

Server

Docker EE

Docker CE

Docker 설치하기

Ubuntu의 경우 Docker CE설치시

OS requirements (18년 3월 22일 기준)

Docker CE는 아래 버전 중 하나의 64비트 버전이 필요함

  • Artful 17.10 (Docker CE 17.11 Edge and higher only)
  • Xenial 16.04 (LTS)
  • Trusty 14.04 (LTS)

Docker CE는 Ubuntu에서 x86_64armhfs390x (IBM Z), and ppc64le (IBM Power) 아키텍쳐를 지원함

(ppc64le and s390x limitations: IBM Z 및 Power 아키텍쳐 패키지는 Ubuntu Xenial 이상만 사용 가능)

Docker CE 설치

  • Docker repositories를 설정 후 설치
  • DEB 패키지 다운로드 후 수동 설치
  • 스크립트를 사용하여 설치

Docker Storage를 설정 후 설치 방법

## 패키지 업데이트
    $ sudo apt-get update
    ...
    ## HTTPS를 통해 repository를 사용할 수 있도록 패키지 설치
    $ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
    ...
    ## Docker 공식 GPG 키 추가
    ## Key fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 확인
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    $ sudo apt-key fingerprint 0EBFCD88
    pub   4096R/0EBFCD88 2017-02-22
    Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
    uid                  Docker Release (CE deb) <docker@docker.com>
    sub   4096R/F273FCD8 2017-02-22
    ...
    ## stable repository 사용시 아래 커맨드 추가
    ## arch 값을 amd64, armhf, ppc64el, s390x 등으로 맞춰서 사용
    $ sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
       $(lsb_release -cs) \
       stable"
    ...
    ## 패키지 업데이트
    $ sudo apt-get update
    ...
    ## 옵션 1. Docker CE 최신 버전 설치
    $ sudo apt-get install docker-ce
    ...
    ## 옵션 2. Docker CE 특정 버전 설치
    $ apt-cache madison docker-ce
    docker-ce | 17.12.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
    $ sudo apt-get install docker-ce=<VERSION>
    ...
    ## hello-world 이미지를 실행하여 Docker CE가 올바르게 설치되었는지 확인
    $ sudo docker run hello-world

다른 OS에서 Docker 설치

Docker 제거

Docker CE 제거

Docker CE 패키지 제거

$ sudo apt-get purge docker-ce

Image, Container, Volume, 사용자 정의 구성파일 등은 자동으로 제거 안됨.

모든 데이터를 삭제하려면 아래처럼 실행

$ sudo rm -rf /var/lib/docker

Docker Image

이미지는 추상적인 개념이며, 이미지를 기반으로 생성된 컨테이너가 실행됨

이미지는 코드, 런타임, 도서관, 환경 변수 및 구성 파일 등 응용 프로그램을 실행하는 데 필요한 모든 것을 포함하는 실행 가능한 패키지

Docker Image 관련 명령어

docker images

현재 시스템에서 사용 가능한 이미지 리스트

$ docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    hello-world         latest              f2a91732366c        4 months ago        1.85kB

docker pull 

이 명령어를 사용하면 docker.io의 공식 저장소에서 이미지를 다운로드

공식 저장소에 있는 이미지 정보들은 https://hub.docker.com/explore/에서 확인 가능

$ docker pull ubuntu
    Pulling repository ubuntu
    04180f9bd8a6: Download complete
    1e548c932d40: Download complete
    ...

Docker Container

컨테이너는 기본적으로 리눅스에서 실행되며, 다른 컨테이너와 호스트 시스템의 커널을 공유

더 많은 메모리를 사용하지 않고 개별 프로세스를 실행하여 가볍게 만듬

Docker Container 관련 명령어

docker run

특정 이미지로 컨테이너 생성 및 실행

$ docker run -i -t ubuntu:12.04 /bin/bash
    root@8bfd70fe7392:/#

docker ps

실행 중인 컨테이너들을 출력 (전체 볼때는 docker ps -a)

$ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
    0fae5858c9c0        ubuntu:12.04        /bin/bash           8 seconds ago       Up 7 seconds

    PORTS               NAMES
    sleepy_nobel

docker start <Container name/id>

생성되어 있는 컨테이너를 실행

$ docker start a37f1348c4c4
    a37f1348c4c4
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
    a37f1348c4c4        hello-world         "/hello"            25 minutes ago      Up 7 seconds

    PORTS               NAMES
    sleepy_nobel

docker stop <Container name/id>

실행 중인 컨테이너를 정지

$ docker stop a37f1348c4c4
    a37f1348c4c4
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
    a37f1348c4c4        hello-world         "/hello"            25 minutes ago      Exited(0) 25 minutes ago

    PORTS               NAMES
    sleepy_nobel

docker exec -it <Container name/id>

실행 중인 컨테이너에 진입시

쉘이 안떠있는 컨테이너일 경우 : docker exec -it <Container name/id> /bin/bash

$ docker attach e2af613
    root@e2af61348652:/#

docker stop $(docker ps -a -q)

실행 중인 컨테이너들 전체 정지시

$ docker stop $(docker ps -a -q)
    a37f1348c4c4
    e2af6134a1s2
    ...

참고 자료

Docker 공식 문서 : https://docs.docker.com/

nacyout님의 "도커(Docker) 튜토리얼:깐 김에 배포까지" : http://blog.nacyot.com/articles/2014-01-27-easy-deploy-with-docker/

(18년 3월 22일 기준 정리)


지인의 추천으로 아래 링크들을 보게 되었고, 공감되는 바가 많아 링크 및 개인적인 요약내용을 올려봅니다.


이 글에서 지적하는 Expert Beginner의 문제점들이 저에게서도 보이는 걸 많이 느꼈답니다.


나태해지고 정적으로 머물러 있었던 저에게 필요한 글이었던 것 같습니다.


https://medium.com/@jwyeom63/더-이상-배우려-하지-않는-개발자-expert-beginner의-등장-dd40c40aeedf


https://medium.com/@jwyeom63/소프트웨어-집단의-부패-expert-beginner의-유산-9d226b6ebde2


Novice(*역:초심자)

Advanced Beginner(*역:숙련된 초심자)

Competent(*역:실력을 갖춤)

Proficient(*역:능숙함)

Expert(*역:전문가).


무언가를 배울 때 사람은 “큰 그림을 보지 못하고 정해진 규칙만 따라가기” 에서 시작해서 “직감적으로 규칙 전반을 넘어선 큰 그림을 볼 수 있는 상태”에 도달하게 된다는 것


Advanced Beginner ----------> Competent

                                └-> Expert Beginner



10년의 경험인가 아니면 같은 경험을 10년동안 한것인가


이들이 Expert Beginner 단계로 자연스럽게 입장하는 것을 막을 수 있는 유일한 방법은 피어리뷰(peer review)와 개발자 커뮤니티와의 교류 뿐이다.


“Expert Beginner”라는 용어를 자신의 테두리가 곧 전체의 테두리라고 굳게 믿고, 지역적 최고점에 도달한 후 배움을 멈춘 개발자들을 표현하기 위해 사용했다.

자신들이 여태까지 노출되었던 환경이 곧 전체이자 유일한 방법이라고 생각할 정도로 시야가 좁다는 뜻이다.

그는 장님들만 있는 거리의 외눈박이이며, 굉장히 현실적이고 동시에 불운하게도, 지역적(local) 전문가이다. 

쉽게 성공할 수 있고, 요구되는 기준이 낮으며, 진짜 전문가들은 존재하지 않고, 경쟁도 없으며, 외부와의 교류도 없다.


Expert Beginner는 자신의 행동과 본보기로 새로운 Expert Beginner들을 만들어내고 이는 곧 Expert Beginnerism의 문화를 생성하는 것이다.


Expert Beginner들은 사실은 인격적인 문제가 없을 수도 있다. 나는 이것이 외부와 격리된 환경, 낮은 기대치, 그리고 실제로 효율성 산출이 불가능한 그저 그런 수행능력에 대한 꾸준한 보상이 만들어낸 자연스러운 결과라고 생각한다.


건강한 겸손함과 지속적으로 성장하기 위한 노력을 겸비하고, 객관적 수치들을 주관적인 고려사항들보다 우선순위에 둔다면 Expert Beginner로부터 충분히 거리를 둘 수 있을 것이다.


이 리스트는 우선적으로는 매니저와 팀 리더들을 위한 것이지만, 팀 멤버들도 충분히 이러한 변화를 일으킬 수 있다. 차이점은 한쪽은 바로 실행에 옮길 수 있고, 다른 쪽은 관리자들을 설득해야 한다는 점이다.

가능하다면, 몸소 실천해서 보여줌으로써 주도 해보라. 만약 이것이 모두 소용이 없다면, 내 개인적인 생각으로는 이미 가망이 없는 것이니 가능성이 있는 곳으로 떠나기 바란다. 


Expert Beginner는 절대로 “모르겠다”라는 답을 하지 않는다. 이는 곧 기술을 배우고 있는 사람과 자신이 이미 알건 다 안다고 생각하는 사람 사이의 중요한 차이이다.


C9 VNC 사용시에 한글 세팅을 위해 참고했던 링크 및 정보들입니다.

C9 VNC에서 크롬 설치하여 사용할때 유용합니다.


1. 관련 스크립트 설치하기. 

https://github.com/noobkilervip/cloud9-vnc


2. 한글 세팅하기. 

http://ledgku.tistory.com/24


$ sudo apt-get install ibus ibus-hangul

$ ibus-setup

1)한글키보드 추가.

Input Method -> Customize active input methods -> Select an input method -> Korean - Hangul -> add

2) 단축키 변경.

Keyboard Shorcuts -> Shif Space로 변경.

3) Use custom font

NanumGothic 세팅.


3. 크롬 세팅하기.

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb 

sudo apt-get install libxss1 libgconf2-4 libappindicator1 libindicator7 

sudo dpkg -i google-chrome-stable_current_amd64.deb

'IT > 각종 환경설정' 카테고리의 다른 글

DokuWiki 설정하기  (0) 2018.03.12
[Docker] Ruby On Rails 이미지 만들기  (0) 2017.12.28
TISTORY 포스팅에서 코딩 스타일 입히기  (0) 2017.12.12

그냥 개인 PC에서 DokuWiki를 사용할 일이 있어서 설정한 부분이 있어 정리합니다.


1. IIS 활성화(Windows 7)

  - 제어판 -> 프로그램 및 기능

  - 좌측 "WIndows 기능 사용/사용 안함" 선택

  - 인터넷 정보 서비스 "World Wide Web 서비스", "웹 관리 도구" 선택


  - 내컴퓨터 우클릭 -> 관리 ->  서비스 및 응용 프로그램

  - Default Web Service 확인

  - 참조 : http://h5bak.tistory.com/140

  

2. DokuWiki 설정

  - PHP 다운 후 압축해제(http://windows.php.net/download/), 5.6버전 non-thread safe 권고(7버전에서 실패했음)


  - php.ini-production 복사 후 php.ini로 변경


  - php.ini 값 변경

fastcgi.impersonate = 1

fastcgi.logging = 0

cgi.fix_pathinfo=1

cgi.force_redirect = 0

  - CGI 설정. 

"Windows 기능 켜기/끄기"에서 CGI 선택되어 있어야함.

"서비스 및 응용프로그램"에서 최상위에서 "처리기 매핑"에서 아래 내용으로 추가

요청 경로: *.php

모듈: FastCgiModule

실행파일 옵션: C:\[Path to PHP installation]\php-cgi.exe

이름: PHP_via_FastCGI 

"요청제한" -> "파일 또는 폴더"


"서비스 및 응용프로그램"에서 최상위에서 "MIME 형식"에서 아래 내용으로 추가

파일이름 확장명 : .php

MIME 형식 : application/php

IIS 재시작  

  - ISAPI 설치(https://www.iis.net/learn/application-frameworks/install-and-configure-php-applications-on-iis/using-fastcgi-to-host-php-applications-on-iis)


  - DokuWiki 다운 후 압축 해제(https://www.dokuwiki.org/dokuwiki)


  - web.config 생성 후 아래 소스 저장


<?xml version="1.0" encoding="UTF-8"?> 

<configuration> 

    <system.webServer> 

        

        <security> 

            <requestFiltering> 

                <filteringRules> 

                </filteringRules> 

                <denyUrlSequences> 

                    <add sequence="/data/" /> 

                    <add sequence="/conf/" /> 

                    <add sequence="/bin/" /> 

                    <add sequence="/inc/" /> 

                </denyUrlSequences> 

            </requestFiltering> 

        </security> 

    </system.webServer> 

</configuration>


  - "서비스 및 응용프로그램"에서 dokuwiki 위치 설정

  - "서비스 및 응용프로그램"에서 dokuwiki 선택 후 "사용 권한 편집"에서 보안 선택

  - "그룹 또는 사용자 이름" 편집에서 "IUSR" 추가 후 모든권한 추가

  - dokuwiki 설치(ex. http://localhost/dokuwiki/install.php)

  - dokuwiki 접속(ex. http://localhost/dokuwiki/index.php)

  - 참조 : https://www.dokuwiki.org/install:iis

  - 참조 : http://aspdotnet.tistory.com/1208


3. 환경설정

  - admin 접속 후 "관리" -> "환경설정"  

  - "사이드바 문서이름"에 sidebar 입력

  - "디렉터리 만들기"/"파일 만들기"에 0755 입력

  - "멋진 URL 사용"에 "도쿠위키 내부" 선택

  - "URL에서 이름공간 구분자로 슬래시 사용"에 체크

  - dokuwiki/inc/init.php에서 시간설정

date_default_timezone_set('Asia/Seoul');

  - 특정 확장자를 가진 파일의 업로드를 허용하려면, DokuWiki가 설치된 디렉토리의 conf/mime.conf = DOKU_CONF/mime.conf 파일에 확장자를 추가해줘야 함.

exe     application/octet-stream

msi     application/octet-stream


  

4. 플러그인 설치

  - 각 플러그인 다운 후 압축해제하여 

  - fontcolor plugin

  - fontsize2 plugin

  - indexmenu plugin

http://localhost/dokuwiki/doku.php/sidebar 에서 아래 내용으로 문서편집

{{indexmenu>.#1|js}}

  

루비앤레일즈는 기본적으로 MVC 패턴을 따르며, 이에 맞춰 웹 서비스가 가능합니다.


Cloud9 에서 프로젝트를 생성 후 간단한 페이지를 작성해 보겠습니다.


작업은 1. 프로젝트 생성 -> 2. 라우트 설정 -> 3. 컴포넌트 생성 -> 4. 컨트롤러 작성 -> 5. 뷰 작성 등으로 진행됩니다.


1. C9 프로젝트 생성


1.1 C9 로그인 후 Workspaces 에서 Create a new workspace 를 선택합니다.



1.2 Workspace 정보 입력 후 Ruby on Rails 템플릿을 선택합니다.



1.3 C9 프로젝트 생성 완료 화면입니다.



2. 환경설정


라우트에 주소규칙을 설정할 수 있습니다. config/routes.rb 파일에 아래를 참고하여 주소규칙을 작성해봅니다.

Rails.application.routes.draw do
  # get "/" => "<<컨트롤러>>#<<액션명>>" # "/" 로 접속시 <<컨트롤러>>의 <<액션명>> 실행
  # get "/" => "member#login" # "/" 로 접속시 member 컨트롤러의 login 액션 실행
  get "/member/login" => "member#login" # "/" 로 접속시 member 컨트롤러의 login 액션 실행
end


3. 컴포넌트 생성


Cloud9 bash 창에서 아래 커맨드로 컴포넌트 생성할 수 있습니다.

rails generate controller <<컴포넌트명>>  #<<컴포넌트명>> 컴포넌트 생성
rails g controller <<컴포넌트명>>  # 위와 동일
rails g controller Member   # Memeber 컴포넌트 생성


실제 컴포넌트 생성 결과입니다.

$ rails g controller Member   # Memeber 컴포넌트 생성
Running via Spring preloader in process 2371
      create  app/controllers/member_controller.rb     # 컨트롤러
      invoke  erb
      create    app/views/member                            # 뷰 경로
      invoke  test_unit
      create    test/controllers/member_controller_test.rb  # 컨트롤러 테스트
      invoke  helper
      create    app/helpers/member_helper.rb           # 헬퍼
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/member.coffee  #자바스크립트
      invoke    scss
      create      app/assets/stylesheets/member.scss   # 스타일시트


4. 컨트롤러 작성


config/routes.rb 에 작성하였던 컨트롤러에 액션을 추가해 보겠습니다.


app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.

class MemberController < ApplicationController
  def login
  end
end


5. 뷰 작성


이제 컨트롤러의 액션에 해당하는 뷰를 작성해 보겠습니다.


app/views/member/login.html.erb 파일을 생성 후 아래와 같이 작성해 봅니다. (파일명을 액션명과 맞춰줘야 합니다.)

<h1>Log In@@@</h1>



6. 결과 보기 및 다양한 출력 방법


지금까지 프로젝트 생성 후 라우트 설정을 하였고, 컴포넌트를 생성하여 컨트롤러와 뷰를 작성하였습니다.


이제 그 결과를 확인해 볼 차례입니다.


아래 C9 Workspace에서 Run Project 를 통해 서버를 구동시켜봅니다.



그리고 서버 구동 후 아래 링크들을 열어 결과를 확인해 볼 수 있습니다.



6.1 그 결과는 아래와 같습니다.



6.2 이번에는 컨트롤러에서 직접 내용을 출력해보겠습니다.


app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.


class MemberController < ApplicationController
  def login
    render text: "Log In!!!"  # 뷰에서 "Log In!!!" 문구 출력
  end
end

그 결과를 확인해봅니다.



6.3 이번에는 뷰 파일명을 달리하여 컨트롤러 액션에서 직접 지정하여 출력해보겠습니다.


app/views/member/test_login.html.erb 파일을 생성 후 아래와 같이 작성해 봅니다.

<h1>Log In Test@@@</h1>


그리고 app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.

class MemberController < ApplicationController
  def login
    render "test_login" # test_login 뷰 지정
  end
end


그 결과를 확인해봅니다.



이렇게 Cloud9 과 Ruby on Rails를 통해 간단하게 페이지를 작성해 보았습니다.


MVC 패턴 중 View 와 Controll 만을 사용하여 만들어 보았습니다. 


생각보다 어렵지 않게 페이지가 만들어 지는 것을 확인할 수가 있네요.


이상 간단 시식을 마칩니다.










'IT > ETC' 카테고리의 다른 글

[SonarQube] SonarQube & Jenkins 이야기  (0) 2020.02.14
[SonarQube] SonarQube 도입기?  (0) 2020.02.07
[Docker] Docker란?  (0) 2018.03.23
Expert Beginner란...  (0) 2018.03.12

개인적으로 Cloud9 에서 작성한 Ruby On Rails 어플리케이션을 Docker로 돌려보기 위해 작업했던 내용들을 작성해봅니다.


사전에 Cloud9 에서 작업한 Ruby On Rails 프로젝트를 Bitbucket 으로 연결하여 git으로 형상관리를 하였습니다.


본 작업에서는 Docker Image 에서 Bitbucket에 올라간 Ruby On Rails 프로젝트를 clone 하여 사용하는 구조로 만들기로 합니다.

아래 Docker Image를 사용하려 하였으나, Deprecated 라는 내용 때문에 직접 Docker Image를 만들어 쓰기로 하였습니다.


https://github.com/docker-library/rails


1. 먼저 Docker Image를 만들기 위해 Dockerfile을 생성합니다.


FROM ubuntu
 
ENV PATH "~/.rbenv/bin:$PATH"
ENV PATH "~/.rbenv/versions/2.3.0/bin:$PATH"
ENV RAILS_ENV development
EXPOSE 3000
 
# Run upgrades
RUN apt-get -y update
 
# Install basic packages
RUN apt-get -y install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
 
RUN apt-get install nano
 
#RUN cd
WORKDIR ~
RUN git clone git://github.com/sstephenson/rbenv.git ~/.rbenv 
 
RUN git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build 
 
RUN ls ~/.rbenv
RUN ~/.rbenv/bin/rbenv init -
 
# 루비 설치
RUN ~/.rbenv/bin/rbenv install -v 2.3.0 
RUN ~/.rbenv/bin/rbenv global 2.3.0
 
RUN ~/.rbenv/versions/2.3.0/bin/ruby -v
 
# gem 설정, bundler 설치
RUN echo "gem: --no-document" > ~/.gemrc
RUN ~/.rbenv/versions/2.3.0/bin/gem install bundler
 
# 레일즈 설치
RUN ~/.rbenv/versions/2.3.0/bin/gem install rails -v 4.2.5
RUN ~/.rbenv/bin/rbenv rehash
RUN ~/.rbenv/versions/2.3.0/bin/rails -v
 
# node js 설치
RUN apt-get -y install nodejs
 
# 프로젝트 소스 clone
WORKDIR /app
RUN git clone https://id:pwd@bitbucket.org/<<아이디>>/<<프로젝트>>
 
# bunde install
WORKDIR /app/testror
RUN ~/.rbenv/versions/2.3.0/bin/bundle install
RUN ~/.rbenv/versions/2.3.0/bin/bundle exec rake db:migrate
 
# rails 서버 start
CMD ~/.rbenv/versions/2.3.0/bin/rails s -b 0.0.0.0 -p 3000

위 내용을 간단히 설명하자면 아래와 같습니다.

  1. ubuntu 이미지 기반
  2. 환경변수 설정 후 3000포트 사용 정의
  3. 기본 패키지 업데이트 및 설치
  4. ruby 설치
  5. gem 설정, bundler 설치
  6. rails 설치
  7. node js 설치
  8. Rails 어플리케이션 clone
  9. bundle install 및 db migrate
  10. CMD 명령으로 컨테이너 실행시마다 rails 서버 시작

2. Dockerfile 작성 후 Docker Image 빌드를 합니다.


Dockerfile이 있는 경로에서 아래 커맨드를 실행합니다.

docker build -t ror .


위 커맨드를 간단히 설명하자면 아래와 같습니다.

  1. Docker Image를 build 하겠다.
  2. -t로 이름과 태그 지정(name/tag식으로 tag 안 쓸 경우는 name만). 이름은 ror로 지정
  3. . 으로 빌드 대상 경로 지정. Dockerfile 있는 경로로
  4. 완료 후 docker images 로 이미지 생성 완료 확인
  5. 실패시 docker rmi ≪image name≫ 으로 실패한 이미지 삭제

실행시 아래와 같은 결과를 확인할 수 있습니다.



$ docker build -t ror .
Sending build context to Docker daemon  16.38kB
Step 1/28 : FROM ubuntu
 ---> 20c44cd7596f
...
Successfully built 840df28a7759
Successfully tagged ror:latest

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ror                 latest              840df28a7759        2 hours ago         842MB


3. Docker Container를 생성 및 실행합니다.


Docker Image 생성 완료 후 아래 커맨드로 컨테이너를 생성 및 실행합니다.


docker run -d --name ror -p 60005:3000 ror


위 커맨드를 간단히 설명하자면 아래와 같습니다.

  1. Docker Image를 build 하겠다.
  2. Docker Container를 run 하겠다.
  3. -d 옵션으로 컨테이너를 백그라운드에서 실행
  4. --name 으로 컨테이너 이름 설정. ror로 설정함
  5. -p 로 호스트에 연결된 컨테이너의 특정 포트를 외부에 노출(<호스트 포트>:<컨테이너 포트>)
  6. ror 이미지로 생성
  7. 실패시 docker rm ror 로 컨테이너 삭제
실행시 아래와 같은 결과를 확인할 수 있습니다.


$ docker run -d --name ror -p 60005:3000 ror
0431b06b76a1978898d3f0cdf44ebda94.......
$ docker logs ror
[2017-12-28 10:40:46] INFO  WEBrick 1.3.1
[2017-12-28 10:40:46] INFO  ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2017-12-28 10:40:46] INFO  WEBrick::HTTPServer#start: pid=6 port=3000

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                     NAMES
0431b06b76a1        ror                 "/bin/sh -c '~/.rb..."   2 hours ago         Up 2 hours               0.0.0.0:60005->3000/tcp   ror


위와 같이 하신 후 브라우저에서 locahost:60005 로 연결하시면 Ruby On Rails 프로젝트 동작을 확인할 수 있습니다.


참고로 위 작업을 마친 후 아래 링크도 찾게 되었네요;; 그런데 안해봐서 아래 링크대로는 아직 확인을 못해봤습니다.


https://docs.docker.com/compose/rails/


위 링크를 따라하시다 안되시면 제 포스팅 내용을 참고하시면 될 거 같습니다.

'IT > 각종 환경설정' 카테고리의 다른 글

C9 VNC 사용시 한글 세팅  (0) 2018.03.12
DokuWiki 설정하기  (0) 2018.03.12
TISTORY 포스팅에서 코딩 스타일 입히기  (0) 2017.12.12

개발 관련된 포스팅을 보다 보면 소스들이 이쁘게 색을 입고 IDE 처럼 차려놓은 것들을 보게된다.

찾아보니 티스토리에서 기본 지원되는 부분은 아니고 SyntaxHighlighter 라는 붙여서 사용하는 것이었다.

생각보다 어렵지 않고 이에 대해 이미 시행착오를 겪고 잘 정리해주시는 고마운 분들이 있다.

그 중 내가 참고했던 한 포스팅을 올려놓는다.


http://sometimes-n.tistory.com/5


추가로 "<", ">" 등의 특수문자를 쓸때 "&lt;", "&gt;" 와 같이 문자열을 치환하여 사용해야한다.

소스 라인을 이리 바꾸는 일 또한 힘든 일이라 아래 서비스 등을 사용하면 도움이 된다.


http://www.elliotswan.com/postable/



---------------------------------------------------------------------------------------------------------------------


더 간단한 방법도 있었다.

android studio 처럼 나오게 하기 위해 찾아보니 있었다......


http://editorizer.tistory.com/190

'IT > 각종 환경설정' 카테고리의 다른 글

C9 VNC 사용시 한글 세팅  (0) 2018.03.12
DokuWiki 설정하기  (0) 2018.03.12
[Docker] Ruby On Rails 이미지 만들기  (0) 2017.12.28

+ Recent posts