Refactor Makefile to support both Docker and Podman, enhancing compatibility and flexibility

This commit is contained in:
2026-05-24 11:00:25 +08:00
parent eef80ca97d
commit 1b837ce502
+69 -55
View File
@@ -1,4 +1,4 @@
# Makefile for managing Podman Compose # Makefile for managing Docker or Podman
# Variables # Variables
COMPOSE_FILE=docker-compose.yml COMPOSE_FILE=docker-compose.yml
@@ -6,6 +6,7 @@ PROJECT_NAME=home
DB_VOLUME=home_app-db-data DB_VOLUME=home_app-db-data
BACKUP_DIR=./backups BACKUP_DIR=./backups
ENV_FILE=.env ENV_FILE=.env
CONTAINER_ENGINE?=podman
BUILD_NETWORK?=host BUILD_NETWORK?=host
IMAGE_TAG=$(if $(TAG),$(TAG),latest) IMAGE_TAG=$(if $(TAG),$(TAG),latest)
BACKEND_IMAGE?=$(DOCKER_IMAGE_BACKEND):$(IMAGE_TAG) BACKEND_IMAGE?=$(DOCKER_IMAGE_BACKEND):$(IMAGE_TAG)
@@ -16,6 +17,16 @@ FRONTEND_BUILD_NODE_ENV?=development
PLAYWRIGHT_BUILD_VITE_API_URL?=https://service.furyhawk.lol PLAYWRIGHT_BUILD_VITE_API_URL?=https://service.furyhawk.lol
PLAYWRIGHT_BUILD_NODE_ENV?=production PLAYWRIGHT_BUILD_NODE_ENV?=production
ifeq ($(CONTAINER_ENGINE),docker)
COMPOSE_CMD=$(CONTAINER_ENGINE) compose
NETWORK_EXISTS_CMD=$(CONTAINER_ENGINE) network inspect traefik-public >/dev/null 2>&1
else ifeq ($(CONTAINER_ENGINE),podman)
COMPOSE_CMD=$(CONTAINER_ENGINE) compose
NETWORK_EXISTS_CMD=$(CONTAINER_ENGINE) network exists traefik-public >/dev/null 2>&1
else
$(error Unsupported CONTAINER_ENGINE '$(CONTAINER_ENGINE)'. Use 'podman' or 'docker')
endif
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
CREATE_LOCAL_DIRS_CMD=powershell -NoProfile -Command "New-Item -ItemType Directory -Force -Path 'backend/htmlcov','frontend/blob-report','frontend/test-results' | Out-Null" CREATE_LOCAL_DIRS_CMD=powershell -NoProfile -Command "New-Item -ItemType Directory -Force -Path 'backend/htmlcov','frontend/blob-report','frontend/test-results' | Out-Null"
else else
@@ -34,48 +45,48 @@ ensure-local-dirs:
@echo "Local bind-mount directories are ready." @echo "Local bind-mount directories are ready."
network: network:
@podman network exists traefik-public || podman network create traefik-public @$(NETWORK_EXISTS_CMD) || $(CONTAINER_ENGINE) network create traefik-public
@echo "Traefik network ready." @echo "Traefik network ready."
up: network ensure-local-dirs up: network ensure-local-dirs
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
up-e2e: network ensure-local-dirs up-e2e: network ensure-local-dirs
podman compose --profile e2e --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d $(COMPOSE_CMD) --profile e2e --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
down: down:
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans
@echo "Containers stopped. Use 'make up' to start them again." @echo "Containers stopped. Use 'make up' to start them again."
build: build:
podman build --network $(BUILD_NETWORK) --no-cache -t $(BACKEND_IMAGE) -f backend/Dockerfile backend $(CONTAINER_ENGINE) build --network $(BUILD_NETWORK) --no-cache -t $(BACKEND_IMAGE) -f backend/Dockerfile backend
podman build --network $(BUILD_NETWORK) --no-cache -t $(FRONTEND_IMAGE) --build-arg VITE_API_URL=$(FRONTEND_BUILD_VITE_API_URL) --build-arg NODE_ENV=$(FRONTEND_BUILD_NODE_ENV) -f frontend/Dockerfile frontend $(CONTAINER_ENGINE) build --network $(BUILD_NETWORK) --no-cache -t $(FRONTEND_IMAGE) --build-arg VITE_API_URL=$(FRONTEND_BUILD_VITE_API_URL) --build-arg NODE_ENV=$(FRONTEND_BUILD_NODE_ENV) -f frontend/Dockerfile frontend
podman build --network $(BUILD_NETWORK) --no-cache -t $(PLAYWRIGHT_IMAGE) --build-arg VITE_API_URL=$(PLAYWRIGHT_BUILD_VITE_API_URL) --build-arg NODE_ENV=$(PLAYWRIGHT_BUILD_NODE_ENV) -f frontend/Dockerfile.playwright frontend $(CONTAINER_ENGINE) build --network $(BUILD_NETWORK) --no-cache -t $(PLAYWRIGHT_IMAGE) --build-arg VITE_API_URL=$(PLAYWRIGHT_BUILD_VITE_API_URL) --build-arg NODE_ENV=$(PLAYWRIGHT_BUILD_NODE_ENV) -f frontend/Dockerfile.playwright frontend
@echo "Containers built. Use 'make up' to start them." @echo "Containers built. Use 'make up' to start them."
restart: down build up restart: down build up
reset: reset:
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans -v $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans -v
podman system prune -f $(CONTAINER_ENGINE) system prune -f
podman volume prune -f $(CONTAINER_ENGINE) volume prune -f
podman network prune -f $(CONTAINER_ENGINE) network prune -f
podman pod prune -f @if [ "$(CONTAINER_ENGINE)" = "podman" ]; then $(CONTAINER_ENGINE) pod prune -f; fi
@echo "Environment completely reset. Use 'make build' then 'make up' to recreate." @echo "Environment completely reset. Use 'make build' then 'make up' to recreate."
deploy-local: network ensure-local-dirs build deploy-local: network ensure-local-dirs build
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
@echo "Local deployment completed using docker-compose.yml + docker-compose.override.yml" @echo "Local deployment completed using docker-compose.yml + docker-compose.override.yml"
deploy-production: network deploy-production: network
podman compose --env-file $(ENV_FILE) -f docker-compose.yml up -d --build $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml up -d --build
@echo "Production deployment completed using docker-compose.yml" @echo "Production deployment completed using docker-compose.yml"
backup: backup:
@mkdir -p $(BACKUP_DIR) @mkdir -p $(BACKUP_DIR)
$(eval TIMESTAMP := $(shell date +%Y%m%d_%H%M%S)) $(eval TIMESTAMP := $(shell date +%Y%m%d_%H%M%S))
podman volume export $(DB_VOLUME) --output $(BACKUP_DIR)/$(DB_VOLUME)_$(TIMESTAMP).tar $(CONTAINER_ENGINE) run --rm -v $(DB_VOLUME):/volume -v $(abspath $(BACKUP_DIR)):/backup alpine:3.22 tar -C /volume -cf /backup/$(DB_VOLUME)_$(TIMESTAMP).tar .
@echo "Backup created: $(BACKUP_DIR)/$(DB_VOLUME)_$(TIMESTAMP).tar" @echo "Backup created: $(BACKUP_DIR)/$(DB_VOLUME)_$(TIMESTAMP).tar"
restore: restore:
@@ -85,54 +96,57 @@ restore:
exit 1; \ exit 1; \
fi fi
@echo "Restoring from latest backup: $(LATEST_BACKUP)" @echo "Restoring from latest backup: $(LATEST_BACKUP)"
podman volume rm $(DB_VOLUME) || true $(CONTAINER_ENGINE) volume rm $(DB_VOLUME) || true
podman volume create --name $(DB_VOLUME) $(CONTAINER_ENGINE) volume create $(DB_VOLUME)
podman volume import $(DB_VOLUME) --input $(LATEST_BACKUP) $(CONTAINER_ENGINE) run --rm -v $(DB_VOLUME):/volume -v $(abspath $(BACKUP_DIR)):/backup alpine:3.22 sh -c "tar -C /volume -xf /backup/$(notdir $(LATEST_BACKUP))"
@$(CREATE_LOCAL_DIRS_CMD) @$(CREATE_LOCAL_DIRS_CMD)
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down --remove-orphans
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
@echo "Backup and restore completed." @echo "Backup and restore completed."
@echo "Please check the logs for any errors." @echo "Please check the logs for any errors."
@echo "Use 'make logs' to view the logs." @echo "Use 'make logs' to view the logs."
logs: logs:
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml logs $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml logs
@echo "Logs for all containers:" @echo "Logs for all containers:"
clean: clean:
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down
podman volume rm $(DB_VOLUME) $(CONTAINER_ENGINE) volume rm $(DB_VOLUME)
@echo "Cleaned up all containers and volumes." @echo "Cleaned up all containers and volumes."
prune: prune:
podman volume prune $(CONTAINER_ENGINE) volume prune
podman container prune $(CONTAINER_ENGINE) container prune
podman network prune $(CONTAINER_ENGINE) network prune
podman image prune $(CONTAINER_ENGINE) image prune
@echo "Pruned all stopped containers and unused volumes." @echo "Pruned all stopped containers and unused volumes."
help: help:
@echo "Makefile for managing Podman Compose" @echo "Makefile for managing Docker or Podman"
@echo "" @echo ""
@echo "Usage:" @echo "Usage:"
@echo " make <target> [CONTAINER_ENGINE=podman|docker]"
@echo " make network Create the traefik-public network if it doesn't exist" @echo " make network Create the traefik-public network if it doesn't exist"
@echo " make up Start the containers in detached mode" @echo " make up Start the containers in detached mode"
@echo " make up-e2e Start containers including the Playwright test service" @echo " make up-e2e Start containers including the Playwright test service"
@echo " make down Stop the containers" @echo " make down Stop the containers"
@echo " make logs View the logs of the containers" @echo " make logs View the logs of the containers"
@echo " make build Build backend, frontend, and Playwright images directly with Podman" @echo " make build Build backend, frontend, and Playwright images with the selected engine"
@echo " make restart Restart the containers" @echo " make restart Restart the containers"
@echo " make reset Completely reset Podman (containers, volumes, networks)" @echo " make reset Completely reset the selected engine state"
@echo " make deploy-local Deploy locally with development overrides" @echo " make deploy-local Deploy locally with development overrides"
@echo " make deploy-production Deploy with production compose file only" @echo " make deploy-production Deploy with production compose file only"
@echo " make backup Create a backup of the database volume" @echo " make backup Create a backup of the database volume"
@echo " make restore Restore the database volume from a backup" @echo " make restore Restore the database volume from a backup"
@echo " make clean Remove all containers and volumes" @echo " make clean Remove all containers and volumes"
@echo " make prune Remove all stopped containers and unused volumes" @echo " make prune Remove all stopped containers and unused volumes"
@echo " make info Display detailed information about Podman state" @echo " make info Display detailed information about the selected engine state"
@echo " make help View this help message" @echo " make help View this help message"
@echo " make ai-launcher Interactive AI backend launcher (recommended for new users)" @echo " make ai-launcher Interactive AI backend launcher (recommended for new users)"
@echo "" @echo ""
@echo "Defaults to Podman. Set CONTAINER_ENGINE=docker to use Docker instead."
@echo ""
@echo "Ollama-specific targets:" @echo "Ollama-specific targets:"
@echo " make ollama-build Build Ollama container with no cache (using host networking)" @echo " make ollama-build Build Ollama container with no cache (using host networking)"
@echo " make ollama-build-host Build Ollama container with host networking (alternative)" @echo " make ollama-build-host Build Ollama container with host networking (alternative)"
@@ -154,38 +168,38 @@ help:
@echo "" @echo ""
info: info:
@echo "===== Podman System Info =====" @echo "===== $(CONTAINER_ENGINE) System Info ====="
podman info $(CONTAINER_ENGINE) info
@echo "\n===== Podman Networks =====" @echo "\n===== $(CONTAINER_ENGINE) Networks ====="
podman network ls $(CONTAINER_ENGINE) network ls
@echo "\n===== Podman Volumes =====" @echo "\n===== $(CONTAINER_ENGINE) Volumes ====="
podman volume ls $(CONTAINER_ENGINE) volume ls
@echo "\n===== Podman Containers =====" @echo "\n===== $(CONTAINER_ENGINE) Containers ====="
podman ps -a $(CONTAINER_ENGINE) ps -a
@echo "\n===== Podman Images =====" @echo "\n===== $(CONTAINER_ENGINE) Images ====="
podman images $(CONTAINER_ENGINE) images
@echo "\n===== Podman Compose Config =====" @echo "\n===== Compose Config ====="
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml config $(COMPOSE_CMD) --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml config
# Ollama-specific targets # Ollama-specific targets
ollama-build: ollama-build:
cd ai_stack/ollama && DOCKER_BUILDKIT=0 podman compose build --no-cache cd ai_stack/ollama && DOCKER_BUILDKIT=0 $(COMPOSE_CMD) build --no-cache
@echo "Ollama container built with no cache. Use 'make ollama-up' to start it." @echo "Ollama container built with no cache. Use 'make ollama-up' to start it."
ollama-build-host: ollama-build-host:
cd ai_stack/ollama && DOCKER_BUILDKIT=0 podman build --network=host --no-cache -t localhost/ollama-server:latest . cd ai_stack/ollama && DOCKER_BUILDKIT=0 $(CONTAINER_ENGINE) build --network=host --no-cache -t localhost/ollama-server:latest .
@echo "Ollama container built with host networking. Use 'make ollama-up' to start it." @echo "Ollama container built with host networking. Use 'make ollama-up' to start it."
ollama-up: ollama-up:
cd ai_stack/ollama && podman compose up -d cd ai_stack/ollama && $(COMPOSE_CMD) up -d
@echo "Ollama container started. Use 'make pull-deepseek-model' to download and load the DeepSeek model." @echo "Ollama container started. Use 'make pull-deepseek-model' to download and load the DeepSeek model."
ollama-down: ollama-down:
cd ai_stack/ollama && podman compose down cd ai_stack/ollama && $(COMPOSE_CMD) down
@echo "Ollama container stopped." @echo "Ollama container stopped."
ollama-logs: ollama-logs:
cd ai_stack/ollama && podman compose logs -f cd ai_stack/ollama && $(COMPOSE_CMD) logs -f
pull-deepseek-model: pull-deepseek-model:
@echo "Pulling DeepSeek-R1 model from Hugging Face..." @echo "Pulling DeepSeek-R1 model from Hugging Face..."
@@ -199,23 +213,23 @@ setup-ollama: ollama-up
# LlamaCPP-specific targets # LlamaCPP-specific targets
llamacpp-build: llamacpp-build:
cd ai_stack/llamacpp && DOCKER_BUILDKIT=0 CONTAINERS_NETNS=slirp4netns podman compose build --no-cache cd ai_stack/llamacpp && DOCKER_BUILDKIT=0 CONTAINERS_NETNS=slirp4netns $(COMPOSE_CMD) build --no-cache
@echo "LlamaCPP container built with no cache. Use 'make llamacpp-up' to start it." @echo "LlamaCPP container built with no cache. Use 'make llamacpp-up' to start it."
llamacpp-build-host: llamacpp-build-host:
cd ai_stack/llamacpp && DOCKER_BUILDKIT=0 podman build --network=host --no-cache -t localhost/llama-cpp-server:latest . cd ai_stack/llamacpp && DOCKER_BUILDKIT=0 $(CONTAINER_ENGINE) build --network=host --no-cache -t localhost/llama-cpp-server:latest .
@echo "LlamaCPP container built with host networking. Use 'make llamacpp-up' to start it." @echo "LlamaCPP container built with host networking. Use 'make llamacpp-up' to start it."
llamacpp-up: llamacpp-up:
cd ai_stack/llamacpp && podman compose up -d cd ai_stack/llamacpp && $(COMPOSE_CMD) up -d
@echo "LlamaCPP container started. Use 'make pull-deepseek-llamacpp' to download the DeepSeek model." @echo "LlamaCPP container started. Use 'make pull-deepseek-llamacpp' to download the DeepSeek model."
llamacpp-down: llamacpp-down:
cd ai_stack/llamacpp && podman compose down cd ai_stack/llamacpp && $(COMPOSE_CMD) down
@echo "LlamaCPP container stopped." @echo "LlamaCPP container stopped."
llamacpp-logs: llamacpp-logs:
cd ai_stack/llamacpp && podman compose logs -f cd ai_stack/llamacpp && $(COMPOSE_CMD) logs -f
pull-deepseek-llamacpp: pull-deepseek-llamacpp:
@echo "Pulling DeepSeek-R1 model from Hugging Face for LlamaCPP..." @echo "Pulling DeepSeek-R1 model from Hugging Face for LlamaCPP..."