Dockerfile을 읽을 줄 안다는 것은 해당 이미지가 어떻게 구성되어 있는지 알 수 있다는 의미이다.
Dockerfile 작성 방법
키워드
FROM: 시작점이 될 베이스 이미지를 지정한다.
MAINTAINER: 이미지를 생성한 개발자의 정보를 표시한다. (1.13.0 이후에는 권장되지 않고, LABEL을 사용하는 것이 좋다.)
LABEL: 이미지에 메타데이터를 추가한다. key-value 형태로 지정된다.
RUN: 이미지 내에서 명령어를 실행한다. 실행 결과는 새로운 레이어에 기록되고, 이 레이어는 최종 이미지에 포함된다. 각 RUN 명령은 새로운 레이어를 생성하며, 이러한 레이어들은 캐시되어 재사용될 수 있다.
WORKDIR: 컨테이너 내에서의 작업 디렉토리를 지정한다. 해당 디렉토리가 없으면 자동으로 생성되며, 이후의 작업들은 이 디렉토리 내에서 실행된다.
EXPOSE: 이미지를 실행할 때 열려야 하는 포트를 지정한다. 이 포트는 컨테이너 실행 시 -p 옵션으로 호스트와 매핑될 수 있다.
USER: 컨테이너가 실행될 때 사용될 사용자를 지정한다. (기본값 root)
COPY / ADD: 호스트 시스템의 파일이나 디렉토리를 이미지에 복사한다. ADD는 COPY보다 확장된 기능을 제공한다. ADD는 URL로부터 파일을 가져오거나 압축 해제 기능도 제공한다. 특별한 기능이 필요하지 않은 경우, COPY를 사용하는 것이 권장된다.
ENV: 컨테이너 내에서 사용될 환경 변수를 설정한다.
CMD / ENTRYPOINT: 컨테이너를 생성하거나 실행할 때 수행될 명령어를 정의한다. docker run 명령으로 새 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 해당 명령어가 실행된다. 주로 컨테이너 내부에서 지속적으로 실행되어야 하는 서버나 애플리케이션을 시작할 때 사용된다.
CMD: CMD는 docker run 실행 시 추가적인 명령어가 주어지면, 해당 명령어를 ENTRYPOINT에 지정된 명령어의 인자로 사용한다. 만약 ENTRYPOINT가 정의되어 있지 않다면, CMD에서 지정한 명령어를 실행한다.
Dockerfile 내에서 CMD를 여러 번 정의할 수 있지만, 마지막으로 정의된 CMD만 최종적으로 사용된다.
CMD는 3가지 형태로 작성될 수 있다: - CMD ["executable", "param1", "param2"]: 실행할 프로그램과 그에 대한 인자를 지정한다. - CMD ["param1", "param2"]: ENTRYPOINT로 지정된 실행 가능한 파일의 인자로 사용된다. - CMD command param1 param2: shell 형태로 명령어를 실행한다. 여기서는 /bin/sh -c를 사용하여 해당 명령어를 실행한다.
ENTRYPOINT : ENTRYPOINT는 docker run 실행 시, 추가적인 명령어가 주어지면 이 명령어는 ENTRYPOINT에 지정된 명령어에 대한 인자로 사용된다. CMD에서 기본 인자가 제공되었을 때 docker run에서 명령어를 추가로 주게 되면, CMD의 인자는 덮어쓰여진다.
ENTRYPOINT 명령은 2가지 형태로 제공된다: - exec 형태: ENTRYPOINT ["executable", "param1", "param2"]. 이 형태는 명령어가 PID 1로 실행되어 신호 처리가 올바르게 이루어진다. - shell 형태: ENTRYPOINT command param1 param2. 이 형태를 사용할 때, 명령어는 실제로 /bin/sh -c 내에서 실행되므로 신호 처리에 주의가 필요하다.
ENTRYPOINT는 CMD와 함께 사용될 때, ENTRYPOINT는 실행할 명령어를, CMD는 그 명령어의 기본 인자로 사용된다.
Docker 빌드
Dockerfile의 기본이름은 Dockerfile이다. 파일명을 이렇게 설정하면 파일이 위치한 경로에서 docker build . 만 해도 빌드가 가능하다. 하지만 이렇게 생성하면 이미지의 이름과 태그가 없기 때문에 -t 옵션으로 태그와 파일명 지정이 가능하다.
docker build . -t container_name:tag
Dockerfile은 파일명 변경이 가능하다. 위에서 파일명을 다르게 지정했다면 -f 옵션으로 지정이 가능하다.
인프라의 규모가 확장되면서 여러 팀원들과 함께 작업하는 상황에서는 동일한 상태 파일을 공유하고 동기화하는 것이 중요해졌다.
https://kschoi728.tistory.com/139
유형 1은 직접 .tf 파일과 tfstate 파일을 공유하는 방식이다. 이런 방식으로 파일을 공유할 수는 있지만, 수동으로 관리하는 데에는 여러 번거로운 작업들이 포함된다. 이 과정에서 인간의 실수나 정보의 누락이 발생할 수 있기 때문에 이러한 문제점을 해결하고자 버전 관리 시스템(VCS)의 도입이 필요해졌다.
유형 2에서는 VCS(예: git, svn)를 사용하여 해당 파일들을 효율적으로 관리한다. 이를 통해 변경 이력을 체계적으로 추적할 수 있으며, 필요한 경우 이전 버전으로 쉽게 롤백할 수 있게 되었다.
유형 3은 git을 사용하여 .tf 파일을 관리하는 동시에, s3와 같은 백엔드 서비스를 활용하여 tfstate 파일을 안전하게 저장하고 관리하는 방식이다. 이 구조를 사용하면 각 파일의 특성에 맞는 최적화된 관리 방식을 선택할 수 있다.
일반적으로는 유형 3의 구조에서 Git 저장소에 브랜치를 생성한 후 PR을 보내서 작업을 진행하게 된다.
PR은 git으로 코드를 관리할 때 주로 사용되는 브랜치 branch를 이용하는 방법으로 작업자가 코드 수정을 위해 새로운 브랜치를 생성하고 작업한 후 본인의 브랜치를 push하여 코드리뷰 후 Merge를 요청하는 방식이다.
Push와 Pull만으로도 코드 협업이 가능하긴 하지만 이렇게 할 경우, 다른 사람이 작성한 커밋을 확인하기가 쉽지 않고 리모트 저장소에 푸시할 때가 되어야 충돌 상황을 확인 할 수 있다. PR을 사용하면 작업된 테라폼 코드에 대한 자연스러운 리뷰와 메인스트림 main branch의 병합을 관리하기 수월해진다.
이전에 만들었던 Terraform VPC Module에 PR을 보내기 위해 feature 브랜치를 생성했다.
브랜치 생성
작업 후에 PR을 생성하고 main 브랜치에 Merge 해보자.
commit 후 pushopen a pull requestcommentmerge
위 과정을 거치면 다른 브랜치를 통해서 작업한 내용을 main브랜치에 합칠 수 있다.
Hashcorp TFC (Terraform Cloud) 백엔드
위에서 VCS와 PR을 활용하는 방법을 확인했다. 하지만 유형3에서 코드의 관리만큼 중요한 상태 파일의 관리를 해결하지 못했는데,
s3 등의 시스템들을 활용하면 백엔드로 관리하면 상태 파일을 안정적으로 공유할 수 있다.
그 중 TFC 백엔드에 대해서 정리해보려고 한다.
하시코프에서 프로비저닝 대상과 별개로 State를 관리할 수 있도록 SaaS 환경인 TFC를 무상 제공한다.
제공 기능 : 기본 기능 무료, State 히스토리 관리, State lock 기본 제공, State 변경에 대한 비교 기능
Free Plan 업데이트 : 사용자 5명 → 리소스 500개, 보안 기능(SSO, Sentinel/OPA로 Policy 사용) -> 링크
# variables.tf
variable "instance_type" {
description = "EC2 instance type"
type = string
}
variable "subnet_id" {
description = "Subnet id to launch the instance in"
type = string
}
variable "security_group_ids" {
description = "List of security group ids to associate with the instance"
type = list(string)
}
variable "instance_name" {
description = "Name to be used on all resources as prefix"
type = string
}
variable "associate_public_ip_address" {
description = "Associate a public ip address with the instance"
type = bool
default = false
}
# main.tf
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "this" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = var.subnet_id
vpc_security_group_ids = var.security_group_ids
associate_public_ip_address = var.associate_public_ip_address
tags = {
Name = var.instance_name
}
}
# output.tf
output "instance_id" {
description = "The ID of the instance"
value = aws_instance.this.id
}
테라폼은 terraform 바이너리 파일을 시작으로 로컬 환경에나 배포 서버와 같은 원격 환경에서 원하는 대상(프로바이더가 제공하는 API)을 호출하는 방식으로 실행된다. 각 프로바이더의 API 구현은 서로 다르지만 테라폼의 고유 문법으로 동일한 동작을 수행하도록 구현되어 있다.
https://malwareanalysis.tistory.com/619
다수의 프로바이더를 로컬 이름 지정
required_providers 블록을 사용하여 다수의 프로바이더를 로컬 이름으로 지정해 사용할 수 있다.
예를 들면 아래는 여러 프로바이더가 제공해주는 동일한 http 관련 data 블록을 사용하는 예제이다.
기본 유형에는 string, number, bool, any가 있고, 집합 유형에는 list, map, set, object, tuple이 있다.
변수 정의할 땐 아래 메타인수가 사용 가능하다.
default : 값이 전달되지 않은 경우의 기본 값, default가 없으면 apply 시 변수에 대한 정보를 물어봄
type : 변수 유형 정의, string number bool list map set object tuple 와 유형을 지정하지 않으면 any 유형으로 간주
description : 입력 변수의 설명
validation : 변수 선언의 제약조건을 추가해 유효성 검사 규칙을 정의
sensitive : 민감한 변수 값으로 테라폼의 출력문에서 값 노출을 제한함 (암호 등 민감 데이터의 경우)
nullable : 변수에 값이 없어도 됨 (null 허용 여부)
사용 예시는 아래와 같다.
variable "string" {
type = string
description = "var String"
default = "myString"
}
variable "number" {
type = number
default = 123
}
variable "boolean" {
default = true
}
variable "list" {
default = [
"google",
"vmware",
"amazon",
"microsoft"
]
}
output "list_index_0" {
value = var.list.0 # google, 1이면 vmware
}
output "list_all" {
value = [
for name in var.list : upper(name)
]
}
variable "map" { # Sorting
default = {
aws = "amazon",
azure = "microsoft",
gcp = "google"
}
}
variable "set" { # Sorting
type = set(string)
default = [
"google",
"vmware",
"amazon",
"microsoft"
]
}
variable "object" {
type = object({ name = string, age = number })
default = {
name = "abc"
age = 12
}
}
variable "tuple" {
type = tuple([string, number, bool])
default = ["abc", 123, true]
}
variable "ingress_rules" { # optional ( >= terraform 1.3.0)
type = list(object({
port = number,
description = optional(string),
protocol = optional(string, "tcp"),
}))
default = [
{ port = 80, description = "web" },
{ port = 53, protocol = "udp" }]
}
variable "my_password" {
default = "password"
sensitive = true
}
우선 순위 :
변수가 선언되는 방식에 따라 우선순위가 존재한다.
실행 후 입력 < variable 블록의 default 값 < 환경 변수 (TF_VAR 변수 이름) < terraform.tfvars < *.auto.tfvars < *.auto.tfvars.json < CLI 실행 시 -var 인수에 지정 또는 -var-file로 파일 지정
오른쪽으로 갈수록 우선순위가 높다. 예를들어 변수의 값을 출력해주는 코드가 있을 때, terraform.tfvars 내부 변수에 1이라는 값이 정의되어 있고, 실행후에 3이라는 값을 입력 한다면 결과는 1이 나오게 된다.
HashiCorp사의 Terraform은 버전화, 재사용 및 공유할 수 있는 사람이 읽을 수 있는 구성 파일에서 클라우드 및 온프레미스 리소스를 모두 정의할 수 있는 코드형 인프라(IaC) 도구로 Amazon Web Services(AWS), Azure, Google Cloud Platform(GCP), Kubernetes, Helm, GitHub, Splunk, DataDog 등 수천여개의 다양한 Provider를 제공한다.
Provider
테라폼을 적용할 대상으로 한번에 하나의 프로비저닝만 가능하며 terraform init을 통해 설치된다. (aws 구성을 azure로 변경하는 등의 작업은 불가함, 프로바이더에 대한 자세한 정보는 아래 링크 참조)
원하는 프로바이터를 선택하고 오른쪽 상단의 USE PROVIDER 버튼을 누르면 간단한 사용방법이 나온다.
Workflow and Terminology used in Terraform
테라폼은 크게 write -> plan -> apply의 과정을 거쳐 인프라를 프로비저닝한다.
write :여러 클라우드 공급자 및 서비스에 걸쳐 있을 수 있는 리소스를 정의한다.
plan : 기존 인프라 및 구성(tfstate)을 기반으로 생성, 업데이트 또는 파괴할 인프라를 설명하는 실행 계획을 생성한다.
apply :승인 시 Terraform은 모든 리소스 종속성을 고려하여 올바른 순서로 제안된 작업을 수행한다.
https://mindmajix.com/terraform-tutorial
아래는 테라폼에서 사용하는 용어들이다.
resourece : 실제로 생성할 인프라 자원을 의미
output : 인프라를 프로비저닝 한 후에 생성된 자원을 output 부분으로 출력할 수 있음
backend : terraform의 상태를 저장할 공간 지정 (내부 / 외부 모두 가능 , 이 기능으로 다른사람들과 협업 가능)
module : 공통적으로 활용할 수 있는 인프라 코드를 한곳으로 모아 정의하는 부분 (변수만 바꿔서 동일한 리소스를 쉽게 생성 가능)
remote state : VPC , IAM 등과 같이 여러 서비스가 공통으로 사용하는 것이 가능 ( ftstate 파일이 저장돼 있는 backend 정보를 명시하면, trerraform이 backend에서 output 정보들을 가져옴 )
.tfstate 파일 : 테라폼이 인프라스트럭처의 상태를 추적하고 관리하는 핵심 도구로 아래와 같은 역할을 수행한다.
인프라스트럭처 상태 추적: 파일을 통해 프로비저닝된 리소스의 상태를 기록하고, 변경 사항을 추적하며, 이전 상태와의 차이를 분석하여 필요한 변경을 식별합니다. (plan 시 달라지는 부분을 확인할 수 있음)
변경 관리: 변경 사항을 .tfstate 파일에 반영하고 apply 시 이 파일을 사용하여 변경 사항을 적용한다. 이런 방식으로 인프라스트럭처를 안전하게 변경하고 일관성 있게 유지할 수 있다.
협업 및 공유: .tfstate 파일은 팀 간 협업과 공유를 지원한다. 팀원들은 동일한 .tfstate 파일(백엔드 등)에 액세스하여 상태를 공유하고, 변경 사항을 추적하고 충돌을 방지할 수 있다.
롤백 및 복구: .tfstate 파일은 변경 사항을 롤백하고 이전 상태로 복구하는 데 사용될 수 있다.
환경 구축
테라폼 설치하기
테라폼은 여러 운영체제에서 사용할 수 있지만, Mac을 사용하기 때문에 brew와 tfenv를 사용해서 설치해보려고 한다.
ftenv를 사용하면 테라폼의 버전을 쉽게 관리할 수 있다.
# tfenv 설치
brew install tfenv
# 테라폼 설치
tfenv list-remote # 설치 가능 버전 확인
tfenv install 1.5.1
tfenv use 1.5.1
tfenv list # tfenv로 설치한 버전 확인
# 테라폼 버전 정보 확인
terraform version
구글 검색을 통해 C++로 작성된 HTTP 클라이언트/서버 애플리케이션을 개발할 때 도움를 주는 C++ REST SDK (또는 Casablanca) 라이브러리를 찾았다.
해당 라이브러리는 microsoft의 공식 라이브러리로 깃 허브에 올라와 있었기 때문에, 빌드를 위해 아래 Dockerfile을 작성했다.
casablanka.Dockerfile
FROM ubuntu:latest AS env
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y sudo
RUN apt-get install -y g++ git libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev openssl libssl-dev ninja-build
RUN git clone https://github.com/microsoft/cpprestsdk.git
RUN apt-get install -y cmake zlib1g-dev
WORKDIR cpprestsdk
RUN mkdir build && cd build
RUN cmake . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DCMAKE_CXX_FLAGS="-Wno-error" -DCMAKE_CXX_FLAGS="-Wno-format-truncation"
RUN make -j$(nproc)
RUN sudo make install
위 코드를 사용해 docker로 빌드하면 .so 파일들이 나온다.
하지만 지금은 윈도우 용 프로그램을 만들고 있기 때문에 visual studio에서 사용할 수 있도록 설정을 다시해봐야 할 것 같다.
기본적인 내용이나 활용 등 어느정도 알고 있다고 생각한 항목은 내용을 작성했고, 애매하게 알고있다고 생각한 내용은 주황색, 잘 모른다고 생각한 항목은 빨간색으로 강조했다.
Learn a Programming Language
c : 포인터, 구조체, 함수 등 기본적인 개념 이해 : Windows API 활용 및 DLL 작성 가능
c++ : 클래스, 템플릿, STD 등 기본 문법 활용이 가능
Python : 기본 문법 및 자료 구조 활용 능숙 : 리스트 컴프리헨션, 람다 함수, 데코레이터, 비동기 활용 가능 : 다양한 패키지 활용 경험
Ruby : 모름
Go : 기본 문법 및 고루틴 이해 : 예제 수준 작성 가능
Rust : 모름
JavaScript/Node.js : 기본적인 JavaSctript 및 Ajax 작성 가능 : 간단한 Node.js 백엔드 구축 및 기동 가능
Understand difference OS concepts
Networking : 라우터, 스위치, 허브 개념 : OSI 7 Layer 이해 : 랜, 구리,광케이블 융착 가능 : 채널먹스, MSPP 운용 경험 : TCP/ UDP 개념 이해
Sockets : c, Python 소켓 프로그래밍 가능 : Raw 소켓 테스트 수준으로 가능
I/O Management :
Virtualization : 하이퍼바이저, VM?
Memory/ Storage :
File Systems :
POSIX Basics :
Process management :
Startup management (initd) :
Service management (systemd) :
Threads and Concurrency :
Operating System
Linux (Debian, SUSE Linux, Fedora, Ubuntu, CentOS, Rocky, RHEL) : rpm build.spec 수정/작성 가능, yum repository 구축 가능, rpm/ deb 버전 별 설치 가능 : 서비스, 네트워크 인터페이스, NTP, locale, iptables 등 명령어 능숙 : 유저별 그룹관리, 계정 생성 및 ssh 연동, 자원 관리 : Clonezilla 활용 가능 : 쉘 스트립팅 가능
Unix (FreeBSD, OpenBSD, NetBSD) : OpenBSD만 설치 해봄
Windows : PowerShell 스크립트 가능 (COM 포트 시리얼 통신 등) : Windows API 활용 가능 : DLL injection, Global hooking 코드 작성 경험 있음 : 커널 디버깅 환경 구축 가능 (windbg, 가상 머신) : 필터/HID 드라이버 기초 개념 이해 및 예제 수준 작성 가능
Windows Server : 설치 및 IIS 서버 구축, 사설 ssl 인증서 발급 가능
Learn to live in Terminal
Bash Scripting
Vim/ Nano/ PowerShell/ Emacs
Compiling apps from source : gcc
System Performance : nmon, iostat, sar, vmstat
Others : strace, dtrace, systemtap, uname, df, history
효율적인 구성 관리 : IaC로 인프라를 구성할 때의 장점 중 하나는 버전 관리 시스템(Git 등)을 활용할 수 있다는 점이다. 이를 통해 인프라의 구성을 버전별로 추적하고 이전 버전으로 되돌리는 등 인프라 구성을 쉽게 수정할 수 있다.
자동화 : IaC를 사용하면 인프라가 자동으로 구성되기 때문에 사람이 구성할 때보다 신뢰성과 정확성이 증가한다.
쉬운 구축과 배포: IaC를 사용하면 인프라 구축과 배포가 쉽고 빨라진다.
히스토리 : 직접 구축된 서버를 보면 실제로 사용하진 않지만, 작업 중에 남겨진 흔적 등이 발견되는 경우가 있다. 이럴 때 이력이 없다면 의미를 이해하기 쉽지않다. 하지만 코드를 통해만들어졌다면 코드를 읽어만 봐도 인프라 구성을 한 눈에 알 수 있게 된다.
멱등성 : 언제 어디서 실행해도 동일한 인프라를 구성할 수 있다.
DevOps 관점에서의 IaC는 개발자와 운영자가 SDLC 상에서 더 가까이 있을 수 있게 하고 운영을 더 명확하게 하며, 운영 업무에 소프트웨어 개발 원칙과 반복성을 적용할 수도 있다. 또한 DevOps의 핵심인 자동화와 협업을 위해서 버전 관리 시스템을 사용하여 IaC를 관리할 경우, 팀으로 하여금 효과적으로 협력하는 방법에 관한 허브 역할도 수행할 수 있다.
IaC의 종류
코드로 인프라를 다룰 수 있게 도와주는 도구들은 여러가지가 있다.
각 도구마다 IaC의 구현 방식과 특성이 다르고, 인프라의 특성에 따라 사용할 때 이점이 다른 경우도 있다.
Chef (2009) : 루비 형태의 DSL(도메인 특화 언어)를 사용하여 recipe(레시피)를 작성한다. 사용을 위해 대상 서버에 별도의 agent 설치가 필요하다.
Puppet (2005) : Chef와 비슷하게 루비로 작성된 DSL를 사용하고, Agent를 설치해야한다.
SaltStack (2011) : ZeroMQ를 사용하여 비동기로 인프라를 구축할 수 있다. Agent가 필요하며 yaml을 사용한다.
Ansible (2012) : agent-less 방식으로 ssh 접속만 가능해도 사용할 수 있다. yaml을 사용하여 코드를 작성할 수 있으며 2015년 Redhat에 인수되었다.
Terraform (2014) : Hashicorp에서 제공하는 오픈소스 IaC로 HCL과 JSON을 사용한다. 클라우드 인프라를 코드로 구성할 수 있다.
Azure Resource Manager : Microsoft Azure에서 제공하는 IaC 도구로 Azure 자원을 관리할 수 있다.
AWS CloudFormation : AWS에서 제공하는 IaC 도구로 AWS 자원을 관리할 수 있다.
위 내용 중 Terraform과 SaltStack, Ansible를 앞으로 블로그에 정리해볼 계획이다.
검색을 통해 /etc/resolv.conf 등 필요한 파일들을 수정해줬고, DNS (8.8.8.8) 주소도 잘 설정되어 있다.
하지만 여전히 update가 안되었기 때문에 결국 필요한 패키지들을 수동으로 설치하기로 했다.
apt-get download
보통 필요한 패키지들은 apt-get install로 시스템에 바로 설치하지만 현재는 원인을 알 수 없는 이유로 저장소 연결이 제한된다. 패키지의 수동 설치를 위해서 먼저 docker 컨테이너를 빠져나가 apt-get이 잘 작동되는 os에서 필요한 패키지들을 다운로드 받는다.
$ sudo apt-get download vim net-tools iproute2 iputil-ping
apt-get download 명령어는 현재 디렉토리에 .deb 형태로 필요한 패키지를 다운로드 받는다.
aaa라는 임시 폴더를 만들어 내부에 필요한 deb 들을 설치했다.
이제 이 파일들을 도커 내부의 ubuntu:20.04로 전달하여 수동으로 설치하면 된다.
docker cp
도커는 도커 외부와 내부 컨테이너 간의 파일 공유가 가능하며 docker cp 명령어로 해당 기능을 제공한다.
위에서 내려받은 deb 파일을 ubuntu:20.04 컨테이너에 넣어준다.
$ sudo docker cp ../aaa/ test:/aaa/
잘 전달되었다.
이제 전달된 deb를 설치해주자.
apt install ./
apt install 명령어를 사용하면 패키지를 설치할 수 있다.
여기서 주의할 점이 있는데, install 뒤에 패키지 명을 그냥 입력하면 저장소에서 해당 패키지를 찾기 때문에
이 글에선 컨테이너 외부의 우분투에 미리 설정되어 있기 때문에 해당 파일을 도커 내부 같은 경로에 cp 명령어로 덮어씌워 줬다.
아래는 /etc/apt/source.list의 내용이고 기존 파일에 kakao 서버 주소만 추가해 주었다.
필요하다면 그대로 사용해도 좋고 다른 국내 서버 주소를 찾아서 추가해줘도 좋다.
$ vi /etc/apt/source.list
# deb cdrom:[Ubuntu 20.04.4 LTS _Focal Fossa_ - Release amd64 (20220223)]/ focal main restricted
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://kr.archive.ubuntu.com/ubuntu/ focal main restricted
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates main restricted
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates main restricted
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal universe
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal universe
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates universe
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates universe
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates multiverse
## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu focal partner
# deb-src http://archive.canonical.com/ubuntu focal partner
deb http://security.ubuntu.com/ubuntu focal-security main restricted
# deb-src http://security.ubuntu.com/ubuntu focal-security main restricted
deb http://security.ubuntu.com/ubuntu focal-security universe
# deb-src http://security.ubuntu.com/ubuntu focal-security universe
deb http://security.ubuntu.com/ubuntu focal-security multiverse
# deb-src http://security.ubuntu.com/ubuntu focal-security multiverse
# This system was installed using small removable media
# (e.g. netinst, live or single CD). The matching "deb cdrom"
# entries were disabled at the end of the installation process.
# For information about how to configure apt package sources,
# see the sources.list(5) manual.
# kakao
deb http://ftp.daumkakao.com/ubuntu/ bionic main restricted
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates main restricted
deb http://ftp.daumkakao.com/ubuntu/ bionic universe
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates universe
deb http://ftp.daumkakao.com/ubuntu/ bionic multiverse
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates multiverse
deb http://ftp.daumkakao.com/ubuntu/ bionic-backorts main restricted universe multiverse
파일을 덮어씌우고 update와 upgrade를 한번씩 더 해줬다.
이제 python3, pip3, vim, venv를 apt-get install로 설치한다.
$ apt-get install -y python3 python3-pip python3-venv vim