Installation
Get started with Velld in minutes
Installation
Velld is designed to be simple to install and run. Choose the installation method that works best for you.
Prerequisites
Before you begin, ensure you have:
- Docker and Docker Compose installed
- At least 512MB RAM and 1GB disk space
- A database you want to backup (PostgreSQL, MySQL, MongoDB, or Redis)
Velld only installs the database clients you need. This keeps the Docker image lightweight and secure.
Quick Start
Fastest way - Pull and run pre-built images directly (no git clone needed):
# Pull images
docker pull ghcr.io/dendianugerah/velld/api:latest
docker pull ghcr.io/dendianugerah/velld/web:latest
# Create .env file
cat > .env << EOF
NEXT_PUBLIC_API_URL=http://localhost:8080
JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
ADMIN_USERNAME_CREDENTIAL=admin
ADMIN_PASSWORD_CREDENTIAL=changeme
ALLOW_REGISTER=true
EOF
# Run API
docker run -d \
--name velld-api \
-p 8080:8080 \
--env-file .env \
-v velld-data:/app/data \
-v velld-backups:/app/backups \
ghcr.io/dendianugerah/velld/api:latest
# Run Web
docker run -d \
--name velld-web \
-p 3000:3000 \
-e NEXT_PUBLIC_API_URL=http://localhost:8080 \
-e ALLOW_REGISTER=true \
ghcr.io/dendianugerah/velld/web:latestImportant: The data directory has changed from /app/internal/database to /app/data.
Open http://localhost:3000 in your browser.
Using Docker Compose
If you prefer docker-compose:
git clone https://github.com/dendianugerah/velld.git
cd velld
cp .env.example .env
docker compose -f docker-compose.prebuilt.yml up -dBuild from Source
If you want to build the images yourself:
git clone https://github.com/dendianugerah/velld.git
cd velld
cp .env.example .env
docker compose up -dDatabase-Specific Installation
Choose only the database client you need to keep your installation lightweight:
PostgreSQL Only
1. Create a custom Dockerfile
Create apps/api/Dockerfile.postgres:
FROM golang:1.24-alpine AS builder
WORKDIR /app
RUN apk add --no-cache gcc musl-dev
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -o main cmd/api-server/main.go
FROM alpine:latest
# Install only PostgreSQL client
RUN apk add --no-cache \
sqlite-libs \
postgresql-client
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/internal/database ./internal/database
EXPOSE 8080
CMD ["./main"]2. Update docker-compose.yml
services:
api:
build:
context: ./apps/api
dockerfile: Dockerfile.postgres # Use PostgreSQL-only Dockerfile
ports:
- "8080:8080"
env_file:
- .env
volumes:
- api_data:/app/data
- backup_data:/app/backups
restart: unless-stopped
web:
build:
context: ./apps/web
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
ALLOW_REGISTER: ${ALLOW_REGISTER}
depends_on:
- api
restart: unless-stopped
volumes:
api_data:
backup_data:3. Start the services
docker compose up -dYour PostgreSQL-only installation is now running! Image size: ~50MB lighter.
MySQL Only
1. Create a custom Dockerfile
Create apps/api/Dockerfile.mysql:
FROM golang:1.24-alpine AS builder
WORKDIR /app
RUN apk add --no-cache gcc musl-dev
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -o main cmd/api-server/main.go
FROM alpine:latest
# Install only MySQL client
RUN apk add --no-cache \
sqlite-libs \
mysql-client
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/internal/database ./internal/database
EXPOSE 8080
CMD ["./main"]2. Update docker-compose.yml
services:
api:
build:
context: ./apps/api
dockerfile: Dockerfile.mysql # Use MySQL-only Dockerfile
ports:
- "8080:8080"
env_file:
- .env
volumes:
- api_data:/app/data
- backup_data:/app/backups
restart: unless-stopped
web:
build:
context: ./apps/web
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
ALLOW_REGISTER: ${ALLOW_REGISTER}
depends_on:
- api
restart: unless-stopped
volumes:
api_data:
backup_data:3. Start the services
docker compose up -dYour MySQL-only installation is now running! Image size: ~45MB lighter.
MongoDB Only
1. Create a custom Dockerfile
Create apps/api/Dockerfile.mongo:
FROM golang:1.24-alpine AS builder
WORKDIR /app
RUN apk add --no-cache gcc musl-dev
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -o main cmd/api-server/main.go
FROM alpine:latest
# Install only MongoDB tools
RUN apk add --no-cache \
sqlite-libs \
mongodb-tools
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/internal/database ./internal/database
EXPOSE 8080
CMD ["./main"]2. Update docker-compose.yml
services:
api:
build:
context: ./apps/api
dockerfile: Dockerfile.mongo # Use MongoDB-only Dockerfile
ports:
- "8080:8080"
env_file:
- .env
volumes:
- api_data:/app/data
- backup_data:/app/backups
restart: unless-stopped
web:
build:
context: ./apps/web
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
ALLOW_REGISTER: ${ALLOW_REGISTER}
depends_on:
- api
restart: unless-stopped
volumes:
api_data:
backup_data:3. Start the services
docker compose up -dYour MongoDB-only installation is now running! Image size: ~60MB lighter.
Environment Configuration
Create a .env file in the project root:
cp .env.example .envRequired Variables
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_API_URL | API server URL (must be accessible from browser) | http://localhost:8080 |
JWT_SECRET | JWT signing key - generate with openssl rand -hex 32 | 64 hex characters |
ENCRYPTION_KEY | Database credential encryption key - generate with openssl rand -hex 32 | 64 hex characters |
Production: Always set JWT_SECRET and ENCRYPTION_KEY manually. While they auto-generate if missing, changing keys will log out users and break database connections.
# Generate secure keys
openssl rand -hex 32 # Run twice, once for eachAuthentication
| Variable | Description | Default |
|---|---|---|
ALLOW_REGISTER | Enable public registration | true |
ADMIN_USERNAME_CREDENTIAL | Admin username (required if ALLOW_REGISTER=false) | - |
ADMIN_PASSWORD_CREDENTIAL | Admin password (required if ALLOW_REGISTER=false) | - |
Optional: Email Notifications
Configure SMTP to get notified when backups fail. You can configure these either:
- Via UI: Go to Settings → Notifications (recommended for most users)
- Via Environment Variables: Set below variables (useful for Docker/Kubernetes deployments)
When configured via environment variables, these settings become read-only in the UI and cannot be changed from the web interface.
| Variable | Description | Default |
|---|---|---|
SMTP_HOST | SMTP server hostname | - |
SMTP_PORT | SMTP port | 587 |
SMTP_USER | SMTP username/email | - |
SMTP_PASSWORD | SMTP password (use App Password for Gmail) | - |
SMTP_FROM | From address | - |
Advanced
| Variable | Description | Default |
|---|---|---|
DB_PATH | Path to Velld's SQLite database | /app/data/velld.db |
PORT | API server port | 8080 |
Data Persistence: Ensure /app/data is mounted as a volume to persist your database.
Verify Installation
Once the services are running, verify everything works:
-
Check service status
docker compose ps -
View logs
docker compose logs -f -
Access the web interface
Open http://localhost:3000 in your browser.
-
Create your account
Sign up with your email and start managing backups!
Updating Velld
To update to the latest version:
# Pull the latest changes
git pull origin main
# Rebuild and restart
docker compose down
docker compose up -d --buildTroubleshooting
Services won't start
# Check logs for errors
docker compose logs api
docker compose logs web
# Ensure ports 3000 and 8080 are available
lsof -i :3000
lsof -i :8080Database connection fails
- Ensure your database is accessible from the Docker container
- Use
host.docker.internalinstead oflocalhostto connect to databases on your host machine - Check firewall rules
Backup fails
- Verify the database client is installed (check which Dockerfile you're using)
- Test connection credentials manually
- Check backup directory permissions