{"id":18387229,"url":"https://github.com/kimhan-nah/inception","last_synced_at":"2026-03-06T11:02:19.090Z","repository":{"id":178857807,"uuid":"566267190","full_name":"Kimhan-nah/inception","owner":"Kimhan-nah","description":"Summary: This document is a System Administration related exercise. Version: 1.2. This project aims to broaden your knowledge of system administration by using Docker. You will virtualize several Docker images, creating them in your new personal virtual machine.","archived":false,"fork":false,"pushed_at":"2023-01-11T06:36:56.000Z","size":236,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-01T20:47:27.900Z","etag":null,"topics":["containers","docker","docker-image","dockerfile","mariadb","nginx","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kimhan-nah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-15T10:10:09.000Z","updated_at":"2023-09-06T17:19:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"62f11b71-bc5a-46b5-aaa1-dceb95fecdcb","html_url":"https://github.com/Kimhan-nah/inception","commit_stats":null,"previous_names":["kimhan-nah/inception"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Kimhan-nah/inception","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kimhan-nah%2Finception","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kimhan-nah%2Finception/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kimhan-nah%2Finception/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kimhan-nah%2Finception/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kimhan-nah","download_url":"https://codeload.github.com/Kimhan-nah/inception/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kimhan-nah%2Finception/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30173348,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containers","docker","docker-image","dockerfile","mariadb","nginx","wordpress"],"created_at":"2024-11-06T01:25:25.309Z","updated_at":"2026-03-06T11:02:14.061Z","avatar_url":"https://github.com/Kimhan-nah.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Table of Contents\n- [Table of Contents](#table-of-contents)\n- [Inception](#inception)\n- [0. MariaDB, Wordpress, Nginx WIKI](#0-mariadb-wordpress-nginx)\n- [1. Alpine Linux](#1-alpine-linux)\n- [2. Virtualization](#2-virtualization)\n\t\t- [가상화란?](#가상화란)\n\t\t- [가상화 종류](#가상화-종류)\n- [3. Container](#3-container)\n- [4. Docker](#4-docker)\n\t- [Docker?](#docker)\n\t- [Docker Architecture](#docker-architecture)\n\t- [Docker Daemon (`dockerd`)](#docker-daemon-dockerd)\n\t- [Docker Client (`docker`)](#docker-client-docker)\n\t- [Docker Registries](#docker-registries)\n\t- [Docker Objects](#docker-objects)\n\t\t- [**Images**](#images)\n\t\t- [**Containers**](#containers)\n\t\t- [Networks](#networks)\n\t\t- [Volumes](#volumes)\n\t\t- [Plugins](#plugins)\n\t- [Storage Driver](#storage-driver)\n\t\t- [Docker Image Layer](#docker-image-layer)\n\t\t- [Docker Container Layer](#docker-container-layer)\n\t- [Signal in Docker](#signal-in-docker)\n\t- [PID 1 (`init system`) in Docker](#pid-1-init-system-in-docker)\n\t\t- [docker-init](#docker-init)\n\t- [Docker Commands](#docker-commands)\n- [Dockerfile](#dockerfile)\n\t- [Docker Cache \\\u0026 Dockerfile](#docker-cache--dockerfile)\n\t- [`RUN` Instruction](#run-instruction)\n\t- [`CMD` Instruction](#cmd-instruction)\n\t- [`ENTRYPOINT` Instruction](#entrypoint-instruction)\n\t\t- [`CMD` \\\u0026 `ENTRYPOINT`](#cmd--entrypoint)\n\t- [`EXPOSE` Instruction](#expose-instruction)\n\t- [`ADD` Instruction](#add-instruction)\n\t- [`COPY` Instruction](#copy-instruction)\n\t- [`VOLUME` Instruction](#volume-instruction)\n\n\n\n# Inception \n  - Summary: This document is a System Administration related exercise.\n  - Version: 1.2\n  - This project aims to broaden your knowledge of system administration by using Docker. You will virtualize several Docker images, creating them in your new personal virtual machine.\n\n\n# 0. MariaDB, Wordpress, Nginx\n  - [구구절절 WIKI](https://github.com/Kimhan-nah/inception/wiki)\n\n# 1. Alpine Linux\n\n  - **리눅스 커널을 기반으로 한 리눅스 배포판**\n  - **“Small. Simple. Secure.”**\n  - 타 리눅스 배포판보다 훨씬 가볍고 깔끔한 것이 장점 → 컨테이너에 흔히 사용됨\n      \n      [왜 컨테이너 환경에서는 Alpine Linux가 선호될까?](https://velog.io/@dry8r3ad/why-alpine-linux)\n      \n  - **가벼운 용량 (Small)**\n      - 가벼운 용량을 컨셉으로 잡은 덕분에 패키지 하나하나의 용량이 매우 작고 기본적으로 man 문서를 분리하여 용량에서 더 많은 이점을 가져갔다고 볼 수 있음\n      - `Glibc` 아닌 `Musl` 을 사용하여 더더욱 임베디드에서 가볍게 동작\n          - `Musl` : C 라이브러리 `Glibc` 대신 사용. 크기, 정확도, 정적 링킹 지원 등의 장점\n      - `BusyBox` 기반으로 단일 바이너리 용량 줄임\n          - `BusyBox` : 여러 유닉스 도구(ls, cd)을 한 실행파일로 제공하는 소프트웨어 → 용량 측면에서 이점\n      \n      ⇒ **클라우드 환경에서 용량은 큰 장점으로 작용**\n      \n      ⇒ AWS, Azure의 Public Cloud에서 제공하는 서비스를 사용하는 경우, **사용량에 따라서 비용 발생 → 컨테이너 환경에서는 지속적인 배포하고 여러 이미지를 받음**\n      \n      ⇒ 이 과정에서 네트워크 자원을 사용량 줄여야 함\n      \n      ⇒ But! 이런 요소들이 기존 배포판과 달라서 문제 해결에 어려움\n      \n  - *Docker가 호스트 운영체제의 커널 위에 격리를 시켜주는 반가상화 시스템?*\n  - **Secure**\n      - 알파인 리눅스에서 제공되는 모든 유저 레벨의 바이너리들은 PIE(Position Independent Executables)로 컴파일 되어 Stack Smashing Protection 되어있다.\n      - 또한 가벼운 OS를 지향하는 만큼 기본적으로 설치되어 있는 프로그램이 적음\n      - 그만큼 취약점 생길 포인트가 적음 (안전)\n      - `PIE` : 리눅스 환경에서의 메모리 보호 기법\n      - *실제로 2014년, `ShellShock` 취약점이 발견되었고 공격 대상이 되었던 Bash가 기본적으로 설치되어 있던 대부분의 리눅스 배포판은 이 취약점의 영향을 받았지만 Bash를 기본으로 설치하지 않은 알파인 리눅스는 영향이 없었음*\n  - `init system`으로 `openRC` 사용함\n      - `init system`\n          - PID 1인, 커널을 시작할 때 실행되는 첫 번째 프로세스. 좀비 프로세스 관리\n          - ex) `systemd` , `openRC`\n    \n\n# 2. Virtualization\n\n### 가상화란?\n\n### 가상화 종류\n\n  ![virtualization](./asset/virtualization.png)\n\n  - 베어메탈\n      - ex) 멀티 부팅\n  - 호스트형 가상머신\n      - ex) Virtual Box, VM ware\n  - **컨테이너**\n      - ex) Docker\n\n# 3. Container\n\n  - **VM과 달리, 호스트 커널 공유하면서 프로세스를 격리된 환경에서 실행하는 기술**\n  - 커널을 공유하는 방식이기 때문에 **실행 속도가 빠르고, 성능 손실 X**\n  - 커널을 공유하지만, 커널 기능(ex. namespace, cgroup)을 활용해 격리(독립)\n      \n      → 호스트 OS 관점에서는 프로세스로 보이나 내부 들여다 보면 하나의 가상환경\n      \n  - 가상화 기술의 종류\n\n# 4. Docker\n## Docker?\n  - 애플리케이션 개발, 배포, 실행을 위한 오픈 플랫폼\n  - 컨테이너를 실행하고 관리할 수 있도록 도와주는 도구\n  - 컨테이너는 가볍고 애플리케이션을 실행하는 데 필요한 모든 것을 포함하므로 호스트에 현재 설치된 항목에 의존할 필요 없음\n  - 이전의 컨테이너 기술에서는 컨테이너의 환경을 완전하고 효율적으로 복원하는 것이 상당히 어려운 일이었음\n      \n      → 도커는 파일을 계층으로 나눠서 저장할 수 있는 `union mount` 기술과 `Docker Hub`라는 원격 저장소를 기본적으로 제공함으로써 이 문제를 해결함\n      \n      → `Docker Images`는 도커의 간편한 인터페이스와 더불어 도커가 성공적으로 자리잡는 데 중요한 역할\n\n## Docker Architecture\n\n  ![img](https://docs.docker.com/engine/images/architecture.svg)\n\n  - Docker Daemon ↔ Docker Client 통신\n      - 동일한 시스템에서 실행 or 클라이언트를 원격 데몬에 연결 가능\n      - UNIX 소켓 or 네트워크 인터페이스를 통해 `REST API wrapper` 사용하여 통신\n      - unix domain socket, fd, tcp 방식으로 docker daemon에 접속\n\n\n## Docker Daemon (`dockerd`)\n\n  - 실제 동작하는 프로세스\n  - 도커 엔진의 기능을 수행 후 응답하는 프로세스\n  - API 요청을 수신하고 이미지, 컨테이너, 네트워크 및 볼륨과 같은 도커 객체를 관리\n\n## Docker Client (`docker`)\n\n  - 사용자가 Docker와 상호작용하는 기본 방법\n  - `docker run`과 같은 명령 사용 → 클라이언트가 명령을 API로 `dockerd`로 보내서 실행\n  - 또다른 도커 클라이언트 is `Docker Compose`\n\n## Docker Registries\n\n  - Docker Image 저장소\n  - 도커는 default로 Docker Hub에서 Image 찾음\n  - own private registry도 가능\n\n## Docker Objects\n\n### **Images**\n\n  - 컨테이너를 빌드하기 위한 read-only 바이너리 파일\n  - 이미지 pull 커맨드 : `docker pull \u003cIMAGE\u003e`\n      - `\u003cIMAGE\u003e` : `\u003cNAMESPACE\u003e/\u003cIMAGE_NAME\u003e:\u003cTAG\u003e` 꼴을 레지스트리에서 내부적으로 파싱되어 사용됨\n      - `\u003cNAMESPACE\u003e` 앞에는 도메인이 들어갈 수 있는데 도커 이미지 저장소의 주소를 가리킴\n          \n          → default가 `Docker Hub` (docker.io)\n          \n      - ex) `docker.io/library/ningx:latest`\n  - I**mage 원리(저장 방식) : [Docker Image Layer](#docker-image-layer)**\n\n### **Containers**\n\n  - 실행가능한 이미지의 인스턴스\n  - 사용자는 컨테이너를 Docker API를 통해 생성, 삭제 수정, 이동\n  - 독립된 환경을 제공해주는 프로세스\n  - 하나의 빈 레이어(Read-Write layer)만 생성하면 되기 때문에 매우 빠르게 생성됨 ⇒ [Container Layer](#container-layer)\n  - 각 컨테이너는 root 디렉토리, pid, 네트워크, 메모리, cpu 등을 새롭게 구성\n\n### Networks\n\n### Volumes\n\n  - 컨테이너에서 생성되고 사용되는 데이터를 유지하기 위해 선호되는 메커니즘\n  - 컨테이너와 관련된 특별한 유형의 디렉터리\n  - 컨테이너 내부 폴더와 컨테이너 외부 폴더를 연결하는 것(`mount`)\n    - 로컬 폴더와 컨테이너 내부 폴더는 격리되어 있으나 `volumes`을 이용해 연결이 가능하도록 만들 수 있다는 의미\n  - 모든 데이터 유형을 저장할 수 있음 (코드, 로그 파일 등)\n  - 컨테이너 간에 데이터 공유 가능\n  - 이미지가 업데이트 될 때 데이터 볼륨에 영향 X → 컨테이너가 컴퓨터에서 삭제된 경우에도 데이터 볼륨은 남아서 여전히 제어 가능\n  - `volumes` 종류 : `named volumes`, `unnamed? volumes`\t\t\u003c!-- 수정 필요 --\u003e\n  - `bind mount`는 호스트 시스템의 디렉토리 구조와 OS에 따라 다르지만 `Volumes`은 도커에서 완전히 관리함\n      - `volumes (mount)` VS `bind mount` VS `tmpfs mount` : mount 종류\n          \n          ### Volumes\n          \n          ![https://docs.docker.com/storage/images/types-of-mounts-volume.png](https://docs.docker.com/storage/images/types-of-mounts-volume.png)\n          \n          \u003e volumes (출처 : docker 공식 문서 [Use volumes](https://docs.docker.com/storage/volumes/))\n          \n          - mount 종류 중 best 방식\n          - `volumes`가 `bind mount` 보다 백업 또는 마이그레이션이 쉬움\n          - Docker CLI command 또는 Docker API 사용하여 `Volumes` 관리\n          - `Volumes`는 Linux, Windows 컨테이너 모두에서 작동함\n          - 여러 컨테이너 간에 `Volumes`을 보다 안전하게 공유할 수 있음\n          - `Volumes` 드라이버를 사용하면 원격 호스트 또는 클라우드 제공자에 `Volumes`을 저장하거나 `Volumes`의 내용을 암호화하거나 다른 기능을 추가할 수 있음\n          - 새 `Volumes`는 컨테이너에 의해 미리 채워진 콘텐츠를 가질 수 있음\n          - Docker Desktop의 `Volumes`는 Mac, Windows 호스트의 `bind mount`보다 훨씬 높은 성능 제공\n  \t\t\t\t- Docker CLI로 관리 가능\n          \n          ### bind mount\n          \n          ![https://docs.docker.com/storage/images/types-of-mounts-bind.png](https://docs.docker.com/storage/images/types-of-mounts-bind.png)\n          \n          \u003e bind mount (출처 : docker 공식 문서 [Use bind mounts](https://docs.docker.com/storage/bind-mounts/))\n          \n          - Docker 초기부터 사용됨\n          - 호스트 시스템의 파일 또는 디렉토리가 컨테이너에 mount\n          - 파일 또는 디렉토리는 호스트의 전체 경로로 지정됨\n          - Docker CLI command로 관리 X\n          - `bind mount` 성능은 매우 우수하지만, 호스트 시스템에 의존해서 사용되기 때문에  `Volumes`에 비해 기능이 제한적\n          - 호스트 시스템의 파일 또는 디렉토리가 컨테이너에 마운트 됨\n      \t### tmpfs mount\n\n        ![https://docs.docker.com/storage/images/types-of-mounts-tmpfs.png](https://docs.docker.com/storage/images/types-of-mounts-tmpfs.png)\n          \u003e tmpfs mount (출처 : docker 공식 문서 [tmpfs mount](https://docs.docker.com/storage/tmpfs/))\n        - `tmpfs mount`로 컨테이너를 생성하면, 컨테이너의 writable layer 외부에 file 생성이 가능\n        - `volumes`, `bind mount` 달리 `tmpfs mount`는 임시이며 호스트 메모리에만 지속됨\n         - 컨테이너 중지되면 `tmpfs mount`가 제거되고 거기에 기록된 파일은 유지되지 않음\n      \t- 호스트 또는 컨테이너 쓰기 가능 계층에 유지하지 않으려는 민감한 파일을 임시로 저장하는 데 유용\n      \t- 다른 mount와는 달리 컨테이너 간 공유 X\n      \t- Only Linux 환경에서 Docker 실행하는 경우에만 사용 가능\n\n  - [`Storage Driver`](#storage-driver) VS `Volumes`\n\n### Plugins\n\n\u003cbr/\u003e\n\n## Storage Driver\n\n  - Docker는 Storage Driver를 사용하여 **Image Layer를 저장**하고 **컨테이너의 쓰기 가능한 layer에 데이터를 저장**\n  - 각 Layer가 서로 상호 작용하는 방식에 대한 세부 정보를 처리함\n  - Storage Driver은 공간 효율성에 최적화\n  - But! 쓰기는 copy-on-write file system을 사용 -\u003e 기본 file system 성능보다 쓰기 속도가 느림\n      \n      **⇒ 컨테이너의 쓰기 가능한 계층은 런타임 시 생성되는 임시 데이터를 저장하는 데 적합**\n      \n  - Database Storage 같은 쓰기 집약적인 애플리케이션은 특히 기존 데이터가 read only 계층에 있는 경우 성능 오버헤드의 영향 받음\n      \n      ⇒ 쓰기 집약적인 데이터, 컨테이너의 수명을 넘어 지속되어야 하는 데이터 및 컨테이너 간에 공유 되어야 하는 데이터는 [`Docker Volumes`](#volumes) 사용!\n      \n  - `docker info | grep \"Storage Dirver\"`로 확인 가능\n      - 현재는 지원되는 모든 Linux 배포판에서 선호하는 스토리지 드라이버는  `overlay2` (추가 구성 필요 없음) - 2022년 11월 기준\n  - 다양한 Storage Driver를 사용할 수 있으며 상황에 따라 장점, 단점이 있음\n  - **효율적으로 Storage Driver를 사용하려면,** Docker가 **이미지를 build하고 저장하는 방법**과 **컨테이너에서 이러한 이미지를 사용하는 방법**을 알아야 함!\n      \n      ⇒ [Docker Image Layer](#docker-image-layer), [Docker Container Layer](#docker-container-layer)\n      \n  - [Docker storage drivers 공식 문서](https://docs.docker.com/storage/storagedriver/select-storage-driver/)\n\n  - [About storage drivers 공식 문서](https://docs.docker.com/storage/storagedriver/)\n\n### Docker Image Layer\n\n  ![https://docs.docker.com/storage/storagedriver/images/container-layers.jpg](https://docs.docker.com/storage/storagedriver/images/container-layers.jpg)\n\n  - Docker image는 일련의 `layer`로 구성\n  - 도커 이미지를 구성하는 각 파일을 `layer`라고 함 (분리된 데이터)\n  - 이러한 계층은 일련의 중간 이미지를 형성, 각 계층이 바로 아래의 계층에 종속됨\n  - file system을 수정하는 명령은 계층을 생성함\n      - `FROM`, `COPY`, `RUN` : layer 생성\n      - `LABEL`, `CMD` : image의 metadata 수정 → layer 생성 X\n  - 각 layer는 이전의 layer과의 차이의 set임\n  - file을 추가, 삭제하는 것은 new layer로 생성됨 → 삭제되어도 이전 layer에서 계속 사용할 수 있으며 images의  total size는 늘어남\n  - 이미지가 컨테이너로 실행되면 맨 위에 쓰기 가능한 layer가 추가됨 → [`Container Layer`](#docker-container-layer)\n\n### Docker Container Layer\n  ![https://docs.docker.com/storage/storagedriver/images/sharing-layers.jpg](https://docs.docker.com/storage/storagedriver/images/sharing-layers.jpg)\n  - 도커 컨테이너가 실행되면 모든 읽기 전용 레이어(`Read Only Layer`)들은 순서대로 쌓은 다음 마지막에 쓰기 가능한 신규 레이어를 추가\n  - 그 다음 컨테이너 안에서 발생하는 결과물들이 쓰기 가능 레이어(`Read-Write Layer`)를 기록\n  - 아무리 많은 도커 컨테이너를 실행하더라도 기존 읽기 전용 레이어는 변하지 않고, 컨테이너마다 생성된 쓰기 가능한 레이어에 데이터가 쌓이기 때문에 서로 겹치지 않으며 컨테이너가 종료되면 모두 사라짐\n\n## Signal in Docker\n\n- `docker stop` → `SIGTERM` signal을 컨테이너에 보냄 → 10초간 컨테이너가 종료되지 않으면 `SIGKILL`\n- docker run, entrypoint\n    - `docker run \u003cimage\u003e \u003cexecutable\u003e` 의 컨테이너를 실행할 때 사용하는 `\u003cexecutable\u003e` 는 해당 컨테이너에서 PID 1로 작동\n- Dockerfile에서의 ENTRYPOINT에는 보통 `exec form`, `shell form`\n    - `exec form` : JSON array 형태로 직접 실행\n        - `\u003cexecutable\u003e` 이 PID 1 됨\n    - `shell form` : /bin/sh -c 형태로 실행\n        - 내부적으로 fork하기 때문에 subprocess로 명령어가 작동함.\n        - 따라서 shell form /bin/sh가 PID 1이 되고, `\u003cexecutable\u003e` 이 PID 2 이후의 것을 받음\n\n⇒ 따라서! 우리는 `docker stop` 으로 `SIGTERM` 시그널로 정상적인 작동하도록 해야함!\n\n1. `shell form` 쓰지 말고, `exec form` 사용하삼!\n2. initialization process 사용해서 PID 1 설정하삼!\n\n## PID 1 (`init system`) in Docker\n\n  - 리눅스 커널의 PID와 마찬가지로 컨테이너에서 실행된 첫 번째 프로세스는 PID 1을 얻는다\n  - PID 1로 등록된 단 하나의 프로세스만을 컨테이너가 담당하겠다는 의미\n  - 단 하나의 컨테이너가 곧 단 하나의 서비스(프로세스)를 의미 → 서버 환경 관리 측면에서 일관성\n  - 분리된 좀비 프로세스를 제거하는 데에 사용됨\n    - 분리된 프로세스 (상위 요소가 사라진 프로세스)는 PID 1이 있는 프로세스에 다시 첨부됨\n    - 그러나 컨테이너에서는 PID 1을 갖고 있는 프로세스가 이러한 책임\n    - 제대로 제거를 하지 못하면 메모리나 다른 리소스가 부족해질 수 있음\n### docker-init\n  - docker run 수행시 --init 옵션\n  - `--init` 사용 X\n    - docker run 수행시 넘겨준 command가 그대로 1번 process가 됨\n  - `--init` 사용 O\n    - child process를 받아줘서 resource의 누수나 zombie process의 생성을 방지하는 init system 역할을 container 내에서 수행\n    - init process로 사용되는 default binary는 `/usr/bin/docker-init` 사용 (`which docker-init` 결과로 찾아지는 binary 사용)\n  \n## Docker Commands\n  - `dockr run [OPTIONS] IMAGE [COMMAND] [ARG...]`\n    -  Run a command in a new container\n    -  `/containers/create` -\u003e `/containers/(id)/start`\n    -  기본 이미지에서 설정되어 있는 것들의 대부분을 run option으로 재정의할 수 있음\n  - `docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]`\n    - Create a new image from a container's changes\n\n\n# Dockerfile\n\n## Docker Cache \u0026 Dockerfile\n\n- image layer는 여러 layer로 구성되어 있는데, 매번 모든 layer를 빌드한다면 매우 느려짐\n    \n    **⇒ Docker Cache!**\n- Layer에서 변경사항이 없으면 기존 Layer 재사용 → 중복 방지 → build 속도 높임 \u0026 저장공간 효율\n- Dockerfile 명령어마다 캐싱 사용하는 기준이 다름!\n    - ADD, COPY 제외한 명령어는 명령어 string만 동일하면 캐싱 사용\n    - ADD, COPY : string + 해당 파일의 변경 유무까지 파악해서 캐싱 사용\n- 한 번 캐싱을 사용할 수 없는 구간이 발생하면, in order로 진행되는 Docker 빌드 특성상 그 아래 모든 layer는 캐싱을 사용할 수 없음\n\n## `RUN` Instruction\n\n- shell form : `/bin/sh -c` 로 실행됨\n- exec form : `exec` 로 실행됨\n    - ex. `RUN [\"/bin/bash\", \"-c\", \"echo hello\"]`\n- **도커 이미지를 빌드하는 순간에 실행이 되는 명령어 (이미지 빌드)**\n- 라이브러리 설치하는 부분에서 주로 활용\n- cache는 다음 build에서 자동으로 invalidate되지 않음 (?)\n    \n    → ADD, COPY에 의해 RUN cache는 invalidate 됨 (?)\n    \n    → 상황에 맞게 `docker build --no-cache` 사용해야 함\n    \n\n## `CMD` Instruction\n\n- **이미지로부터 컨테이너 생성하여 최초로 실행할 때 수행 (컨테이너 실행)**\n- shell form, exec form 사용하면, 이미지로부터 컨테이너가 실행될 때 CMD 세팅해줌 (???)\n- Dockerfile에서 한 번만 사용 가능\n    - 여러 개 있으면 마지막 CMD 적용\n- ENTRYPOINT 같이 사용되면, 모두 JSON array 포맷으로 넘어감\n    - ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터 지정\n\n## `ENTRYPOINT` Instruction\n\n- **컨테이너가 생성되고 최초로 실행할 때 항상 수행되는 명령어를 지정함 (컨테이너 실행)**\n    - CMD와 차이\n        - ENTRYPOINT는 항상 실행되고, CMD는 `docker run` 명령어 실행할 때 변경이 가능함\n        \n        → `docker run` 에서 뒤에 인자들로 CMD가 덮어쓰기 되기 때문에 변경이 가능\n        \n- 컨테이너가 executable로 실행되도록 설정\n- CMD Instruction 덮어씀\n- `docker run \u003cimage\u003e -d` : 같은 형태로 ENTRYPOINT에 인자를 넘길 수 있으며\n- `docker run --entrypoint` : ENTRYPOINT Instruction 덮어쓸 수 있음\n- ENTRYPOINT 여러 개 있으면 마지막에 있는 것 적용\n- ENTRYPOINT는 사용하는 컨테이너가 executable일 때 정의해야 함\n\n### `CMD` \u0026 `ENTRYPOINT`\n\n- Dockerfile에는 적어도 하나의 ENTRYPOINT나 CMD 존재해야 함\n\n## `EXPOSE` Instruction\n\n- 컨테이너가 런타임에서 특정 포트를 listen하도록 정보를 제공\n    - 실제로 포트를 publish 하는 것 아님\n    - just 컨테이너를 실행하는 유저에게 정보 제공하는 역할\n    - 컨테이너에서 publish하려면, `docker run -P` 옵션 사용해야 함\n- TCP, UDP 선택 가능 (default TCP)\n\n## `ADD` Instruction\n\n- src의 새로운 파일이나 디렉토리, file URL 복사해서 이미지의 dest path에 추가함\n- 파일이나 디렉토리 추가하는 경우, build context의 상대경로로 적용되며, 각 src는 `*` 사용 가능\n\n## `COPY` Instruction\n\n- RUN과 비슷하지만, URL 사용할 수 없고 로컬 tar 파일을 자동으로 압축 해제 해주지 않음\n- COPY가 더 직관적이기 때문에, 꼭 필요하지 않으면 COPY 사용하는 게 조히음\n\n## `VOLUME` Instruction\n\n- 해당 이름으로 `mount point`를 생성하고 호스트나 다른 컨테이너와 별개의 volume을 holding함\n\n[Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimhan-nah%2Finception","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkimhan-nah%2Finception","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimhan-nah%2Finception/lists"}