본문 바로가기

전체 글

(128)
8. 도커 데이터 관리3: 볼륨 관리 읽기 전용 볼륨 > docker run --name feedback-app -p 3000:80 --rm -v ${pwd}:/app:ro -v /app/node_modules -v feedback:/app/feedback -v /app/temp feedback-app 개발상의 편의를 위해 컨테이너와 호스트를 바인드 마운트로 연결할 수 있다. 호스트에서 소스를 편집한 내용이 컨테이너에 바로 반영되므로 개발 속도가 빨라진다. 이 경우에 호스트의 변경내용만 컨테이너로 전달되면 충분하다. 반대로 컨테이너에서 소스가 수정되어 호스트에 반영되는것은 문제가 될 수 있다. 이때 사용할 수 있는게 읽기전용 볼륨이다. -v로 정의한 볼륨 뒤에 :ro를 붙여주면 된다. 그리고 읽기전용으로 정의된 경로 하위에 컨테이너에서 쓰기..
7. 도커 데이터 관리2: 익명 볼륨, 지명된 볼륨, 바인드 마운트 도커 볼륨의 종류 도커 볼륨은 익명볼륨, 지명된 볼륨, 바인드 마운트 볼륨 3가지가 존재한다. 익명 볼륨은 -v {컨테이너 폴더 경로} 옵션으로 컨테이너를 실행하면 만들어진다. 볼륨으로 지정된 컨테이너 경로에 파일이 저장하려고 하면 컨테이너가 아니라 연결된 로컬 파일시스템에 해당 파일이 저장된다. 도커가 컨테이너의 폴더와 로컬 폴더를 연결하기때문에 개발자는 로컬 폴더가 어디인지는 알 수 없다. 또 컨테이너가 사라지면 해당 익명볼륨도 함께 사라진다. 지명된 볼륨은 -v {볼륨 이름}:{컨테이너 폴더 경로} 옵션으로 컨테이너를 실행하면 만들어진다. 익명 볼륨과 마찬가지로 컨테이너의 폴더와 로컬 폴더가 맵핑되고 개발자는 자세한 로컬 폴더의 위치를 알 수 없다. 하지만 컨테이너를 삭제해도 볼륨은 삭제되지않기 때..
6. 도커 데이터 관리1: 데이터 종류와 볼륨 데이터의 종류 서비스를 운영할 때 사용하는 데이터는 3개로 구분할 수 있다. 먼저 어플리케이션 데이터는 어플리케이션의 소스파일이나 실행파일, 실행을 위해 필요한 패키지 파일, 환경 설정 파일 등 어플리케이션 실행에 필요한 데이터를 말한다. 이러한 데이터들은 빌드할 때 도커 이미지에 포함시키는 것이 일반적이다. 그리고 도커 이미지는 읽기전용이므로 빌드된 이후 변경되지 않는다. 즉 어플리케이션 데이터는 이미지에 읽기전용으로 저장된다. 다음으로 임시데이터는 어플리케이션이 실행되는동안만 사용되는 데이터를 말한다. 사용자의 요청을 처리하는 동안 만들어지는 임시 파일을 예로 들 수 있다. 이러한 데이터는 컨테이너의 메모리나 파일시스템에 저장되고 컨테이너가 종료되면 사라진다. 즉 임시데이터는 컨테이너에 저장되고 읽기..
5-1) 제네릭 클래스의 raw type은 사용하지 마라 제네릭 클래스 public class Printer { private T source; public Printer(T source) { this.source = source; } public void setSource(T source) { this.source = source; } public void print() { System.out.println(source); } } // 제네릭 클래스 덕분에 String, Integer 타입의 클래스를 따로 만들지 않고 사용할 수 있다. Printer strPrinter = new Printer("hello"); strPrinter.print(); Printer intPrinter = new Printer(100); intPrinter.print(); 제네릭 ..
4-10) 멤버 클래스는 되도록 static으로 만들어라 중첩 클래스 중첩 클래스란 다른 클래스 안에 정의된 클래스로서 이너 클래스(inner class)라고도 불린다. 중첩 클래스는 자신을 감싼 외부 클래스에서만 쓰여야 하며, 그 이외에 쓰임새가 있다면 탑레벨 클래스로 만들어야 한다. 중첩클래스는 1) 정적 멤버 클래스 2) 멤버 클래스 3) 익명 클래스 4) 지역 클래스와 같이 4개의 유형이 있다. 정적 멤버 클래스 public class MyClass { private Integer myNumber; public static class MyInnerClass { public void method(MyClass myClass) { Integer number = myClass.myNumber; } } } // 일반 클래스와 같이 사용할 수 있다. MyInne..
4-9) 태그 달린 클래스보다는 클래스 계층구조를 활용하라 태그달린 클래스 class Figure { enum Shape { RECTANGLE, CIRCLE }; // 도형의 형태를 나타내는 태그 필드 final Shape shape; double length; double width; double radius; Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } Figure(double length, double width) { shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area() { switch(shape) { case RECTANGLE: return length * width; case CI..
4-8) 인터페이스는 타입을 정의하는 용도로만 사용하라 인터페이스 MyInf instance1 = new MyInfImpl(); MyInf instance2 = new YourInfImpl(); 자바의 인터페이스는 (일반적으로) 구현이나 필드 없이 메소드만 정의되어있는 추상화된 요소이다. 개발자는 인터페이스를 구현하여 동일한 기능을 내부 구현을 다르게하여 만들 수 있다. 클라이언트에서는 다르게 만들어진 인터페이스의 구현체들을 내부 모습을 모른체로 사용할 수 있다. 이처럼 인터페이스는 다양한 구현체의 인스턴스를 참조할 수 있는 타입 역할을 한다. 상수 인터페이스 안티패턴 // 수학 상수들을 정의한 인터페이스 public interface Math { static final double pi = 3.141592; ... } 상수 인터페이스란 메소드 없이 상수값들..
5. Docker Hub로 이미지 push/pull, 사용하기 도커 이미지 공유하기 도커의 이미지에는 어플리케이션 파일과 시스템 설정, 도구, 패키지와 같은 실행에 필요한 모든 것이 갖추어져있는 소프트웨어 패키지이다. 만들어진 도커 이미지는 동료들이나 서버에 공유하여 사용한다. 이때 도커를 공유하는 방식은 두가지 생각해 볼 수 있다. 먼저 Dockerfile 소스를 공유하는 것이다. Dockerfile을 공유하고 이를 빌드하면 이미지가 만들어지기 때문에 이미지를 공유하는 것과 비슷한 효과이다. 하지만 Dockerfile을 빌드하는 과정이 추가적으로 필요하고, 빌드를 위해 필요한 로컬 파일이나 소스가 있다면 함께 공유해야한다는 단점이 있다. 그래서 두번째 방법인 도커 이미지를 공유하는 것이 일반적이다. 도커 이미지를 공유하면 빌드할 필요없이 바로 사용할 수 있고 부가..