Linux 서버를 운영하고 자동화 작업을 시작하면 관리해야 할 파일이 점점 많아집니다. 처음에는 Shell Script 하나와 간단한 설정 파일 정도로 시작할 수 있지만, 시간이 지나면 Ansible Playbook, Docker Compose 파일, Nginx 설정, Kubernetes YAML, Terraform 코드 등 다양한 인프라 파일이 쌓이게 됩니다.
이러한 파일을 단순히 서버의 특정 디렉터리에 저장하거나 날짜를 붙여 복사하는 방식으로 관리하면 문제가 발생하기 쉽습니다.
예를 들어 다음과 같은 상황을 생각해 볼 수 있습니다.
nginx.conf
nginx.conf.old
nginx.conf.old2
nginx.conf.final
nginx.conf.final2
nginx.conf.real_final
어떤 파일이 실제 운영 중인 최신 설정인지 확인하기 어렵습니다. 또한 설정을 변경한 사람이 누구인지, 언제 변경했는지, 문제가 발생했을 때 이전 설정으로 어떻게 복구해야 하는지도 알기 어렵습니다.
이러한 문제를 해결하는 대표적인 도구가 Git이며, Git으로 관리하는 코드를 원격으로 저장하고 협업할 수 있는 대표적인 플랫폼이 GitHub입니다.
이번 글에서는 시스템 엔지니어와 DevOps 엔지니어를 위한 Git의 기본 개념부터 Repository, Commit, Branch, Merge, GitHub, .gitignore, 인프라 코드 관리 방법까지 실무 중심으로 알아보겠습니다.
Git은 파일과 코드의 변경 이력을 관리하는 **분산 버전 관리 시스템(Version Control System)**입니다.
Git을 사용하면 파일의 변경 내용을 기록하고 이전 상태로 돌아갈 수 있습니다.
일반적인 파일 관리 방식은 다음과 같습니다.
server.conf
server.conf.old
server.conf.backup
server.conf.final
server.conf.final2
Git을 사용하면 하나의 파일을 계속 관리하면서 변경 이력을 기록할 수 있습니다.
Commit 1
↓
Commit 2
↓
Commit 3
↓
현재 버전
문제가 발생하면 이전 Commit으로 돌아갈 수 있습니다.
따라서 Git은 단순히 개발자가 사용하는 소스 코드 관리 도구가 아닙니다. 시스템 엔지니어에게도 매우 중요한 도구입니다.
시스템 엔지니어가 관리하는 파일에는 다음과 같은 것들이 있습니다.
Shell Script
Ansible Playbook
Dockerfile
docker-compose.yml
Nginx 설정
Apache 설정
Kubernetes YAML
Terraform 코드
Monitoring 설정
CI/CD 설정
이러한 파일을 Git으로 관리하면 다음과 같은 장점이 있습니다.
변경 이력 관리
이전 버전 복구
설정 파일 비교
협업 가능
백업
자동 배포 연동
예를 들어 Nginx 설정을 변경했다고 가정해 보겠습니다.
Version 1
server {
listen 80;
}
설정을 수정합니다.
Version 2
server {
listen 80;
server_name example.com;
}
Git은 어떤 부분이 변경되었는지 기록합니다.
listen 80;
+ server_name example.com;
문제가 발생하면 변경 내용을 확인하거나 이전 버전으로 복구할 수 있습니다.
처음 Git을 공부할 때 가장 많이 혼동하는 부분입니다.
Git과 GitHub는 같은 것이 아닙니다.
Git은 내 컴퓨터에서 파일의 변경 이력을 관리하는 도구입니다.
GitHub는 Git Repository를 인터넷에 저장하고 공유할 수 있는 서비스입니다.
구조를 단순하게 표현하면 다음과 같습니다.
내 PC
|
| Git
v
Local Repository
|
| Push
v
GitHub
|
v
Remote Repository
즉,
Git = 버전 관리 도구
GitHub = Git 저장소를 관리하는 온라인 플랫폼
Git을 사용할 줄 안다고 해서 반드시 GitHub를 사용하는 것은 아니며, GitHub 없이도 내부 Git 서버를 운영할 수 있습니다.
기업 환경에서는 GitHub 외에도 GitLab과 같은 플랫폼을 사용하는 경우가 많습니다.
Git에서 프로젝트와 변경 이력을 관리하는 공간을 Repository, 줄여서 Repository 또는 Repo라고 합니다.
예를 들어 다음과 같은 프로젝트가 있다고 가정해 보겠습니다.
linux-infra/
├── ansible/
├── scripts/
├── docker/
├── nginx/
└── README.md
이 프로젝트 전체를 하나의 Git Repository로 관리할 수 있습니다.
Git 저장소를 생성하려면 프로젝트 디렉터리로 이동합니다.
cd linux-infra
그리고 Git을 초기화합니다.
git init
그러면 .git이라는 숨김 디렉터리가 생성됩니다.
linux-infra/
├── .git/
├── ansible/
├── scripts/
├── docker/
└── nginx/
.git 디렉터리에는 Git의 변경 이력과 내부 정보가 저장됩니다.
Git을 이해할 때 가장 중요한 것은 작업 흐름입니다.
기본 구조는 다음과 같습니다.
Working Directory
|
| git add
v
Staging Area
|
| git commit
v
Local Repository
|
| git push
v
Remote Repository
처음에는 복잡해 보이지만 실제로는 다음 순서입니다.
파일 수정
↓
git add
↓
변경 내용 선택
↓
git commit
↓
변경 이력 저장
↓
git push
↓
GitHub에 업로드
이 흐름을 이해하면 Git의 기본 사용법을 상당 부분 이해한 것입니다.
Git을 처음 설치한 후에는 사용자 정보를 설정합니다.
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
설정 내용을 확인하려면 다음 명령어를 사용합니다.
git config --global --list
Git Commit에는 일반적으로 변경을 기록한 작성자 정보가 포함됩니다.
따라서 개인 프로젝트와 회사 프로젝트의 계정이나 이메일 정책이 다르다면 환경에 맞게 관리할 필요가 있습니다.
Git에서 가장 자주 사용하는 명령어 중 하나가 git status입니다.
git status
현재 Repository에서 어떤 파일이 변경되었는지 확인할 수 있습니다.
예를 들어 Shell Script를 수정했다면 다음과 같은 상태를 확인할 수 있습니다.
modified: scripts/backup.sh
새로운 파일을 만들었다면 다음과 같이 표시될 수 있습니다.
Untracked files:
scripts/server_check.sh
서버 설정이나 자동화 코드를 수정하기 전후에 git status를 확인하는 습관은 매우 중요합니다.
Git은 파일을 수정했다고 자동으로 Commit하지 않습니다.
Commit할 변경 내용을 먼저 선택해야 합니다.
특정 파일을 추가하려면 다음과 같이 사용합니다.
git add scripts/backup.sh
모든 변경 내용을 추가하려면 다음과 같이 사용할 수 있습니다.
git add .
하지만 실무에서는 git add .를 무조건 사용하는 것보다 실제로 어떤 파일이 Commit되는지 확인하는 것이 좋습니다.
git status
특히 인프라 프로젝트에서는 실수로 다음과 같은 파일을 Commit하지 않도록 주의해야 합니다.
비밀번호
API Key
SSH Private Key
인증서 개인키
.env 파일
git add를 통해 변경 내용을 Staging Area에 등록했다면 Commit을 생성합니다.
git commit -m "Add server backup script"
Commit은 단순한 저장 버튼이 아닙니다.
프로젝트의 특정 시점과 변경 내용을 기록하는 작업입니다.
좋은 Commit 메시지의 예는 다음과 같습니다.
Add PostgreSQL backup script
Configure Nginx reverse proxy
Add SSH security settings
Fix Docker Compose environment variables
반대로 다음과 같은 메시지는 좋지 않습니다.
fix
test
update
aaa
나중에 변경 이력을 확인할 때 무엇을 변경했는지 알기 어렵기 때문입니다.
Repository의 변경 이력을 확인하려면 다음 명령어를 사용합니다.
git log
간단하게 확인하려면 다음과 같이 사용할 수 있습니다.
git log --oneline
예를 들어 다음과 같은 결과를 볼 수 있습니다.
a1b2c3d Add Nginx configuration
d4e5f6g Add PostgreSQL backup
g7h8i9j Initial infrastructure setup
이렇게 관리하면 서버 설정이 언제 어떻게 변경되었는지 추적할 수 있습니다.
인프라 코드 관리에서 매우 중요한 명령어가 git diff입니다.
git diff
파일의 변경 전과 변경 후 내용을 비교할 수 있습니다.
예를 들어 Nginx 설정을 변경했다면 다음과 같은 차이를 확인할 수 있습니다.
- listen 80;
+ listen 443 ssl;
실제 운영 서버에 적용하기 전에 변경 내용을 검토하는 습관은 매우 중요합니다.
특히 다음과 같은 파일은 변경 사항을 반드시 확인하는 것이 좋습니다.
nginx.conf
sshd_config
docker-compose.yml
Ansible Playbook
Terraform 코드
Kubernetes YAML
Branch는 기존 작업에 영향을 주지 않고 새로운 작업을 진행할 수 있는 독립적인 작업 공간입니다.
기본 구조는 다음과 같습니다.
main
|
+------ production code
새로운 기능을 개발하거나 설정을 변경할 때 Branch를 만들 수 있습니다.
main
|
+------ nginx-update
새 Branch를 생성하려면 다음과 같이 사용할 수 있습니다.
git branch nginx-update
해당 Branch로 이동합니다.
git switch nginx-update
또는 한 번에 생성과 이동을 할 수 있습니다.
git switch -c nginx-update
이제 nginx-update Branch에서 작업해도 기존 main Branch에는 직접 영향을 주지 않습니다.
Branch에서 작업을 완료했다면 변경 내용을 메인 Branch에 합칠 수 있습니다.
이를 Merge라고 합니다.
구조는 다음과 같습니다.
main
|
+---- Commit A
|
+---- Commit B
|
+---- nginx-update
|
+---- Commit C
+---- Commit D
작업이 완료되면 다음과 같이 변경 내용을 합칩니다.
nginx-update
|
v
Merge
|
v
main
실무에서는 변경 내용을 바로 운영 환경에 반영하기보다 검토와 테스트 과정을 거친 후 Merge하는 방식이 일반적입니다.
로컬에서 Git으로 프로젝트를 관리하는 것만으로도 버전 관리는 가능합니다.
하지만 GitHub와 연결하면 원격 백업과 협업이 가능해집니다.
기본적인 흐름은 다음과 같습니다.
Local Repository
|
| git push
v
GitHub Repository
GitHub에서 Repository를 만든 후 로컬 Repository에 원격 저장소를 등록합니다.
git remote add origin <원격_저장소_주소>
등록된 원격 저장소를 확인합니다.
git remote -v
이후 Branch를 원격 Repository에 Push할 수 있습니다.
git push -u origin main
이제 로컬에서 만든 Commit이 원격 Repository에도 저장됩니다.
Git 프로젝트에는 저장하면 안 되는 파일이 있습니다.
예를 들어 다음과 같습니다.
.env
*.log
*.key
id_rsa
id_ed25519
secrets.yml
이러한 파일을 GitHub에 Push하면 심각한 보안 문제가 발생할 수 있습니다.
이를 방지하기 위해 .gitignore 파일을 사용합니다.
예를 들어 다음과 같이 작성할 수 있습니다.
.env
*.log
*.key
*.pem
id_rsa
id_ed25519
__pycache__/
하지만 .gitignore는 이미 Commit된 민감한 정보를 자동으로 삭제하지 않습니다.
따라서 가장 중요한 원칙은 다음과 같습니다.
비밀번호, API Key, 개인키, 인증서 비밀정보는 처음부터 Git에 Commit하지 않는다.
인프라 코드에서는 데이터베이스 비밀번호나 API Key가 필요한 경우가 많습니다.
예를 들어 다음과 같은 설정은 매우 위험합니다.
database_password: MyPassword123
api_key: secret-key
이 파일을 GitHub에 공개하면 인증 정보가 노출될 수 있습니다.
보다 안전한 방법은 다음과 같습니다.
Git Repository
|
+-- 공개 가능한 코드
|
+-- .gitignore
|
+-- .env 제외
+-- secret 파일 제외
Ansible에서는 환경에 따라 Ansible Vault를 이용하여 민감한 값을 암호화하는 방법도 활용할 수 있습니다.
Ansible 프로젝트는 Git과 매우 잘 어울립니다.
예를 들어 다음과 같은 구조를 만들 수 있습니다.
linux-automation/
├── inventory/
│ ├── dev.ini
│ ├── stage.ini
│ └── prod.ini
│
├── playbooks/
│ ├── web.yml
│ ├── database.yml
│ └── security.yml
│
├── roles/
│ ├── common/
│ ├── nginx/
│ └── postgresql/
│
├── group_vars/
├── host_vars/
├── scripts/
└── README.md
이러한 구조를 Git으로 관리하면 모든 인프라 변경 사항을 코드로 추적할 수 있습니다.
Ansible 코드 변경
↓
Git Commit
↓
코드 검토
↓
테스트 환경 적용
↓
Merge
↓
운영 환경 적용
Git은 Ansible뿐 아니라 Docker와 함께 사용할 때도 매우 중요합니다.
예를 들어 다음과 같은 프로젝트를 관리할 수 있습니다.
my-service/
├── Dockerfile
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
├── backend/
├── frontend/
└── scripts/
이 모든 파일을 하나의 Repository로 관리할 수 있습니다.
작업 흐름은 다음과 같습니다.
코드 변경
↓
Git Commit
↓
GitHub Push
↓
CI/CD 실행
↓
Docker Image Build
↓
테스트
↓
서버 배포
이 구조는 이후 DevOps와 CI/CD의 핵심이 됩니다.
인프라 설정을 직접 운영 서버에서 수정하는 방식은 위험할 수 있습니다.
보다 안전한 방식은 다음과 같습니다.
1. Local에서 설정 수정
↓
2. git status 확인
↓
3. git diff로 변경 내용 검토
↓
4. 테스트 환경 적용
↓
5. git add
↓
6. git commit
↓
7. GitHub Push
↓
8. Pull Request 또는 코드 검토
↓
9. Merge
↓
10. 운영 서버 적용
이러한 방식을 사용하면 운영 환경의 설정 변경을 추적할 수 있습니다.
Git과 GitHub를 학습할 때는 실제 프로젝트를 만들어 보는 것이 좋습니다.
다음과 같은 Repository 구조를 추천합니다.
system-engineer-lab/
├── ansible/
│ ├── inventory.ini
│ └── webserver.yml
│
├── scripts/
│ ├── backup.sh
│ ├── disk_check.sh
│ └── service_check.sh
│
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yml
│
├── nginx/
│ └── nginx.conf
│
├── terraform/
│
├── README.md
└── .gitignore
이 프로젝트를 직접 운영하면서 다음과 같은 작업을 수행해 볼 수 있습니다.
1. Shell Script 작성
2. Git Repository 생성
3. 첫 번째 Commit 생성
4. GitHub 연결
5. Branch 생성
6. 설정 파일 변경
7. git diff 확인
8. Pull Request 생성
9. Merge
10. 서버 적용
Git과 GitHub를 사용하는 가장 큰 이유 중 하나는 이후 CI/CD 자동화와 연결할 수 있기 때문입니다.
예를 들어 다음과 같은 구조를 만들 수 있습니다.
개발자
|
v
Git Commit
|
v
GitHub Push
|
v
GitHub Actions
|
+-- Test
|
+-- Build
|
+-- Docker Image Build
|
+-- Image Registry Push
|
v
Deploy
코드가 GitHub에 Push되는 것을 시작점으로 자동화된 테스트와 빌드, 배포가 실행됩니다.
이것이 현대적인 DevOps 환경의 기본적인 흐름입니다.
과거의 시스템 관리는 서버에 직접 접속하여 설정 파일을 수정하는 방식이 많았습니다.
SSH 접속
↓
vi /etc/nginx/nginx.conf
↓
설정 수정
↓
서비스 재시작
하지만 이러한 방식은 변경 이력이 남지 않거나 다른 서버와 설정이 달라질 가능성이 있습니다.
Git을 활용하면 다음과 같이 관리할 수 있습니다.
Local에서 설정 수정
↓
Git으로 변경 이력 관리
↓
GitHub에 원격 저장
↓
테스트
↓
자동화 도구로 서버 적용
즉, Git은 단순히 코드를 저장하는 도구가 아니라 인프라 운영의 변경 이력과 표준을 관리하는 핵심 도구입니다.
Git과 GitHub는 현대적인 시스템 엔지니어와 DevOps 엔지니어에게 필수적인 기술입니다.
특히 다음과 같은 파일을 Git으로 관리하는 습관이 중요합니다.
Shell Script
Ansible Playbook
Dockerfile
Docker Compose
Nginx 설정
Kubernetes YAML
Terraform 코드
CI/CD 설정
Git의 핵심 작업 흐름은 다음과 같습니다.
파일 생성 또는 수정
↓
git status
↓
git diff
↓
git add
↓
git commit
↓
git push
↓
GitHub
그리고 실무에서는 단순히 파일을 저장하는 것보다 다음 원칙을 지키는 것이 중요합니다.
1. 운영 설정을 직접 수정하지 않는다.
2. 모든 중요한 변경 사항을 Git으로 기록한다.
3. Branch를 이용해 변경 작업을 분리한다.
4. git diff로 변경 내용을 검토한다.
5. 민감한 정보는 Commit하지 않는다.
6. .gitignore를 적극적으로 사용한다.
7. 테스트 후 운영 환경에 적용한다.
8. Ansible과 CI/CD를 연결하여 자동화한다.
시스템 엔지니어의 자동화 학습 과정은 다음과 같이 이어질 수 있습니다.
Linux 기본 운영
↓
Bash Shell
↓
Shell Script
↓
Cron
↓
Ansible
↓
Git / GitHub
↓
CI/CD
↓
Docker
↓
Kubernetes
↓
Terraform
↓
Cloud DevOps
Git과 GitHub까지 익히면 이제 단순히 서버를 직접 관리하는 수준을 넘어 서버 설정과 자동화 코드를 체계적으로 관리하는 기반을 갖추게 됩니다.