저장소 목록, 사용자별 권한, Pull Request가 필요해지면 bare 저장소에 웹 서비스를 더할 수 있습니다. 이 글에서는 Gitea와 PostgreSQL을 별도 Compose 프로젝트로 실행합니다. 먼저 관리자 PC에서만 접속해 초기 설정을 끝내고, 팀에 공개할 주소는 그다음에 정합니다.
대상은 Docker Engine과 Compose 플러그인이 준비된 별도 Linux 실습 VM입니다. Rocky·Ubuntu의 Git 클라이언트 설치만으로 Docker가 설치되는 것은 아닙니다. Windows에서는 Docker Desktop의 Linux 컨테이너 환경을 사용할 수 있지만, Docker 설치 자체와 Windows의 실행 검증은 이 글 범위에 포함하지 않았습니다.
Git·GitOps 전체 연재 · 15 / 24
이 글의 목차
1. 버전과 영구 데이터 위치를 정한다
2026년 10월 18일 공식 릴리스에서 Gitea 28.1.0을 확인했습니다. DB는 PostgreSQL 17 계열을 사용합니다. Gitea 이미지는 릴리스 번호를 지정하고, DB는 메이저 버전을 고정해 의도하지 않은 메이저 전환을 피합니다. 운영 전에는 사용 시점의 보안 공지와 지원 버전을 다시 확인합니다.
mkdir -p ~/git-server-lab
cd ~/git-server-lab
docker version
docker compose version
umask 077
printf 'GITEA_DB_PASSWORD=%s\n' "$(openssl rand -hex 24)" > .env
생성한 .env에는 실제 비밀 값이 들어갑니다. 커밋하거나 공유 자료에 첨부하지 않습니다. 값을 잃지 않도록 서버 복구용 보관소에 접근을 제한해 저장합니다. Docker 명령 권한은 사실상 호스트의 높은 권한과 연결되므로 계정을 신중하게 관리합니다.
2. Compose 파일을 저장한다
다음 내용을 compose.yaml에 저장합니다. named volume을 사용하므로 현재 디렉터리 아래에 DB 파일이 보이지 않아도 영구 데이터는 Docker 볼륨에 남습니다. 이 경로를 몰라 백업에서 빠뜨리지 않도록 주의합니다.
name: maruops-git-lab
services:
gitea:
image: docker.gitea.com/gitea:28.1.0
restart: unless-stopped
environment:
USER_UID: '1000'
USER_GID: '1000'
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: db:5432
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: ${GITEA_DB_PASSWORD:?Set GITEA_DB_PASSWORD}
GITEA__server__DOMAIN: localhost
GITEA__server__ROOT_URL: http://localhost:13000/
GITEA__server__SSH_DOMAIN: localhost
GITEA__server__SSH_PORT: '12222'
GITEA__service__DISABLE_REGISTRATION: 'true'
ports:
- '127.0.0.1:13000:3000'
- '127.0.0.1:12222:22'
volumes:
- gitea-data:/data
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_DB: gitea
POSTGRES_USER: gitea
POSTGRES_PASSWORD: ${GITEA_DB_PASSWORD:?Set GITEA_DB_PASSWORD}
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U gitea -d gitea']
interval: 5s
timeout: 5s
retries: 20
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
gitea-data:
postgres-data:
호스트에는 13000과 12222를 사용하고 컨테이너 안에서는 각각 3000과 22로 연결합니다. VM의 SSH 관리 포트와 Gitea의 SSH 포트는 다른 목적입니다. DB의 5432 포트는 호스트에 공개하지 않습니다.
3. 시작하고 초기 관리자를 만든다
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=80 gitea
config --quiet는 문법과 변수 누락을 확인합니다. docker compose config 전체 출력을 외부에 공유하면 환경 변수의 비밀 값이 노출될 수 있어요. 상태에서 DB가 healthy인지 보고, 브라우저에서 http://localhost:13000/을 엽니다.
VM에서 실행했다면 PC의 localhost는 그 VM이 아닙니다. PC에서 SSH 터널을 열어 접속합니다. Git SSH도 쓸 계획이면 두 포트를 함께 전달합니다.
ssh -N -L 13000:127.0.0.1:13000 -L 12222:127.0.0.1:12222 labadmin@192.168.56.40
설치 화면의 DB 호스트는 db:5432, DB·사용자 이름은 gitea입니다. 관리자 계정 생성 항목에서 실제 관리자와 고유 비밀번호를 지정합니다. 가입 비활성화 설정은 유지하고 설치를 완료합니다. 앱 URL은 이 단계의 터널 접속 주소 http://localhost:13000/를 사용합니다.
4. 빈 저장소를 만들고 코드를 올린다
관리자와 별도로 일반 작업 계정을 사용하면 권한을 확인하기 좋습니다. 계정의 SSH 키 설정에 공개 키를 등록하고 gitops-demo라는 빈 저장소를 만듭니다. 계정명을 아래 YOUR_USER에 넣습니다.
cd ~/git-lab/gitops-demo
git remote add gitea ssh://git@localhost:12222/YOUR_USER/gitops-demo.git
git push gitea main
서버 호스트 키 지문을 먼저 확인합니다. 웹 화면에서 커밋과 파일이 보이면 저장소 전송과 조회를 연결한 상태입니다. PR 실습을 위해 기능 브랜치를 푸시하고 main을 대상으로 요청을 열어 볼 수 있습니다.
팀에 공개할 때 바뀌는 부분
127.0.0.1 바인딩은 외부 접속을 받지 않습니다. 팀용으로 전환할 때에는 신뢰하는 주소로 바인딩하고 HTTPS 역방향 프록시, 내부 DNS, 방화벽 허용 범위를 함께 구성합니다. ROOT_URL, DOMAIN, SSH_DOMAIN, SSH_PORT는 사용자가 실제 접속하는 주소와 일치해야 합니다.
컨테이너나 Kubernetes Pod의 localhost는 Gitea VM을 가리키지 않습니다. Jenkins와 Argo CD를 연결하기 전에는 그 실행 위치에서 실제 주소에 접속할 수 있어야 해요. TLS 검증을 끄기보다 올바른 CA와 서버 이름을 설정합니다.
종료는 docker compose down으로 진행하며 볼륨은 남습니다. down -v는 영구 볼륨을 지울 수 있으므로 정리 명령에 습관적으로 붙이지 않습니다. 구성의 기준은 Gitea Docker 설치와 데이터베이스 준비 안내입니다.
이전 글 · [Git·GitOps 14] 로컬 Git 서버 만들기: Rocky·Ubuntu의 bare 저장소와 SSH · 다음 글 · [Git·GitOps 16] Gitea 백업과 복원: 저장소만 복사하면 빠지는 데이터 · 연재 목록과 예제 파일

![[Git·GitOps 24] Git·CI/CD·GitOps 운영 흐름 완성하기: 장애별 판단과 복구](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-12-768x510.webp)
![[Git·GitOps 23] 비밀 값 관리: Secret의 base64와 SOPS·age 암호화](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-2-768x512.webp)
![[Git·GitOps 22] 변경 감지와 복구: 자동 Sync·selfHeal·prune·Git revert](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-10-768x576.webp)
답글 남기기