개발 ON
  • [Network | Docker] Dockerfile
    2024년 07월 05일 00시 49분 58초에 업로드 된 글입니다.
    작성자: 이주여이
    • 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 소스코드, 명령어, 셸 스크립트 등을 하나의 파일에 기록하면 도커가 해당 파일을 읽어 컨테이너에서 작업을 수행한 뒤 이미지로 만들어내는 작업
    • 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거러움을 덜 수 있다.
    • 깃과 같은 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화 할 수 있다.

    1. Dockerfile 작성

    [root@localhost ~]# mkdir dockerfile && cd dockerfile
    [root@localhost dockerfile]# echo hello world! >> test.html
    [root@localhost dockerfile]# ls
    test.html
    
    [root@localhost dockerfile]# vi Dockerfile
    
    # Dockerfile 내에서 아래와 같이 작성한다.
    FROM rockylinux/rockylinux:latest # 베이스 이미지 지정
    MAINTAINER jy94 # 이미지 생성 개발자 지정
    LABEL "purpose"="practice" # 라벨 지정
    RUN yum install httpd -y # 이미지 생성 시 apache 설치
    ADD test.html /var/www/html # 현재 디렉터리(dockerfile)에 있는 test.html을 /var/www/html에 추가
    WORKDIR /var/www/html # 작업 디렉터리 지정
    RUN ["/bin/bash", "-c", "echo hello docker! >> test2.html"] # bash shell을 통해 test2.html 파일 생성
    EXPOSE 80 # 컨테이너가 사용할 포트 지정
    CMD apachectl -DFOREGROUND # 컨테이너 명령 지정

    Dockerfile은 한 줄이 하나의 명령어이며 명령어 뒤에 옵션을 추가하는 방식으로 작성한다.

    일반적으로 대문자로 표기한다.(FROM, RUN, ADD …)

     

    • FROM - 생성할 이미지의 베이스가 될 이미지 / Dockerfile 작성 시 무조건 입력해야 한다. 사용하려는 이미지가 없다면 자동으로 full한다.
    • MAINTAINER - 이미지를 생성한 개발자의 정보 … 도커 1.13.0 버전 이후로 사용하지 않는다.
    • LABEL - 이미지의 메타 데이터 / key=value로 구분한다. 여러 개의 메타 데이터를 저장할 수 있다. 추가된 메타 데이터는 docker inspect 명령어를 통해 확인 가능하다.
    • RUN - 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행한다. 이미지 빌드 시 입력을 받아야 하는(y / n) RUN이 있다면 오류로 간주 후 빌드가 종료된다.(’RUN yum install ~’ 실행 시 입력받아야 하는 부분이 있는데 -y가 없으면 에러로 간주돼 빌드 실패 에러가 뜬다)
    • ADD - 파일을 이미지에 추가한다.현재는 Dockerfile이 위치한 디렉터리에서 파일을 가져와 이미지 내 /var/www/html 디렉터리에 추가한다.
    • WORKDIR - 실행할 디렉터리를 지정한다.
    • EXPOSE - Dockerfile 빌드 시 생성된 이미지에서 노출할 포트를 지정한다. 바인딩을 보장하는 것이 아니며 단지 컨테이너의 80번 포트를 사용하는 것 임을 나타내는 것 뿐이다.
    • CMD - 컨테이너 시작 시 실행할 명령어를 설정하며 Dockerfile에서 단 한번만 사용 할 수 있다.

    2. Dockerfile 빌드 및 컨테이너 생성

    [root@localhost dockerfile]# docker build -t mybuild:0.0 ./
    [+] Building 16.5s (10/10) FINISHED                                           docker:default
     => [internal] load build definition from Dockerfile                                    0.0s
     => => transferring dockerfile: 349B                                                    0.0s
     => WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using  0.0s
     => WARN: JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintende  0.0s
     => [internal] load metadata for docker.io/rockylinux/rockylinux:latest                 0.0s
     => [internal] load .dockerignore                                                       0.0s
     => => transferring context: 2B                                                         0.0s
     => CACHED [1/5] FROM docker.io/rockylinux/rockylinux:latest                            0.0s
     => [2/5] RUN yum install httpd -y                                                     14.1s
     => [internal] load build context                                                       0.0s
     => => transferring context: 90B                                                        0.0s
     => [3/5] ADD test.html /var/www/html                                                   0.3s
     => [4/5] WORKDIR /var/www/html                                                         0.1s
     => [5/5] RUN ["/bin/bash", "-c", "echo hello docker! >> test2.html"]                   0.7s
     => exporting to image                                                                  0.9s
     => => exporting layers                                                                 0.9s
     => => writing image sha256:7d423b7c547fec09d468c7e7b3ecef98797556f70413dcd01d424cd869  0.0s
     => => naming to docker.io/library/mybuild:0.0                                          0.0s
    
    [root@localhost dockerfile]# docker images
    REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
    mybuild                 0.0       7d423b7c547f   7 minutes ago   250MB
    
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
    02521efde9f3   mybuild:0.0             "/bin/sh -c 'apachec…"   24 minutes ago   Up 24 minutes   0.0.0.0:32782->80/tcp, :::32782->80/tcp                myserver
    • -t - 생성될 이미지의 이름을 지정한다. 위 명령 실행 시 mybuild:0.0 이름의 이미지가 생성된다.(-t 옵션을 사용하지 않을 경우 16진수 형태의 이름으로 저장되기 때문에 -t 옵션을 사용해서 이미지 이름을 지정해주자)

     

    build 명령어 끝에는 Dockerfile이 저장된 경로를 입력하면 된다.

    ./ 는 Dockerfile이 저장된 현재 디렉터리를 뜻한다.

    이제 위에서 docker build한 이미지로 컨테이너를 만들어보자.

     

    $ docker run -d -P --name myserver2 mybuild:0.0
    # docker run -[백그라운드 실행] -[호스트에 Dockerfile EXPOSE 포트 연결] -[컨테이너명 지정] -[이미지:태그]

    3. 확인

    docker build 하기 전에 만들었던 test.html이 정상적으로 출력된다.

     

    docker build 시 RUN 명령어에 의해 만들어졌던 test2.html 또한 정상적으로 출력된다.

    [추가] 난 외부(공인 IP)에서도 들어오게 하고싶다! 🫨

    외부로도 들어올 수 있게 설정해주면 나중에 만들었던 프로젝트들을 배포할 수 있을테니.. 해보자!

    이전에 가상 서버 자체에서 배포했을 때랑 비슷했다.

     

    일단 Dockerfile에서 EXPOSE를 포트 포워딩 할 포트 번호로 수정했다.

    FROM rockylinux/rockylinux:latest
    MAINTAINER jy94
    LABEL "purpose"="practice"
    RUN yum update -y
    RUN yum install httpd -y
    ADD test.html /var/www/html
    WORKDIR /var/www/html
    EXPOSE 5221
    CMD apachectl -DFOREGROUND

     

     

    해당 Dockerfile을 build 한다.

    [root@localhost dockerfile]# docker build -t build5221 ./
    
    [root@localhost dockerfile]# docker images
    REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
    build5221               latest    a3ea627ac00f   3 hours ago     564MB

     

     

    이후 컨테이너를 생성하고 생성한 컨테이너를 확인한다.

    [root@localhost dockerfile]# docker run -d \
    > -p 5221:80 \
    > --name server5221 \
    > build5221
    
    [root@localhost dockerfile]# docker ps
    CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                             NAMES
    44c1ee590545   build5221   "/bin/sh -c 'apachec…"   11 seconds ago   Up 11 seconds   5221/tcp, 0.0.0.0:5221->80/tcp, :::5221->80/tcp   server5221

    kt 와이파이 기준으로 아래와 같이 포트 포워딩을 해준다.

     

    5222로도 테스트해본거라 2개가 있다.

    172.xxx.xx.x.xx는 공유기 사설 IP이다.

    공인 IP 221.xxx … 로 5221 포트를 갖고 들어오면 공유기 사설 IP인 172.xxx … 가 5221번 포트를 포워딩시킨다.

     

    oracle vm virtualbox 기준으로 아래와 같이 포트 포워딩을 아래와 같이 해준다.

     

    여기까지 하고나면 아래와 같이 공인 IP로도 접속이 가능하다.

    댓글