안쓰는 노트북을 Gitea 서버로 만들었다.
Docker로 Gitea 배포 과정
Docker Desktop설치docker-compose.yml로Gitea컨테이너 실행- Windows 방화벽과 공유기 포트 포워딩 설정
DuckDNS로 DDNS를 붙여서 공인 IP가 바뀌어도 다시 접근 가능하게 만들기
Docker Desktop
처음에는 Docker Desktop을 설치했다.
이번 작업에서는 Gitea를 로컬에 바로 설치하는 대신 컨테이너로 올리기로 했기 때문에,
실제 서버 파일을 직접 손대기보다 docker compose 기준으로 관리하는 쪽이 더 낫다고 봤다.
이 방식으로 가면 이후에 다시 띄우거나 내릴 때도 명령이 단순하다.
또 Gitea 자체를 다시 설치하는 게 아니라, 볼륨만 유지한 채 컨테이너를 교체할 수도 있다.
docker-compose.yml 설정
Gitea폴더에 docker-compose.yml 생성3000 포트로 웹, 222 포트로 SSH를 외부에 열고,
실제 데이터는 ./gitea:/data에 볼륨으로 남기는 구조다.
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- TZ=Asia/Seoul
restart: always
volumes:
- ./gitea:/data
ports:
- "3000:3000"
- "222:22"
컨테이너 실행
compose 파일이 있는 위치에서 서버를 올린다.
docker compose up -d

그 다음 바로 컨테이너 상태를 확인
docker ps

3000->3000, 222->22를 눈으로 확인.
gitea컨테이너가 떠 있는지 먼저 확인.- 웹으로
http://localhost:3000에 접근해서 초기 설치 페이지가 나오는지 확인.
Windows 방화벽
노트북 자체가 3000, 222를 받도록 Windows 방화벽 해제
New-NetFirewallRule -DisplayName "Gitea HTTP 3000" -Direction Inbound -Protocol TCP -LocalPort 3000 -Action Allow
New-NetFirewallRule -DisplayName "Gitea SSH 222" -Direction Inbound -Protocol TCP -LocalPort 222 -Action Allow
공유기
내 환경은 공유기가 하나가 아니라 두 단계 구조라서,
두번 고정 IP할당, 포트포워딩 했다.
상위
ㄴ 하위
ㄴ 노트북 (Docker - Gitea)
먼저 하위 공유기에서:
- 노트북
MAC을DHCP 고정 IP를 할당 - 그 노트북 IP로
3000,222포트 포워딩
그 다음 상위 공유기에서:
- 하위 공유기에 대해 고정 IP를 잡고
- 다시
3000,222를 하위 공유기 쪽으로 포워딩

외부 -> 상위 공유기 -> 하위 공유기 -> 노트북 -> Docker Gitea
여기까지 했으면 공인 IP로 3000포트 접근이 가능해진다.
모바일 데이터 통신같은걸로 외부 경로 진입을 확인할 수 있다.
공인 IP와 DDNS
집 인터넷 공인 IP가 계속 고정된다는 보장이 없기 때문에 도메인으로 접근하게 했다.DuckDNS를 사용했다.

먼저 DuckDNS에서 도메인을 만들고 토큰을 발급받은 뒤,
다음 명령으로 갱신이 되는지 확인
Invoke-WebRequest "https://www.duckdns.org/update?domains=duckdns가 준 도메인(duckdns.org 빼고 앞부분)&token=발급받은토큰&ip="
여기서 OK가 나오는지 확인
app.ini 설정
Gitea 설정
볼륨을 /data로 잡아뒀기 때문에 실제 설정 파일은 gitea\gitea\conf\app.ini 쪽을 수정했다.
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = duckdns에서 받아온 도메인
SSH_DOMAIN = duckdns에서 받아온 도메인
HTTP_PORT = 3000
ROOT_URL = http://duckdns에서 받아온 도메인:3000/
DISABLE_SSH = false
SSH_PORT = 222
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
DuckDNS 자동 갱신
공인 IP가 바뀔 수 있으니,
도메인 갱신도 수동이 아니라 자동으로 돌리도록 했다.
먼저 duckdns.ps1를 만들고,
갱신 요청과 로그 저장을 같이 넣었다.
Invoke-WebRequest "https://www.duckdns.org/update?domains=duckdns가 준 도메인(duckdns.org 빼고 앞부분)&token=발급받은토큰&ip=" | Out-File "log파일 경로"
그 다음 작업 스케줄러에 5분마다 돌도록 등록했다.
schtasks /Create /SC MINUTE /MO 5 /TN "DuckDNS Update" /TR "powershell.exe -ExecutionPolicy Bypass -File \경로\duckdns.ps1" /F
등록이 됐는지는 이렇게 다시 확인했다.
schtasks /Query /TN "DuckDNS Update"

이렇게 해두면 노트북이 켜져 있는 동안은 DuckDNS가 계속 현재 공인 IP를 따라간다.
최종 확인
컨테이너가 정상인지:
docker ps
도메인 갱신이 살아 있는지:
Invoke-WebRequest "https://www.duckdns.org/update?domains=duckdns가 준 도메인(duckdns.org 빼고 앞부분)&token=발급받은토큰&ip="
DNS가 실제로 어디를 보고 있는지:
nslookup duckdns에서 받아온 도메인
이렇게 최대 12월까지는 꺼지지 못하는 노트북을 만들었다.