-
-
Notifications
You must be signed in to change notification settings - Fork 6
Add Pluton app Docker setup and CI workflow #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dragonfire1119
wants to merge
2
commits into
main
Choose a base branch
from
add-pluton
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| name: "Build and release for pluton" | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| pluton_version: | ||
| description: 'Pluton version tag (e.g., "latest" or commit sha)' | ||
| required: false | ||
| default: 'latest' | ||
| schedule: | ||
| - cron: '0 2 * * 1' # Weekly | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - 'Apps/pluton/**' | ||
| - '.github/workflows/build_and_release_for_pluton.yaml' | ||
|
|
||
| env: | ||
| IMAGE_NAME: bigbeartechworld/big-bear-pluton | ||
| DOCKERFILE_PATH: Apps/pluton | ||
|
|
||
| jobs: | ||
| check-pluton-release: | ||
| name: Check Pluton Latest Release | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| pluton_version: ${{ steps.get_version.outputs.version }} | ||
| should_build: ${{ steps.check_build.outputs.should_build }} | ||
| steps: | ||
| - name: Get Latest Pluton Commit | ||
| id: get_version | ||
| run: | | ||
| if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ github.event.inputs.pluton_version }}" != "latest" ]; then | ||
| VERSION="${{ github.event.inputs.pluton_version }}" | ||
| else | ||
| # Get latest commit SHA from GitHub API with validation | ||
| RESPONSE=$(curl -s -w "%{http_code}" https://api.github.com/repos/plutonhq/pluton/commits/main) | ||
| HTTP_CODE=${RESPONSE: -3} | ||
| CONTENT=${RESPONSE:0:${#RESPONSE}-3} | ||
|
|
||
| if [ "$HTTP_CODE" != "200" ]; then | ||
| echo "Error: GitHub API returned status $HTTP_CODE" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$CONTENT" ]; then | ||
| echo "Error: Empty response from GitHub API" | ||
| exit 1 | ||
| fi | ||
|
|
||
| VERSION=$(echo "$CONTENT" | jq -r '.sha' | cut -c1-7) | ||
|
|
||
| if [[ ! "$VERSION" =~ ^[0-9a-f]{7}$ ]]; then | ||
| echo "Error: Invalid version format received: $VERSION" | ||
| exit 1 | ||
| fi | ||
| fi | ||
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | ||
| echo "Pluton version: ${VERSION}" | ||
|
|
||
| - name: Check if image exists | ||
| id: check_image | ||
| if: github.event_name == 'schedule' | ||
| run: | | ||
| VERSION="${{ steps.get_version.outputs.version }}" | ||
| # Check if image with this tag already exists | ||
| CODE=$(curl --silent --max-time 10 -o /dev/null -w "%{http_code}" https://hub.docker.com/v2/repositories/${{ env.IMAGE_NAME }}/tags/${VERSION}) | ||
|
|
||
| if [ "$CODE" = "000" ] || [ -z "$CODE" ]; then | ||
| echo "Error: Failed to check Docker Hub (curl error)" | ||
| echo "exists=unknown" >> "$GITHUB_OUTPUT" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ "$CODE" == "200" ]; then | ||
| echo "Image exists" | ||
| echo "exists=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "Image does not exist" | ||
| echo "exists=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Check if Build Needed | ||
| id: check_build | ||
| run: | | ||
| if [ "${{ github.event_name }}" == "workflow_dispatch" ] || [ "${{ github.event_name }}" == "push" ]; then | ||
| echo "should_build=true" >> "$GITHUB_OUTPUT" | ||
| elif [ "${{ steps.check_image.outputs.exists }}" == "false" ]; then | ||
| echo "should_build=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "should_build=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| build-and-push: | ||
| name: Build and Push | ||
| needs: check-pluton-release | ||
| if: needs.check-pluton-release.outputs.should_build == 'true' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Log in to Docker Hub | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Extract metadata (tags, labels) | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| images: ${{ env.IMAGE_NAME }} | ||
| tags: | | ||
| type=raw,value=latest | ||
| type=raw,value=${{ needs.check-pluton-release.outputs.pluton_version }} | ||
|
|
||
| - name: Build and push Docker image | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| context: ${{ env.DOCKERFILE_PATH }} | ||
| push: true | ||
| platforms: linux/amd64,linux/arm64 | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| # Stage 0: Clone | ||
| FROM alpine:latest as source | ||
| RUN apk add --no-cache git | ||
| WORKDIR /src | ||
| ARG PLUTON_VERSION=1a2986b2d59ecd49e82a19df4afa8066b70a20af | ||
| RUN git clone https://github.com/plutonhq/pluton.git . && \ | ||
| git checkout ${PLUTON_VERSION} | ||
|
|
||
| ARG APP_VERSION=0.0.1 | ||
| ARG RESTIC_VERSION=0.18.1 | ||
| ARG RCLONE_VERSION=1.71.2 | ||
|
|
||
| # Stage 1: Dependencies | ||
| FROM node:24-alpine AS deps | ||
| RUN corepack enable && corepack prepare pnpm@latest --activate | ||
| WORKDIR /workspace | ||
| COPY --from=source /src/package.json /src/pnpm-workspace.yaml /src/pnpm-lock.yaml /src/turbo.json ./ | ||
| COPY --from=source /src/frontend/package.json ./frontend/package.json | ||
| COPY --from=source /src/backend/package.json ./backend/package.json | ||
| RUN pnpm install --frozen-lockfile | ||
|
|
||
| # Stage 2: Frontend Builder | ||
| FROM node:24-alpine AS frontend-builder | ||
| RUN corepack enable && corepack prepare pnpm@latest --activate | ||
| WORKDIR /workspace | ||
| COPY --from=deps /workspace/node_modules ./node_modules | ||
| COPY --from=deps /workspace/pnpm-lock.yaml ./ | ||
| COPY --from=source /src ./ | ||
| RUN pnpm install --frozen-lockfile | ||
| RUN pnpm --filter @plutonhq/core-frontend build | ||
|
|
||
| # Stage 3: Backend Builder | ||
| FROM node:24-alpine AS backend-builder | ||
| RUN corepack enable && corepack prepare pnpm@latest --activate | ||
| WORKDIR /workspace | ||
| COPY --from=deps /workspace/node_modules ./node_modules | ||
| COPY --from=deps /workspace/pnpm-lock.yaml ./ | ||
| COPY --from=source /src ./ | ||
| COPY --from=frontend-builder /workspace/frontend/dist ./frontend/dist | ||
| RUN pnpm install --frozen-lockfile | ||
| RUN pnpm --filter @plutonhq/core-backend build | ||
| RUN pnpm --filter @plutonhq/core-backend deploy --prod --legacy /deploy | ||
|
|
||
| # Stage 4: Runner | ||
| FROM node:24-alpine AS runner | ||
| WORKDIR /app | ||
| RUN apk add --no-cache curl ca-certificates fuse3 bash su-exec | ||
|
|
||
| # Create data directory and set permissions | ||
| RUN mkdir -p /data /data/logs /data/db /data/config && \ | ||
| chown -R node:node /data /app | ||
|
|
||
| # Download specific versions of restic and rclone binaries | ||
| ARG TARGETARCH | ||
| ARG RESTIC_VERSION=0.18.1 | ||
| ARG RCLONE_VERSION=1.71.2 | ||
|
|
||
| # Checksums | ||
| ARG RESTIC_SHA256_AMD64=680838f19d67151adba227e1570cdd8af12c19cf1735783ed1ba928bc41f363d | ||
| ARG RESTIC_SHA256_ARM64=87f53fddde38764095e9c058a3b31834052c37e5826d2acf34e18923c006bd45 | ||
| ARG RCLONE_SHA256_AMD64=ab9fa5877cee91c64fdfd61a27028a458cf618b39259e5c371dc2ec34a12e415 | ||
| ARG RCLONE_SHA256_ARM64=e2e2efc7ed143026352d60216ef0d46d3fa4fe9d647eff1bd929e6fea498e6f1 | ||
|
|
||
| RUN echo "Building for architecture: ${TARGETARCH}" && \ | ||
| echo "Installing restic v${RESTIC_VERSION} and rclone v${RCLONE_VERSION}" && \ | ||
| # Download restic | ||
| if [ "${TARGETARCH}" = "amd64" ]; then \ | ||
| wget -q "https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2" -O /tmp/restic.bz2; \ | ||
| echo "${RESTIC_SHA256_AMD64} /tmp/restic.bz2" | sha256sum -c -; \ | ||
| elif [ "${TARGETARCH}" = "arm64" ]; then \ | ||
| wget -q "https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_arm64.bz2" -O /tmp/restic.bz2; \ | ||
| echo "${RESTIC_SHA256_ARM64} /tmp/restic.bz2" | sha256sum -c -; \ | ||
| fi && \ | ||
| bunzip2 /tmp/restic.bz2 && \ | ||
| mv /tmp/restic /usr/local/bin/restic && \ | ||
| chmod +x /usr/local/bin/restic && \ | ||
| # Download rclone | ||
| if [ "${TARGETARCH}" = "amd64" ]; then \ | ||
| wget -q "https://downloads.rclone.org/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-amd64.zip" -O /tmp/rclone.zip; \ | ||
| echo "${RCLONE_SHA256_AMD64} /tmp/rclone.zip" | sha256sum -c -; \ | ||
| elif [ "${TARGETARCH}" = "arm64" ]; then \ | ||
| wget -q "https://downloads.rclone.org/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-arm64.zip" -O /tmp/rclone.zip; \ | ||
| echo "${RCLONE_SHA256_ARM64} /tmp/rclone.zip" | sha256sum -c -; \ | ||
| fi && \ | ||
| apk add --no-cache unzip && \ | ||
| unzip -q /tmp/rclone.zip -d /tmp && \ | ||
| mv /tmp/rclone-*/rclone /usr/local/bin/rclone && \ | ||
| chmod +x /usr/local/bin/rclone && \ | ||
| rm -rf /tmp/rclone* && \ | ||
| apk del unzip && \ | ||
| # Verify installations | ||
| unset RESTIC_VERSION RCLONE_VERSION && \ | ||
| restic version && \ | ||
| rclone version | ||
|
|
||
| # Create Pluton wrapper scripts for rclone and restic | ||
| RUN echo '#!/bin/sh' > /usr/local/bin/prclone && \ | ||
| echo '# Pluton Wrapper for rclone' >> /usr/local/bin/prclone && \ | ||
| echo 'exec /usr/local/bin/rclone --config /data/config/rclone.conf "$@"' >> /usr/local/bin/prclone && \ | ||
| chmod +x /usr/local/bin/prclone && \ | ||
| echo '#!/bin/sh' > /usr/local/bin/prestic && \ | ||
| echo '# Pluton Wrapper for restic' >> /usr/local/bin/prestic && \ | ||
| echo 'export RCLONE_CONFIG=/data/config/rclone.conf' >> /usr/local/bin/prestic && \ | ||
| echo 'exec /usr/local/bin/restic -o rclone.program=/usr/local/bin/rclone "$@"' >> /usr/local/bin/prestic && \ | ||
| chmod +x /usr/local/bin/prestic | ||
|
|
||
| COPY --from=backend-builder /deploy ./ | ||
| COPY --from=source /src/backend/drizzle ./drizzle | ||
| COPY --from=backend-builder /workspace/backend/loader.mjs ./loader.mjs | ||
| COPY --from=frontend-builder /workspace/frontend/dist ./public | ||
| COPY entrypoint.sh /entrypoint.sh | ||
| RUN chmod +x /entrypoint.sh | ||
|
|
||
| ARG APP_VERSION | ||
| ENV NODE_ENV=production \ | ||
| IS_DOCKER=true \ | ||
| SERVER_PORT=5173 \ | ||
| APP_VERSION=${APP_VERSION} | ||
|
|
||
| EXPOSE 5173 | ||
|
|
||
| ENTRYPOINT ["/entrypoint.sh"] | ||
| CMD ["node", "--loader", "./loader.mjs", "dist/index.js"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 0.0.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| services: | ||
| big-bear-pluton: | ||
| build: .. | ||
| image: bigbeartechworld/big-bear-pluton:latest | ||
| container_name: big-bear-pluton | ||
| restart: unless-stopped | ||
| ports: | ||
| - "5173:5173" | ||
| environment: | ||
| SECRET: ${SECRET:-CHANGE_ME_SECRET_KEY_123} | ||
| ENCRYPTION_KEY: ${ENCRYPTION_KEY:-CHANGE_ME_ENCRYPTION_KEY_123} | ||
| APIKEY: ${APIKEY:-CHANGE_ME_API_KEY_123} | ||
| USER_NAME: ${USER_NAME:-admin} | ||
| USER_PASSWORD: ${USER_PASSWORD:-password} | ||
| APP_TITLE: ${APP_TITLE:-Pluton} | ||
| APP_URL: ${APP_URL:-http://localhost:5173} | ||
| SERVER_PORT: ${SERVER_PORT:-5173} | ||
| volumes: | ||
| - big_bear_pluton_data:/data | ||
| healthcheck: | ||
| test: ["CMD", "curl", "-f", "http://localhost:5173/"] | ||
| interval: 30s | ||
| timeout: 10s | ||
| retries: 3 | ||
| start_period: 30s | ||
|
|
||
| volumes: | ||
| big_bear_pluton_data: | ||
| driver: local |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| { | ||
| "name": "Pluton", | ||
| "description": "A modern, self-hosted backup solution for secure, encrypted backups across local and cloud storage.", | ||
| "version": "latest", | ||
| "category": "Backup", | ||
| "tags": ["backup", "restic", "rclone", "self-hosted", "encrypted"], | ||
| "platform": "linux/amd64,linux/arm64", | ||
| "logo": "https://pluton.b-cdn.net/logo.png", | ||
| "documentation": "https://docs.usepluton.com/", | ||
| "github": "https://github.com/plutonhq/pluton", | ||
| "ports": { | ||
| "5173/tcp": "Pluton Web UI" | ||
| }, | ||
| "volumes": { | ||
| "/data": "Pluton data directory" | ||
| }, | ||
| "environment": { | ||
| "SECRET": { | ||
| "description": "Master encryption key for securing sensitive data (min 12 chars)", | ||
| "default": "CHANGE_ME_SECRET_KEY_123" | ||
| }, | ||
| "ENCRYPTION_KEY": { | ||
| "description": "Encryption key for restic/rclone Snapshot encryption (min 12 chars)", | ||
| "default": "CHANGE_ME_ENCRYPTION_KEY_123" | ||
| }, | ||
| "APIKEY": { | ||
| "description": "API authentication key", | ||
| "default": "CHANGE_ME_API_KEY_123" | ||
| }, | ||
| "USER_NAME": { | ||
| "description": "Admin username for login", | ||
| "default": "admin" | ||
| }, | ||
| "USER_PASSWORD": { | ||
| "description": "Admin password for login", | ||
| "default": "password" | ||
| } | ||
| }, | ||
| "notes": [ | ||
| "Default credentials are admin:password - CHANGE THESE IN PRODUCTION!", | ||
| "Access the Pluton UI at http://localhost:5173", | ||
| "Ensure you set strong secrets for SECRET, ENCRYPTION_KEY, and APIKEY." | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| #!/bin/sh | ||
|
|
||
| # Fix permissions for /data | ||
| chown -R node:node /data | ||
|
|
||
| # Execute the command as node user | ||
| exec su-exec node "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Build script for Pluton Docker image | ||
| # This script builds the Pluton Docker image for multiple architectures | ||
|
|
||
| set -e | ||
|
|
||
| # Colors for output | ||
| RED='\033[0;31m' | ||
| GREEN='\033[0;32m' | ||
| YELLOW='\033[1;33m' | ||
| NC='\033[0m' # No Color | ||
|
|
||
| # Configuration | ||
| IMAGE_NAME="bigbeartechworld/big-bear-pluton" | ||
| VERSION=$(cat VERSION) | ||
|
|
||
| echo -e "${GREEN}Building Pluton Docker Image${NC}" | ||
| echo -e "${YELLOW}Version: ${VERSION}${NC}" | ||
|
|
||
| # Check if we are in the right directory | ||
| if [ ! -f "Dockerfile" ]; then | ||
| echo -e "${RED}Error: Dockerfile not found. Please run this script from the Apps/pluton directory.${NC}" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Build the image | ||
| echo -e "${YELLOW}Building image...${NC}" | ||
| docker build -t "${IMAGE_NAME}:${VERSION}" -t "${IMAGE_NAME}:latest" . | ||
|
|
||
| echo -e "${GREEN}Build complete!${NC}" | ||
| echo -e "Tags:" | ||
| echo -e " - ${IMAGE_NAME}:${VERSION}" | ||
| echo -e " - ${IMAGE_NAME}:latest" |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.