code .
ubuntu 에서 진행함.
# 코드 작성
mkdir 1.1 && cd 1.1
echo "print ('Hello Docker')" > hello.py
cat > Dockerfile <<EOF
FROM python:3
COPY . /app
WORKDIR /app
CMD python3 hello.py
EOF
# 컨테이너 이미지 빌드
docker pull python:3
docker build . -t hello
docker image ls -f reference=hello
# 컨테이너 실행
docker run --rm hello
docker build . -t hello:1
docker image ls -f reference=hello
docker tag hello:1 hello:latest
docker image ls -f reference=hello
docker run --rm hello:1
21초나 걸렸다.
로컬로 애플리케이션을 미리 컴파일 하고 추가 할 수 있고, 실습 예시 처럼 Dockerfile 에서 직접 컴파일 할 수 있음.
어떤 방법이 각자 회사에 개발자분들이 선호하는지, 그리고 CI/CD 전체 과정에서 보면 어떤 방법이 적합한지, 보안적으로 문제는 없는지 고민해보세요.
개인적으로 멀티스테이지로 컴파일하는게 제일 좋을 것 같다.
'dive'
github : https://github.com/wagoodman/dive/releases
# 맥 환경
brew install dive
# 윈도우 환경(gpt 자료 -> scoop 사용 or github[https://github.com/wagoodman/dive/releases])
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
iwr -useb get.scoop.sh | iex
scoop install dive
# dive 사용
dive hello:latest
여러 운영체제와 하드웨어 아키텍쳐 별 도커이미지 빌드.
요즈음 amd 의 시대에서 arm이 대두되는 만큼, 아키텍쳐 별 자동으로 구동될 수 있게, 멀티 플랫폼을 설정할 수 있다.
# 활성화
docker buildx create --use
# 플랫폼 설정
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
https://www.youtube.com/watch?v=dLap7vclQvo
Jenkins:
가장 널리 사용되는 오픈소스 CI/CD(지속적 통합/지속적 배포) 도구입니다
빌드, 테스트, 배포 과정을 자동화할 수 있게 해주는 자동화 서버입니다
플러그인 생태계가 매우 풍부하여 다양한 개발 도구들과 쉽게 통합할 수 있습니다
웹 인터페이스를 통해 파이프라인을 쉽게 구성하고 모니터링할 수 있습니다
Gogs:
Git 저장소를 자체 호스팅할 수 있게 해주는 가벼운 오픈소스 도구입니다
GitHub와 유사한 웹 인터페이스를 제공합니다
Go 언어로 작성되어 있어 가볍고 설치가 쉽습니다
이슈 트래킹, 위키, 풀 리퀘스트 등 기본적인 협업 기능을 제공합니다
작은 팀이나 개인 프로젝트에 적합한 Git 호스팅 솔루션입니다
# docker-compose.yaml
services:
jenkins:
container_name: jenkins
image: jenkins/jenkins
restart: unless-stopped
networks:
- cicd-network
ports:
- "8080:8080"
- "50000:50000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- jenkins_home:/var/jenkins_home
gogs:
container_name: gogs
image: gogs/gogs
restart: unless-stopped
networks:
- cicd-network
ports:
- "10022:22"
- "3000:3000"
volumes:
- gogs-data:/data
volumes:
jenkins_home:
gogs-data:
networks:
cicd-network:
driver: bridge
docker compose up -d
docker compose exec jenkins bash
docker compose exec gogs bash
==
docker exec -it jenkins bash
docker exec -it gogs bash
docker compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# b67846bb4f444fc88d2a22d91c96acfc
docker compose logs jenkins -f
도커 컨테이너 안에서 도커를 실행하는 방식 비교.
특징:
Jenkins 컨테이너 내부에 완전한 Docker 엔진을 설치하여 실행
완전히 격리된 환경에서 Docker 작업 수행
장점:
보안상 더 안전한 격리 환경 제공
호스트 Docker와 완전히 독립적으로 동작
단점:
성능 오버헤드가 큼
캐시 레이어를 공유할 수 없어 빌드 속도가 느림
권한 설정이 복잡하고 privileged 모드 필요
특징:
Jenkins 컨테이너에서 호스트의 Docker 소켓을 마운트하여 사용
/var/run/docker.sock을 볼륨으로 마운트
장점:
성능이 더 좋음
호스트의 Docker 캐시 활용 가능
설정이 비교적 간단
단점:
보안상 취약할 수 있음 (호스트 Docker에 직접 접근)
호스트 시스템에 영향을 미칠 수 있음
# Jenkins 컨테이너 내부에 도커 실행 파일 설치
docker compose exec --privileged -u root jenkins bash
-----------------------------------------------------
id
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update && apt install docker-ce-cli curl tree jq -y
docker info
docker ps
which docker
jenkins 컨테이너 안에서 호스트의 도커를 사용할 수 있게 되었다.
# Jenkins 컨테이너 내부에서 root가 아닌 jenkins 유저도 docker를 실행할 수 있도록 권한을 부여
groupadd -g 2000 -f docker
chgrp docker /var/run/docker.sock
ls -l /var/run/docker.sock
usermod -aG docker jenkins
cat /etc/group | grep docker
exit
permission denied가 발생한다.
# jenkins item 실행 시 docker 명령 실행 권한 에러 발생 : Jenkins 컨테이너 재기동으로 위 설정 내용을 Jenkins app 에도 적용 필요
docker compose restart jenkins
sudo docker compose restart jenkins # Windows 경우 이후부터 sudo 붙여서 실행하자
근데 여기서 permission denied가 발생한다.
sudo를 붙히면 해결되긴 한다.(??)
-> 그룹을 1001로 수정하면 해결된다.(호스트의 docker 그룹과, 해당 컨테이너의 docker 그룹 id가 다른게 원인이다.
# jenkins user로 docker 명령 실행 확인
sudo docker compose exec jenkins id
sudo docker compose exec jenkins docker info
sudo docker compose exec jenkins docker ps
아래 상자중 application URL 부분은 본인의 로컬 IP로 채운다.
25e3e2d03691116a10253aabcd1786dd139ef97f
신규 레포지토리 생성
Gogs 사용을 위한 저장소 설정 (Jenkins 안에서 git 작업)
#
docker compose exec jenkins bash
-----------------------------------
whoami
pwd
cd /var/jenkins_home/
tree
#
git config --global user.name "<Gogs 계정명>"
git config --global user.name "devops"
git config --global user.email "a@dkd.com"
git config --global init.defaultBranch main
#
git clone <각자 Gogs dev-app repo 주소>
git clone http://192.168.254.124:3000/devops/dev-app.git
Cloning into 'dev-app'...
Username for 'http://192.168.254.124:3000': devops # Gogs 계정명
Password for 'http://devops@192.168.254.124:3000': <토큰> # 혹은 계정암호
#
tree dev-app
cd dev-app
git branch
git remote -v
# server.py 파일 작성
cat > server.py <<EOF
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from datetime import datetime
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
now = datetime.now()
response_string = now.strftime("The time is %-I:%M:%S %p, CloudNeta Study.\n")
self.wfile.write(bytes(response_string, "utf-8"))
def startServer():
try:
server = ThreadingHTTPServer(('', 80), RequestHandler)
print("Listening on " + ":".join(map(str, server.server_address)))
server.serve_forever()
except KeyboardInterrupt:
server.shutdown()
if __name__== "__main__":
startServer()
EOF
# Dockerfile 생성
cat > Dockerfile <<EOF
FROM python:3.12
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app
CMD python3 server.py
EOF
# VERSION 파일 생성
echo "0.0.1" > VERSION
#
git add .
git commit -m "Add dev-app"
git push -u origin main
https://hub.docker.com/
접속해서 로그인하고 private 레포 하나 만들자.
Jenkins 관리 > Credentials > (global) > Add Credential
아까 gogs에서 가져온 토큰 값을 password에 넣는다.