feat: Add multi-architecture support and manifests creation

This commit is contained in:
Peifan Li
2025-12-25 12:39:43 -05:00
parent f3929e5e16
commit dec45d4234
4 changed files with 221 additions and 56 deletions

View File

@@ -5,79 +5,238 @@ DOCKER_PATH="/Applications/Docker.app/Contents/Resources/bin/docker"
USERNAME="franklioxygen"
VERSION=$1
BACKEND_LATEST="$USERNAME/mytube:backend-latest"
FRONTEND_LATEST="$USERNAME/mytube:frontend-latest"
if [ -n "$VERSION" ]; then
echo "🔖 Version specified: $VERSION"
BACKEND_VERSION_TAG="$USERNAME/mytube:backend-$VERSION"
FRONTEND_VERSION_TAG="$USERNAME/mytube:frontend-$VERSION"
fi
# Default build arguments (can be overridden by environment variables)
VITE_API_URL=${VITE_API_URL:-"http://localhost:5551/api"}
VITE_BACKEND_URL=${VITE_BACKEND_URL:-"http://localhost:5551"}
# Define platforms to build
PLATFORMS=("linux/amd64" "linux/arm64")
# Tag definitions
BACKEND_LATEST_AMD64="$USERNAME/mytube:backend-latest-amd64"
BACKEND_LATEST_ARM64="$USERNAME/mytube:backend-latest-arm64"
FRONTEND_LATEST_AMD64="$USERNAME/mytube:frontend-latest-amd64"
FRONTEND_LATEST_ARM64="$USERNAME/mytube:frontend-latest-arm64"
if [ -n "$VERSION" ]; then
echo "🔖 Version specified: $VERSION"
BACKEND_VERSION_AMD64="$USERNAME/mytube:backend-$VERSION-amd64"
BACKEND_VERSION_ARM64="$USERNAME/mytube:backend-$VERSION-arm64"
FRONTEND_VERSION_AMD64="$USERNAME/mytube:frontend-$VERSION-amd64"
FRONTEND_VERSION_ARM64="$USERNAME/mytube:frontend-$VERSION-arm64"
fi
# Ensure Docker is running
echo "🔍 Checking if Docker is running..."
$DOCKER_PATH ps > /dev/null 2>&1 || { echo "❌ Docker is not running. Please start Docker and try again."; exit 1; }
echo "✅ Docker is running!"
# Build backend image with no-cache to force rebuild
echo "🏗️ Building backend image..."
cd backend
$DOCKER_PATH build --no-cache --platform linux/amd64 -t $BACKEND_LATEST .
if [ -n "$VERSION" ]; then
$DOCKER_PATH tag $BACKEND_LATEST $BACKEND_VERSION_TAG
fi
cd ..
# Function to build backend for a specific platform
build_backend() {
local platform=$1
local tag=$2
local version_tag=$3
echo "🏗️ Building backend for $platform..."
cd backend
$DOCKER_PATH build --no-cache --platform $platform -t $tag .
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
$DOCKER_PATH tag $tag $version_tag
fi
echo "🚀 Pushing backend image: $tag"
$DOCKER_PATH push $tag
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
echo "🚀 Pushing backend version image: $version_tag"
$DOCKER_PATH push $version_tag
fi
echo "🧹 Cleaning up local backend image: $tag"
$DOCKER_PATH rmi $tag
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
$DOCKER_PATH rmi $version_tag
fi
cd ..
}
# Build frontend image with no-cache to force rebuild
echo "🏗️ Building frontend image with default localhost configuration..."
cd frontend
$DOCKER_PATH build --no-cache --platform linux/amd64 \
--build-arg VITE_API_URL="$VITE_API_URL" \
--build-arg VITE_BACKEND_URL="$VITE_BACKEND_URL" \
-t $FRONTEND_LATEST .
# Function to build frontend for a specific platform
build_frontend() {
local platform=$1
local tag=$2
local version_tag=$3
echo "🏗️ Building frontend for $platform..."
cd frontend
$DOCKER_PATH build --no-cache --platform $platform \
--build-arg VITE_API_URL="$VITE_API_URL" \
--build-arg VITE_BACKEND_URL="$VITE_BACKEND_URL" \
-t $tag .
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
$DOCKER_PATH tag $tag $version_tag
fi
echo "🚀 Pushing frontend image: $tag"
$DOCKER_PATH push $tag
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
echo "🚀 Pushing frontend version image: $version_tag"
$DOCKER_PATH push $version_tag
fi
echo "🧹 Cleaning up local frontend image: $tag"
$DOCKER_PATH rmi $tag
if [ -n "$VERSION" ] && [ -n "$version_tag" ]; then
$DOCKER_PATH rmi $version_tag
fi
cd ..
}
if [ -n "$VERSION" ]; then
$DOCKER_PATH tag $FRONTEND_LATEST $FRONTEND_VERSION_TAG
fi
cd ..
# Function to create and push manifest list
create_and_push_manifest() {
local manifest_tag=$1
local image_amd64=$2
local image_arm64=$3
# Push images to Docker Hub
echo "🚀 Pushing images to Docker Hub..."
$DOCKER_PATH push $BACKEND_LATEST
$DOCKER_PATH push $FRONTEND_LATEST
echo "📜 Creating manifest list: $manifest_tag"
# Try to remove existing manifest first to avoid errors
$DOCKER_PATH manifest rm $manifest_tag 2>/dev/null || true
if ! $DOCKER_PATH manifest create $manifest_tag \
--amend $image_amd64 \
--amend $image_arm64 2>/dev/null; then
echo "⚠️ Failed to create manifest list: $manifest_tag"
echo " This might happen if the images are not yet available in the registry."
echo " The platform-specific images are still available individually."
return 1
fi
if [ -n "$VERSION" ]; then
echo "🚀 Pushing versioned images..."
$DOCKER_PATH push $BACKEND_VERSION_TAG
$DOCKER_PATH push $FRONTEND_VERSION_TAG
echo "🚀 Pushing manifest list: $manifest_tag"
if ! $DOCKER_PATH manifest push $manifest_tag; then
echo "⚠️ Failed to push manifest list: $manifest_tag"
$DOCKER_PATH manifest rm $manifest_tag 2>/dev/null || true
return 1
fi
echo "🧹 Cleaning up local manifest: $manifest_tag"
$DOCKER_PATH manifest rm $manifest_tag 2>/dev/null || true
return 0
}
# Build for each platform
echo "🏗️ Building images for multiple platforms with separate tags..."
echo "Platforms: ${PLATFORMS[*]}"
echo ""
# Build backend for all platforms
for platform in "${PLATFORMS[@]}"; do
if [ "$platform" = "linux/amd64" ]; then
build_backend "$platform" "$BACKEND_LATEST_AMD64" "${BACKEND_VERSION_AMD64:-}"
elif [ "$platform" = "linux/arm64" ]; then
build_backend "$platform" "$BACKEND_LATEST_ARM64" "${BACKEND_VERSION_ARM64:-}"
fi
done
echo ""
# Build frontend for all platforms
for platform in "${PLATFORMS[@]}"; do
if [ "$platform" = "linux/amd64" ]; then
build_frontend "$platform" "$FRONTEND_LATEST_AMD64" "${FRONTEND_VERSION_AMD64:-}"
elif [ "$platform" = "linux/arm64" ]; then
build_frontend "$platform" "$FRONTEND_LATEST_ARM64" "${FRONTEND_VERSION_ARM64:-}"
fi
done
echo ""
# Create and push manifests
echo "📦 Creating and pushing manifests..."
MANIFEST_ERRORS=0
# Backend Manifests
if ! create_and_push_manifest "$USERNAME/mytube:backend-latest" "$BACKEND_LATEST_AMD64" "$BACKEND_LATEST_ARM64"; then
MANIFEST_ERRORS=$((MANIFEST_ERRORS + 1))
fi
# Clean up local images
echo "🧹 Cleaning up local images..."
$DOCKER_PATH rmi $BACKEND_LATEST
$DOCKER_PATH rmi $FRONTEND_LATEST
if [ -n "$VERSION" ]; then
$DOCKER_PATH rmi $BACKEND_VERSION_TAG
$DOCKER_PATH rmi $FRONTEND_VERSION_TAG
if ! create_and_push_manifest "$USERNAME/mytube:backend-$VERSION" "$BACKEND_VERSION_AMD64" "$BACKEND_VERSION_ARM64"; then
MANIFEST_ERRORS=$((MANIFEST_ERRORS + 1))
fi
fi
# Frontend Manifests
if ! create_and_push_manifest "$USERNAME/mytube:frontend-latest" "$FRONTEND_LATEST_AMD64" "$FRONTEND_LATEST_ARM64"; then
MANIFEST_ERRORS=$((MANIFEST_ERRORS + 1))
fi
if [ -n "$VERSION" ]; then
if ! create_and_push_manifest "$USERNAME/mytube:frontend-$VERSION" "$FRONTEND_VERSION_AMD64" "$FRONTEND_VERSION_ARM64"; then
MANIFEST_ERRORS=$((MANIFEST_ERRORS + 1))
fi
fi
if [ $MANIFEST_ERRORS -gt 0 ]; then
echo ""
echo "⚠️ Some manifest lists failed to create/push ($MANIFEST_ERRORS error(s))"
echo " Platform-specific images are still available and can be used directly."
fi
echo ""
echo "✅ Successfully built and pushed images to Docker Hub!"
echo "Backend image: $BACKEND_LATEST"
echo "Frontend image: $FRONTEND_LATEST"
echo ""
echo "Multi-architecture images (auto-selects platform):"
echo " - $USERNAME/mytube:backend-latest"
echo " - $USERNAME/mytube:frontend-latest"
if [ -n "$VERSION" ]; then
echo "Backend version: $BACKEND_VERSION_TAG"
echo "Frontend version: $FRONTEND_VERSION_TAG"
echo " - $USERNAME/mytube:backend-$VERSION"
echo " - $USERNAME/mytube:frontend-$VERSION"
fi
echo ""
echo "Platform-specific images (explicit architecture):"
echo " Backend:"
echo " - $BACKEND_LATEST_AMD64"
echo " - $BACKEND_LATEST_ARM64"
echo " Frontend:"
echo " - $FRONTEND_LATEST_AMD64"
echo " - $FRONTEND_LATEST_ARM64"
if [ -n "$VERSION" ]; then
echo ""
echo "Versioned platform-specific images:"
echo " Backend:"
echo " - $BACKEND_VERSION_AMD64"
echo " - $BACKEND_VERSION_ARM64"
echo " Frontend:"
echo " - $FRONTEND_VERSION_AMD64"
echo " - $FRONTEND_VERSION_ARM64"
fi
echo ""
echo "To deploy to your server or QNAP Container Station:"
echo "1. Upload the docker-compose.yml file to your server"
echo "2. Set environment variables in your docker-compose.yml file:"
echo "1. Use the multi-arch tags in docker-compose.yml (recommended):"
echo " - Docker will automatically select the correct architecture"
echo " - Example: franklioxygen/mytube:backend-latest"
echo ""
echo "2. Or use platform-specific tags for explicit control:"
echo " - For amd64: use tags ending with '-amd64'"
echo " - For arm64: use tags ending with '-arm64'"
echo ""
echo "3. Set environment variables in your docker-compose.yml file:"
echo " - VITE_API_URL=http://your-server-ip:port/api"
echo " - VITE_BACKEND_URL=http://your-server-ip:port"
echo "3. Use Container Station or Docker to deploy the stack using this compose file"
echo "4. Access your application at the configured port"
echo ""
echo "4. Use Container Station or Docker to deploy the stack"
echo "5. Access your application at the configured port"
echo ""
echo "Usage examples:"
echo " # Build both platforms with latest tags:"
echo " ./build-and-push.sh"
echo ""
echo " # Build both platforms with version tags:"
echo " ./build-and-push.sh 1.6.43"

