Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions .env.example

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Release

on:
release:
types: [published]

env:
REGISTRY: docker.io
IMAGE_NAME: mlapaglia/borgitory

jobs:
docker-release:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}

- name: Extract version and determine release type
id: version
run: |
VERSION=${{ github.event.release.tag_name }}
# Remove 'v' prefix if present
VERSION=${VERSION#v}
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "Extracted version: ${VERSION}"

# Check if version contains prerelease indicators OR if GitHub release is marked as prerelease
if [[ "$VERSION" =~ (alpha|beta|rc|dev|pre) ]] || [ "${{ github.event.release.prerelease }}" == "true" ]; then
echo "IS_PRERELEASE=true" >> $GITHUB_OUTPUT
echo "PRERELEASE_TAG=alpha" >> $GITHUB_OUTPUT
echo "This is a prerelease (detected from version string or GitHub flag)"
else
echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT
echo "PRERELEASE_TAG=" >> $GITHUB_OUTPUT
echo "This is a stable release"
fi

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# For stable releases: tag with version and latest
type=raw,value=${{ steps.version.outputs.VERSION }},enable=${{ steps.version.outputs.IS_PRERELEASE == 'false' }}
type=raw,value=latest,enable=${{ steps.version.outputs.IS_PRERELEASE == 'false' }}
# For prereleases: tag with exact version (already contains alpha/beta/etc) and alpha
type=raw,value=${{ steps.version.outputs.VERSION }},enable=${{ steps.version.outputs.IS_PRERELEASE == 'true' }}
type=raw,value=alpha,enable=${{ steps.version.outputs.IS_PRERELEASE == 'true' }}
labels: |
org.opencontainers.image.title=Borgitory
org.opencontainers.image.description=Borg Backup Manager with Web UI
org.opencontainers.image.version=${{ steps.version.outputs.VERSION }}
org.opencontainers.image.url=https://github.com/mlapaglia/borgitory
org.opencontainers.image.source=https://github.com/mlapaglia/borgitory
org.opencontainers.image.vendor=mlapaglia
org.opencontainers.image.licenses=MIT

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ steps.version.outputs.VERSION }}

- name: Update Docker Hub description
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
repository: ${{ env.IMAGE_NAME }}
readme-filepath: ./README.md
24 changes: 5 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,20 @@ FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
rclone \
borgbackup \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN groupadd -r borgitory && useradd -r -g borgitory -d /app -s /bin/bash borgitory

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY app/ ./app/
COPY start.sh /app/start.sh

# Create data directory and set permissions
RUN mkdir -p /app/data && chown -R borgitory:borgitory /app

# Switch to non-root user
USER borgitory
# Make script executable
RUN chmod +x /app/start.sh

# Expose port
EXPOSE 8000

# Set environment variables
ENV PYTHONPATH=/app
ENV DATABASE_URL=sqlite:///./data/borgitory.db
ENV DATA_DIR=/app/data

# Run the application (reload is disabled by default)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["/app/start.sh"]
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ A comprehensive web-based management interface for BorgBackup repositories with
### Advanced Features
- **Automated Scheduling**: Set up cron-based backup schedules with APScheduler
- **Cloud Sync**: Synchronize repositories to S3-compatible storage using Rclone
- **Passkey Authentication**: Secure access using WebAuthn (passwordless authentication)
- **User Authentication**: Secure username/password authentication
- **Docker Integration**: Manage Borg operations through isolated Docker containers
- **Mobile Responsive**: HTMX + Alpine.js + Tailwind CSS interface

Expand Down Expand Up @@ -45,7 +45,7 @@ A comprehensive web-based management interface for BorgBackup repositories with

4. **Access the web interface**
- Open http://localhost:8000 in your browser
- Set up passkey authentication on first visit
- Create your first admin account on initial setup

### Development Setup

Expand Down Expand Up @@ -76,7 +76,6 @@ A comprehensive web-based management interface for BorgBackup repositories with
|----------|---------|-------------|
| `SECRET_KEY` | *required* | Encryption key for stored credentials |
| `DATABASE_URL` | `sqlite:///./data/borgitory.db` | SQLite database path |
| `DATA_DIR` | `./data` | Data directory for app storage |
| `BORG_DOCKER_IMAGE` | `ghcr.io/borgmatic-collective/borgmatic:latest` | Docker image for Borg/Borgmatic operations |

### BorgBackup Docker Image
Expand Down Expand Up @@ -154,7 +153,7 @@ The application provides a RESTful API with automatic OpenAPI documentation:
- **SQLite**: Lightweight database for configuration
- **APScheduler**: Job scheduling and cron support
- **Docker SDK**: Container management
- **Fido2**: WebAuthn/passkey authentication
- **Passlib**: Password hashing and verification

### Frontend Stack
- **HTMX**: Dynamic HTML updates
Expand All @@ -163,11 +162,11 @@ The application provides a RESTful API with automatic OpenAPI documentation:
- **Server-Sent Events**: Real-time progress updates

### Security Features
- Passkey-only authentication (WebAuthn)
- Username/password authentication with bcrypt hashing
- Secure session management
- Encrypted credential storage (Fernet)
- Docker container isolation
- No network access for Borg containers
- CSRF protection

## Deployment

Expand Down Expand Up @@ -231,9 +230,9 @@ server {
- Verify repository path is accessible from container
- Check volume mounts in docker-compose.yml

3. **Passkey registration fails**
- Ensure HTTPS in production
- Check browser WebAuthn support
3. **Login fails**
- Check username and password are correct
- Ensure database is properly initialized

### Logs

Expand Down
Loading