[Unit]
Description=Disable ACT LED on boot
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 0 > /sys/class/leds/ACT/brightness'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
# 내용 확인
cat /sys/class/leds/ACT/brightness
# 서비스 확인
sudo systemctl status disable-act-led.service
# 재부팅
sudo reboot
# 상태 확인
cat /sys/class/leds/ACT/brightness
매일매일 공고를 확인하고, 수집하고, 적합한지 판단해서, 적합하면 저한테 텔레그램 메시지를 보내주도록 했습니다.. LLM분석은 토큰 비용이 들기 때문에, 무료로 일부 사용가능하고 속도도 빠른 Ollama Cloud모델로 분석을 시켰습니다...
매일 새벽1시에 수집하고, 새벽내내 분석해서 아침 9시에 텔레그램으로 요약해서 적합한것만... 보고합니다.
이런 프로그램 필요하신 분이 있을까요?
공공지원사업/입찰 공고를 자동으로 모으고 LLM으로 분석하는 OZ-BID 대시보드
기업마당 지원사업, 나라장터 SW 개발 용역, K-Startup 공고를 매일 확인하고 엑셀로 정리하는 일은 생각보다 많은 시간을 잡아먹습니다. 제목만 보고 넘어갔다가 중요한 첨부파일 조건을 놓치기도 하고, 담당자가 바뀌면 어떤 공고가 우리 회사에 맞는지 판단 기준도 흔들립니다.
OZ-BID는 이런 반복 업무를 줄이기 위해 만든 FastAPI 기반 공고 수집/분석 대시보드입니다. 공고 목록 수집, 첨부파일 다운로드, 첨부 본문 추출, LLM 적합도 분석, Telegram 알림, 운영 설정 화면까지 하나의 시스템으로 구성되어 있습니다.
공고 목록, 최신 LLM 점수, 분석 요약, 첨부파일 수를 한 화면에서 확인할 수 있는 메인 대시보드입니다.
핵심 가치
OZ-BID는 단순 크롤러가 아니라 “우리 회사에 맞는 공고를 빨리 찾는” 운영형 대시보드입니다.
여러 공고 소스를 한 화면에서 확인
첨부파일 내용까지 읽고 LLM으로 적합도 분석
적합도가 높은 공고는 Telegram으로 자동 알림
수집 시간, 요약 발송 시간, 분석 timeout, 회사 필터 프로필을 화면에서 변경
공고, 수집 로그, 분석 로그를 웹 대시보드에서 추적
FastAPI, PostgreSQL, Celery, Redis 기반으로 운영 확장 가능
수집 대상
현재 구현된 수집 대상은 다음과 같습니다.
기업마당 지원사업 공고
나라장터 SW 개발 용역 공고
K-Startup 모집중 공고
수집기는 소스별로 분리되어 있어 다른 공고 사이트를 추가하기 좋습니다. 수집된 공고는 PostgreSQL에 저장되고, 첨부파일은 로컬 data/attachments에 관리됩니다.
첨부파일 본문까지 분석
많은 공고의 핵심 조건은 제목이나 요약이 아니라 첨부파일 안에 있습니다. OZ-BID는 첨부파일을 다운로드한 뒤 Celery worker에서 본문을 추출하고, 그 내용을 LLM 분석 프롬프트에 포함합니다.
지원 형식:
PDF
DOCX
XLSX/XLSM
HWPX
HWP
API 서버에서 무거운 문서 분석을 직접 처리하지 않고 worker task로 분리했기 때문에, 웹 화면 응답성과 분석 작업을 독립적으로 운영할 수 있습니다.
LLM 적합도 분석
OZ-BID는 공고와 첨부 본문을 바탕으로 LLM 분석 결과를 저장합니다.
공고 상세 화면에서는 원문, 첨부파일, 적합도 점수, 수주 가능성, 필요 기술, 위험 요소를 함께 확인할 수 있습니다.
공고 적합도 판단은 회사마다 다릅니다. OZ-BID는 회사명, 소재지, 인증/자격, 주업무, 기술 강점, 수행 이력, 선호 공고 유형, 제외/감점 공고 유형 등을 DB 설정값으로 관리합니다.
운영자는 /ui/settings 화면에서 이 값을 직접 수정할 수 있습니다. .env를 수정하고 서버를 재시작하는 방식이 아니라, 대시보드에서 바꾼 값이 다음 분석과 수집 우선순위에 반영됩니다.
회사정보를 설정하여 분석시 참고하도록 합니다.
수집 시간, Telegram 요약 시간, 분석 timeout, 재분석 횟수, 수집 소스, 회사 필터 프로필을 화면에서 관리할 수 있습니다.
공고 대시보드
대시보드는 실제 운영자가 매일 보는 화면을 기준으로 구성했습니다.
주요 기능:
공고 목록 조회
공고 상세 화면
첨부파일 다운로드 상태 확인
최신 LLM 분석 결과 표시
키워드/기관/출처 필터
LLM 적합도 슬라이더 필터
슬라이더 변경 시 즉시 검색 적용
전체 데이터를 볼 수 있는 페이지네이션
페이지 이동 시 기존 필터 유지
초기에는 목록 제한만 있었지만, 운영 데이터가 쌓이면 모든 공고를 탐색할 수 있어야 합니다. 그래서 페이지네이션을 추가했고, LLM 적합도 필터는 숫자 입력 대신 슬라이더로 바꿔 빠르게 기준을 조절할 수 있게 했습니다.
로그와 운영 추적
운영 시스템은 “돌았는지 안 돌았는지”를 확인할 수 있어야 합니다. OZ-BID는 수집 로그와 분석 로그 화면을 제공합니다.
수집 로그 화면에서는 소스별 수집 결과, 생성/업데이트/분석 큐 등록 건수, 실패 메시지를 확인할 수 있습니다.
분석 로그 화면에서는 첨부 본문 추출과 LLM 분석의 시작/종료 시간, 분석 시간, 상태, 점수를 추적할 수 있습니다.
수집 실행 시간
소스별 수집 결과
생성/업데이트/분석 큐 등록 건수
분석 시작/종료 시간
분석 stage
분석 소요 시간
성공/실패 상태
실패 메시지
timeout 재분석 여부
분석 timeout을 초과한 running 작업은 failed 처리하고, 설정된 재시도 횟수 안에서 다시 분석 큐에 넣습니다.
Telegram 알림
분석이 끝난 공고 중 적합도 기준을 넘는 항목은 Telegram으로 개별 알림을 보냅니다. 또한 지정된 시간에 최근 분석 결과 요약을 발송할 수 있습니다.
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
TELEGRAM_NOTIFY_MIN_FIT_SCORE=80
PUBLIC_BASE_URL=http://사이트 주소를 입력
PUBLIC_BASE_URL을 설정하면 Telegram 메시지에서 바로 공고 상세 화면으로 이동할 수 있습니다.
OAuth 로그인
운영 대시보드는 Google, Naver, Kakao OAuth 로그인을 지원합니다.
공고 데이터와 분석 결과는 회사의 영업 전략과 입찰 판단 기준을 담고 있기 때문에, 대시보드는 처음부터 인증을 거쳐 접근하도록 구성되어 있습니다. OZ-BID는 로컬 계정 로그인과 주요 소셜 OAuth 로그인을 함께 지원해 운영 환경에 맞는 접근 방식을 선택할 수 있습니다.
Google OAuth
Naver OAuth
Kakao OAuth
로컬 관리자 계정 로그인
공통 허용 이메일/도메인 설정
provider별 callback URL 지원
로그아웃 시 세션 정리 후 로그인 화면 이동
특장점은 단순히 로그인 버튼을 붙인 수준이 아니라, 실제 내부 업무용 도구에 필요한 접근 제어 흐름을 갖췄다는 점입니다. 허용 이메일과 도메인을 공통 정책으로 관리할 수 있고, OAuth 제공자별 callback URL을 운영 외부 URL 기준으로 분리해 배포 환경에서도 일관되게 동작합니다. 로그아웃 후에는 JSON 응답이 아니라 로그인 화면으로 이동해, 사용자가 다시 자연스럽게 인증 흐름으로 돌아오도록 구성했습니다.
이 구조 덕분에 사내 담당자는 별도 계정 체계를 새로 만들지 않고도 기존 Google, Naver, Kakao 계정으로 접속할 수 있고, 운영자는 필요한 사용자만 허용 목록에 올려 대시보드 접근을 제한할 수 있습니다. 공고 수집, 첨부 분석, LLM 판단 결과처럼 민감할 수 있는 데이터를 다루는 시스템에 적합한 현실적인 보안 출발점입니다.
운영 아키텍처
OZ-BID는 역할을 분리해 운영합니다.
FastAPI Main: API와 대시보드 제공
Celery Worker: 수집, 첨부 본문 추출, LLM 분석 처리
Celery Beat: 매분 scheduler tick 실행
Redis: Celery broker/result backend
PostgreSQL: 공고, 분석 결과, 설정, 로그 저장
Ollama/OpenAI: LLM 분석
Telegram Bot API: 알림 발송
수집/분석 작업은 API 요청에서 직접 실행하지 않고 Celery task로 처리합니다. 웹 서버는 화면과 API에 집중하고, 오래 걸리는 작업은 worker가 담당합니다.
docker run --rm -d \
-v /home/user/ftp/data:/home/vsftpd \ # Local 경로 : 컨테이너 경로
-p 2020:20 \ # 데이터 포트
-p 2021:21 \ # 접속 및 제어 포트
-p 21100-21110:21100-21110 \ # PASV 포트
-e FTP_USER=test_user \ # 계정
-e FTP_PASS=change_me \ # 비번
--name vsftpd \ # 컨테이너이름
--restart=always \
fauria/vsftpd # 이미지 이름
공식 우분투 패키지 레포를 통하지 않고, nginx 에서 제공하는 패키지 레포를 통해 설치하도록 한다.
# 다음과 같이 키 정보를 등록
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
# 패키지 정보 등록
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
# 설치 진행
sudo apt update
sudo apt install nginx
----
# 부팅 시 Nginx 자동 시작 해제
sudo systemctl disable nginx
# 자동 재시작으로 다시 활성화 경우
sudo systemctl enable nginx
# 서비스 상태확인
sudo systemctl status nginx
## 제어 명령
# Nginx 시작 및 systemctl에 등록
sudo systemctl start nginx
#Nginx 중지
sudo systemctl stop nginx
# Nginx 재시작
sudo systemctl restart nginx
# Nginx 다시 로드
sudo systemctl reload nginx