View File

@@ -41,4 +41,4 @@ volumes:
networks:
mytube-network:
driver: bridge
driver: bridge

View File

@@ -2,6 +2,9 @@
This guide provides step-by-step instructions to deploy [MyTube](https://github.com/franklioxygen/MyTube "null") using Docker and Docker Compose. This setup is designed for standard environments (Linux, macOS, Windows) and modifies the original QNAP-specific configurations for general use.
> [!NOTE]
> **Multi-Architecture Support:** The official images support both **amd64** (x86_64) and **arm64** (Apple Silicon, Raspberry Pi, etc.) architectures. Docker will automatically pull the correct image for your system.
## 🚀 Quick Start (Pre-built Images)
The easiest way to run MyTube is using the official pre-built images.
@@ -133,7 +136,7 @@ If you prefer to build the images yourself (e.g., to modify code), follow these
1. **Clone the Repository:**
```
git clone [https://github.com/franklioxygen/MyTube.git](https://github.com/franklioxygen/MyTube.git)
git clone https://github.com/franklioxygen/MyTube.git
cd MyTube
```
@@ -141,7 +144,7 @@ If you prefer to build the images yourself (e.g., to modify code), follow these
Modify `docker-compose.yml`:
```
```yaml
services:
backend:
build: ./backend

View File

@@ -2,6 +2,9 @@
本指南提供了使用 Docker 和 Docker Compose 部署 [MyTube](https://github.com/franklioxygen/MyTube "null") 的详细步骤。此设置适用于标准环境Linux, macOS, Windows并针对通用用途修改了原本专用于 QNAP 的配置。
> [!NOTE]
> **多架构支持:** 官方镜像支持 **amd64** (x86_64) 和 **arm64** (Apple Silicon, Raspberry Pi 等) 架构。Docker 会自动为您的系统拉取极其正确的镜像。
## 🚀 快速开始 (使用预构建镜像)
运行 MyTube 最简单的方法是使用官方预构建的镜像。
@@ -133,7 +136,7 @@ docker-compose up -d
1. **克隆仓库:**
```
git clone [https://github.com/franklioxygen/MyTube.git](https://github.com/franklioxygen/MyTube.git)
git clone https://github.com/franklioxygen/MyTube.git
cd MyTube
```
@@ -141,7 +144,7 @@ docker-compose up -d
修改 `docker-compose.yml`
```
```yaml
services:
backend:
build: ./backend