올인원 PhotoPrism 설치/관리 스크립트

1. 올인원 PhotoPrism 설치/관리 스크립트 1) 아래 스크립트를 그대로 복사하여 우분투 터미널에 붙여넣기 하신 후 엔터키만 누르면 스크립트 파일이 생성 됩니다. cat > setup-photoprism.sh <<'__SCRIPT__' #!/usr/bin/env bash set -euo pipefail # ========================================================== # PhotoPrism 올인원 설치기 (재귀 감시 즉시 반영 + WebDAV 업로드 허용) # - Docker/Compose 설치 # - MariaDB 연동 # - VAAPI 자동 감지 # - systemd 등록/자동 시작 # - WebDAV 기본 활성 (/import 업로드) # - AUTH_MODE=password, UPLOAD_NSFW=true, READONLY=false # - inotify 재귀감시로 업로드 즉시 import+index # - --update-site 로 PHOTOPRISM_SITE_URL 갱신 # ========================================================== # 루트 보장 if [[ $EUID -ne 0 ]]; then exec sudo -E bash "$0" "$@"; fi PORT="${PORT:-2342}" TZ="${TZ:-Asia/Seoul}" rand() { openssl rand -base64 24 | tr -d '\n=' | cut -c1-32; } trim() { echo -n "${1:-}" | tr -d '[:space:]'; } normalize_url() { local u="$(trim "${1:-}")" [ -z "$u" ] && { echo ""; return 0; } u="${u%/}"; [[ ! "$u" =~ ^https?:// ]] && u="https://$u"; echo "$u" } detect_vaapi() { [ -e /dev/dri ] && echo "true" || echo "false"; } ADMIN_USER="${SUDO_USER:-$USER}" ADMIN_HOME="$(getent passwd "$ADMIN_USER" | cut -d: -f6)" BASE_DIR="${ADMIN_HOME}/photoprism" DATA_DIR="${BASE_DIR}/data" ORIGINALS_DIR="${BASE_DIR}/originals" IMPORT_DIR="${BASE_DIR}/import" STORAGE_DIR="${BASE_DIR}/storage" ENV_FILE="${BASE_DIR}/.env" COMPOSE_FILE="${BASE_DIR}/docker-compose.yml" SERVICE_FILE="/etc/systemd/system/photoprism.service" INFO_FILE="${BASE_DIR}/INSTALL_INFO.txt" # ---- update-site 모드 ---- if [[ "${1:-}" == "--update-site" ]]; then if [ ! -f "$ENV_FILE" ]; then echo "[!] ${ENV_FILE} 없음. 먼저 설치하세요."; exit 1; fi SITE_URL_INPUT="${SITE_URL:-}" if [ -z "$(trim "$SITE_URL_INPUT")" ]; then read -rp "새 도메인 (예: photos.example.com): " SITE_URL_INPUT; fi NEW_URL="$(normalize_url "$SITE_URL_INPUT")" [ -z "$NEW_URL" ] && { echo "[!] 빈 값은 허용 안 함"; exit 1; } sed -i "s|^PHOTOPRISM_SITE_URL=.*|PHOTOPRISM_SITE_URL=${NEW_URL}|" "$ENV_FILE" systemctl restart photoprism NOW="$(date '+%Y-%m-%d %H:%M:%S')" echo "== 도메인 갱신 완료 =="; echo "시각: ${NOW}"; echo "새 주소: ${NEW_URL}" { echo; echo "# [도메인 갱신] ${NOW}"; echo "# PHOTOPRISM_SITE_URL=${NEW_URL}"; } >> "$INFO_FILE" exit 0 fi echo "==[ PhotoPrism 설치 ]==" echo "관리자: ${ADMIN_USER} 경로: ${BASE_DIR} 포트: ${PORT} TZ: ${TZ}" echo get_value() { local ENV_NAME="$1" PROMPT="$2" DTYPE="$3" DFIXED="${4:-}" local CUR="$(trim "${!ENV_NAME:-}")" if [ -n "$CUR" ]; then echo "$CUR"; return; fi read -rp "$PROMPT" CUR || true; CUR="$(trim "$CUR")" if [ -n "$CUR" ]; then echo "$CUR"; return; fi if [ "$DTYPE" = "random" ]; then rand; else echo "$DFIXED"; fi } ADMIN_ID="$(get_value ADMIN_ID "관리자 아이디(기본=admin): " fixed "admin")" ADMIN_PASS="$(get_value ADMIN_PASS "관리자 비번(엔터=랜덤): " random)" DB_ROOT_PASS="$(get_value DB_ROOT_PASS "DB root 비번(엔터=랜덤): " random)" DB_PASS="$(get_value DB_PASS "DB 사용자 비번(엔터=랜덤): " random)" SITE_URL_RAW="$(get_value SITE_URL "사이트 도메인(엔터=비움): " fixed "")" SITE_URL="$(normalize_url "$SITE_URL_RAW")" DB_NAME="photoprism"; DB_USER="photoprism" echo; echo "[적용값] ADMIN_ID=${ADMIN_ID} SITE_URL=${SITE_URL:-<비움>} PORT/TZ=${PORT}/${TZ}"; echo # ---- Docker 설치 ---- if ! command -v docker >/dev/null 2>&1; then echo "[*] Docker 설치 중..." apt update -y apt install -y ca-certificates curl gnupg lsb-release install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list apt update -y apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin usermod -aG docker "${ADMIN_USER}" || true fi apt install -y inotify-tools >/dev/null 2>&1 || true mkdir -p "${DATA_DIR}" "${ORIGINALS_DIR}" "${IMPORT_DIR}" "${STORAGE_DIR}" chown -R "${ADMIN_USER}:${ADMIN_USER}" "${BASE_DIR}" # ---- .env 생성 (업로드 허용 옵션 포함) ---- cat > "${ENV_FILE}" <<EOF PHOTOPRISM_ADMIN_USER=${ADMIN_ID} PHOTOPRISM_ADMIN_PASSWORD=${ADMIN_PASS} PHOTOPRISM_SITE_URL=${SITE_URL} PHOTOPRISM_ORIGINALS_PATH=/photoprism/originals PHOTOPRISM_IMPORT_PATH=/photoprism/import PHOTOPRISM_STORAGE_PATH=/photoprism/storage PHOTOPRISM_PUBLIC=false PHOTOPRISM_DISABLE_WEBDAV=false PHOTOPRISM_READONLY=false PHOTOPRISM_AUTH_MODE=password PHOTOPRISM_UPLOAD_NSFW=true PHOTOPRISM_WORKERS=2 PHOTOPRISM_AUTO_INDEX=1 UMASK=0002 TZ=${TZ} PHOTOPRISM_DATABASE_DRIVER=mysql PHOTOPRISM_DATABASE_SERVER=mariadb:3306 PHOTOPRISM_DATABASE_NAME=${DB_NAME} PHOTOPRISM_DATABASE_USER=${DB_USER} PHOTOPRISM_DATABASE_PASSWORD=${DB_PASS} PHOTOPRISM_FFMPEG_ENCODER=software EOF # ---- VAAPI 감지 ---- if [ "$(detect_vaapi)" = "true" ]; then sed -i 's/^PHOTOPRISM_FFMPEG_ENCODER=.*/PHOTOPRISM_FFMPEG_ENCODER=vaapi/' "${ENV_FILE}" HW_EXTRA="devices: - /dev/dri:/dev/dri" echo "[*] VAAPI 감지 → 하드웨어 가속 활성화" else HW_EXTRA="" echo "[*] VAAPI 미감지 → 소프트웨어 인코딩" fi # ---- docker-compose.yml ---- cat > "${COMPOSE_FILE}" <<EOF services: mariadb: image: docker.io/library/mariadb:11.4 container_name: photoprism-db restart: unless-stopped environment: - MARIADB_DATABASE=${DB_NAME} - MARIADB_USER=${DB_USER} - MARIADB_PASSWORD=${DB_PASS} - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASS} - MARIADB_AUTO_UPGRADE=1 - TZ=${TZ} volumes: - ${DATA_DIR}/mysql:/var/lib/mysql photoprism: image: docker.io/photoprism/photoprism:latest container_name: photoprism-app depends_on: - mariadb restart: unless-stopped env_file: - .env ports: - "${PORT}:2342" volumes: - ${ORIGINALS_DIR}:/photoprism/originals - ${IMPORT_DIR}:/photoprism/import - ${STORAGE_DIR}:/photoprism/storage $( [ -n "${HW_EXTRA}" ] && echo " ${HW_EXTRA}" ) EOF # ---- systemd: photoprism compose 서비스 ---- cat > "${SERVICE_FILE}" <<EOF [Unit] Description=PhotoPrism (Docker Compose) After=network-online.target docker.service Wants=network-online.target [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=${BASE_DIR} ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down TimeoutStartSec=0 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable photoprism # ---- 이미지 미리 당겨오기 (Docker Hub) ---- /usr/bin/docker pull docker.io/library/mariadb:11.4 || true /usr/bin/docker pull docker.io/photoprism/photoprism:latest || true # ---- 서비스 시작 ---- ( cd "$BASE_DIR" && /usr/bin/docker compose pull || true ) systemctl start photoprism # ========================= # 재귀 감시 → 즉시 import+index # ========================= # 1) 워처 스크립트 cat > /usr/local/bin/photoprism-reindex-watch.sh << "EOSH" #!/usr/bin/env bash set -euo pipefail CONTAINER="photoprism-app" WATCH_DIR="__IMPORT_DIR__" mkdir -p "$WATCH_DIR" reindex() { if ! /usr/bin/docker ps --format '{{.Names}}' | grep -qx "$CONTAINER"; then exit 0; fi /usr/bin/docker exec "$CONTAINER" photoprism import --path /photoprism/import --move -a || true /usr/bin/docker exec "$CONTAINER" photoprism index -a || true } # 중복 실행 방지 + 디바운스 exec 9>/tmp/photoprism-reindex.lock flock -n 9 || exit 0 # 최초 1회 reindex # 재귀 감시: 생성/이동/쓰기완료/삭제/속성변경 while inotifywait -r -e create,move,close_write,delete,attrib "$WATCH_DIR"; do sleep 3 reindex done EOSH sed -i "s|__IMPORT_DIR__|${IMPORT_DIR}|g" /usr/local/bin/photoprism-reindex-watch.sh chmod +x /usr/local/bin/photoprism-reindex-watch.sh # 2) 워처 서비스 (항상 실행) cat > /etc/systemd/system/photoprism-reindex-watch.service << "EOU" [Unit] Description=PhotoPrism recursive reindex watcher After=docker.service StartLimitIntervalSec=0 [Service] Type=simple User=root ExecStart=/usr/local/bin/photoprism-reindex-watch.sh Restart=always RestartSec=2 [Install] WantedBy=multi-user.target EOU systemctl daemon-reload systemctl enable --now photoprism-reindex-watch.service NOW="$(date '+%Y-%m-%d %H:%M:%S')" DEFAULT_ADDR="http://<서버IP>:${PORT}" SHOW_ADDR="${SITE_URL:-$DEFAULT_ADDR}" echo echo "== 설치 완료! ==" echo "설치 시각 : ${NOW}" echo "접속 주소 : ${SHOW_ADDR}" echo "관리자 계정: ${ADMIN_ID}" echo "관리자 비번: ${ADMIN_PASS}" echo "DB root 비번: ${DB_ROOT_PASS}" echo "DB 계정 : ${DB_USER} / ${DB_PASS}" cat > "${INFO_FILE}" <<EOF # ===== PhotoPrism 설치 정보 ===== 설치 시각 : ${NOW} 접속주소 : ${SHOW_ADDR} 관리자 : ${ADMIN_ID} 관리자PW : ${ADMIN_PASS} DB rootPW : ${DB_ROOT_PASS} DB 계정 : ${DB_USER} / ${DB_PASS} 경로 안내 : originals: ${ORIGINALS_DIR} import : ${IMPORT_DIR} storage : ${STORAGE_DIR} EOF cat >> "$0" <<EOF # ===== [설치 당시 계정/환경 기록] ===== # 설치 시각 : ${NOW} # 접속주소 : ${SHOW_ADDR} # 관리자 : ${ADMIN_ID} # 관리자PW : ${ADMIN_PASS} # DB rootPW : ${DB_ROOT_PASS} # DB 계정 : ${DB_USER} / ${DB_PASS} EOF echo echo "[관리]" echo " 상태 : systemctl status photoprism" echo " 재시작 : systemctl restart photoprism" echo " 중지 : systemctl stop photoprism" echo echo "[재귀 감시]" echo " 상태 : systemctl status photoprism-reindex-watch.service" echo " 로그 : journalctl -fu photoprism-reindex-watch.service" echo echo "[업데이트]" echo " cd ${BASE_DIR} && docker compose pull && systemctl restart photoprism" __SCRIPT__ 2) 실행 파일 권한 부여 chmod +x setup-photoprism.sh 3) 실행 방법 2가지 ( 2개중에 하나로 실행하면됨. ) ① 기본 실행 ( 중간 중간 암호 입력 하라는 메세지가 뜸.) sudo bash setup-photoprism.sh ② 환경 변수 추가하여 완전 자동 실행 ( 암호는 모두 동일하게 실행하고, 사이트 URL없는 경우 환경변수 삭제해도 됨 ) sudo env ADMIN_ID="우분투관리자ID" ADMIN_PASS="암호" DB_ROOT_PASS="암호" DB_PASS="암호" SITE_URL="photos.example.com" bash setup-photoprism.sh 4) 최초 PhotoPrism 설치 후 SITE_URL 도메인 주소가 추가 되었을 경우 아래 명령어를 입력하면 자동 수정됨. ① 도메인 주소만 바꿀 때 sudo SITE_URL="새로운 도메인 주소" bash setup-photoprism.sh --update-site 5) 설치 후 검사 ① sudo systemctl status photoprism ※ Active 항목에 active(exited)로 표시되면 정상 ② docker ps ※NAME에 Photoprism 이 들어가는 것들의 STATUS가 UP으로 되어 있으면 정상 2. 올인원 PhotoPrism 한방 제거 스크립트 cat > uninstall-photoprism.sh <<'__SCRIPT__' #!/usr/bin/env bash set -euo pipefail # ============================================ # PhotoPrism 완전 삭제 스크립트 # - systemd 서비스/패스 유닛 제거 # - Docker compose down(-v), 컨테이너/네트워크 정리 # - (옵션) 데이터 디렉터리 완전 삭제 # - (옵션) Docker 이미지 제거 # - (옵션) 설치 경로 변경 지원 # ============================================ # 기본값 (setup 스크립트와 동일) ADMIN_USER="${SUDO_USER:-${USER}}" ADMIN_HOME="$(getent passwd "$ADMIN_USER" | cut -d: -f6)" BASE_DIR="${BASE_DIR:-${ADMIN_HOME}/photoprism}" # 파일/유닛/이름들 SERVICE_FILE="/etc/systemd/system/photoprism.service" REINDEX_SVC="/etc/systemd/system/photoprism-reindex.service" REINDEX_PATH="/etc/systemd/system/photoprism-reindex.path" REINDEX_BIN="/usr/local/bin/photoprism-reindex.sh" COMPOSE_FILE="${BASE_DIR}/docker-compose.yml" ENV_FILE="${BASE_DIR}/.env" # 컨테이너 이름 APP_CTN="photoprism-app" DB_CTN="photoprism-db" PURGE_PHOTOS=false # originals/import/storage 포함 BASE_DIR 삭제 PURGE_IMAGES=false # docker images 삭제 NO_PROMPT=false # 파괴적 동작 확인 프롬프트 생략 usage() { cat <<USAGE PhotoPrism 완전 삭제 스크립트 사용법: sudo bash uninstall-photoprism.sh [옵션] 옵션: --purge 데이터 디렉터리까지 전부 삭제(BASE_DIR 내 originals/import/storage 포함) [영구 삭제] --purge-images photoprism/photoprism, mariadb 이미지까지 삭제 --base-dir PATH 설치 경로가 다를 때 지정(기본: \$HOME/photoprism) --yes 확인 프롬프트 생략(비대화식) 예시: sudo bash uninstall-photoprism.sh sudo bash uninstall-photoprism.sh --purge sudo bash uninstall-photoprism.sh --purge --purge-images sudo BASE_DIR=/DATA/photoprism bash uninstall-photoprism.sh --purge --yes USAGE } # 인자 파싱 while [[ $# -gt 0 ]]; do case "$1" in --purge) PURGE_PHOTOS=true; shift;; --purge-images) PURGE_IMAGES=true; shift;; --base-dir) BASE_DIR="$2"; shift 2;; --yes|-y) NO_PROMPT=true; shift;; -h|--help) usage; exit 0;; *) echo "[!] 알 수 없는 옵션: $1"; usage; exit 1;; esac done echo "==[ PhotoPrism 완전 삭제 ]==" echo "대상 경로 : ${BASE_DIR}" echo "서비스 : ${SERVICE_FILE}" echo "리인덱스 : ${REINDEX_SVC}, ${REINDEX_PATH}" echo "옵션 : purge_photos=${PURGE_PHOTOS} purge_images=${PURGE_IMAGES} no_prompt=${NO_PROMPT}" echo # 루트 권한 보장 if [[ $EUID -ne 0 ]]; then exec sudo BASE_DIR="${BASE_DIR}" PURGE_PHOTOS="${PURGE_PHOTOS}" PURGE_IMAGES="${PURGE_IMAGES}" NO_PROMPT="${NO_PROMPT}" bash "$0" "$@" fi confirm() { $NO_PROMPT && return 0 read -r -p "$1 [y/N]: " ans [[ "$ans" == "y" || "$ans" == "Y" ]] } # 1) systemd 유닛 중지/해제/삭제 echo "[1/6] systemd 유닛 정리..." systemctl stop photoprism 2>/dev/null || true systemctl disable photoprism 2>/dev/null || true rm -f "${SERVICE_FILE}" 2>/dev/null || true systemctl stop photoprism-reindex.path 2>/dev/null || true systemctl disable photoprism-reindex.path 2>/dev/null || true rm -f "${REINDEX_PATH}" 2>/dev/null || true systemctl stop photoprism-reindex.service 2>/dev/null || true systemctl disable photoprism-reindex.service 2>/dev/null || true rm -f "${REINDEX_SVC}" 2>/dev/null || true systemctl daemon-reload || true # 2) reindex 스크립트 삭제 echo "[2/6] reindex 실행 스크립트 삭제..." rm -f "${REINDEX_BIN}" 2>/dev/null || true # 3) docker compose down(-v) 또는 개별 컨테이너 제거 echo "[3/6] Docker 컨테이너/네트워크 정리..." if [[ -f "${COMPOSE_FILE}" ]]; then (cd "${BASE_DIR}" && docker compose down -v || true) else docker rm -f "${APP_CTN}" 2>/dev/null || true docker rm -f "${DB_CTN}" 2>/dev/null || true fi # 남은 네트워크 정리(있으면) docker network prune -f >/dev/null 2>&1 || true docker volume prune -f >/dev/null 2>&1 || true # 4) 이미지 제거(옵션) if [[ "${PURGE_IMAGES}" == "true" ]]; then echo "[4/6] Docker 이미지 제거..." docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}' \ | awk '/^photoprism\/photoprism:/ {print $2}' \ | xargs -r docker rmi || true docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}' \ | awk '/^mariadb:/ {print $2}' \ | xargs -r docker rmi || true fi # 5) 설정/데이터 삭제 echo "[5/6] 파일/디렉터리 정리..." if [[ -d "${BASE_DIR}" ]]; then if [[ "${PURGE_PHOTOS}" == "true" ]]; then if confirm "[!!] ${BASE_DIR} 전체(사진 포함)를 영구 삭제할까요?"; then rm -rf "${BASE_DIR}" echo "[OK] ${BASE_DIR} 전체 삭제 완료." else echo "[취소] 데이터 삭제를 건너뜁니다." # 설정 파일만 제거 rm -f "${COMPOSE_FILE}" "${ENV_FILE}" "${BASE_DIR}/INSTALL_INFO.txt" 2>/dev/null || true fi else echo "[i] 데이터는 보존하고 구성 파일만 삭제합니다." rm -f "${COMPOSE_FILE}" "${ENV_FILE}" "${BASE_DIR}/INSTALL_INFO.txt" 2>/dev/null || true # 비어있으면 디렉터리 제거 시도 rmdir "${BASE_DIR}/data" 2>/dev/null || true rmdir "${BASE_DIR}" 2>/dev/null || true fi else echo "[i] ${BASE_DIR} 가 존재하지 않습니다(건너뜀)." fi # 6) 최종 정리 메시지 echo echo "== 정리 완료 ==" echo "- 남은 이미지 일괄 정리: docker image prune -a" echo "- 남은 볼륨 정리: docker volume prune" echo "- (재설치) setup-photoprism.sh 로 다시 설치하세요." __SCRIPT__ 2) 실행 파일 권한 부여 chmod +x uninstall-photoprism.sh 3) 실행 방법 ① 기본 제거(사진 보존) sudo bash uninstall-photoprism.sh ② 사진까지 전부 삭제(영구 삭제!) sudo bash uninstall-photoprism.sh --purge ③ 이미지(photoprism, mariadb)까지 지우고 싶다면: sudo bash uninstall-photoprism.sh --purge --purge-images ④ 설치 경로를 바꿔서 설치했었다면 sudo BASE_DIR=설치경로 bash uninstall-photoprism.sh --purge

공개 마지막 업데이트: 2025-09-25 11:38:52 AM