Skip to main content

Self-Hosting

Plumio can be self-hosted using Docker, Docker Compose, or from source. Choose the method that best fits your infrastructure.

Using Docker

The quickest way to get started is with Docker:

docker run -d \
--name plumio \
-p 3000:3000 \
-p 3001:3001 \
-v plumio-data:/data \
-e JWT_SECRET="$(openssl rand -base64 32)" \
-e ENCRYPTION_KEY="$(openssl rand -base64 32)" \
ghcr.io/albertasaftei/plumio:latest

Access Plumio at http://localhost:3000

Environment Variables

VariableDescriptionRequired
JWT_SECRETSecret key for JWT tokensYes
ENCRYPTION_KEY32-character key for encryptionYes
DOCUMENTS_PATHPath to store documentsNo (default: /data/documents)
DB_PATHPath to SQLite databaseNo (default: /data/plumio.db)
ENABLE_ENCRYPTIONEnable document encryptionNo (default: true)

Optional SMTP support for password reset and email change features:

VariableDescriptionRequired
SMTP_HOSTSMTP hostname for password reset emailsNo
SMTP_PORTSMTP port for password reset emailsNo
SMTP_USERSMTP usernameNo
SMTP_PASSSMTP password or app passwordNo
SMTP_FROMSender address shown in reset emailsNo
APP_URLPublic app URL used in generated reset linksNo

If these variables are omitted, plumio still works normally, but users will not be able to reset their password by email.

Using Docker Compose

For production deployments, use Docker Compose for better configuration management.

1. Create docker-compose.yml

version: "3.8"

services:
plumio:
image: ghcr.io/albertasaftei/plumio:latest
container_name: plumio
restart: unless-stopped
ports:
- "3000:3000" # Frontend
- "3001:3001" # Backend API
environment:
- NODE_ENV=production
- BACKEND_INTERNAL_PORT=3001
- DOCUMENTS_PATH=/data/documents
- DB_PATH=/data/plumio.db
- JWT_SECRET=${JWT_SECRET}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- ALLOWED_ORIGINS=http://${FRONTEND_URL}:${FRONTEND_PORT}
- ENABLE_ENCRYPTION=true
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USER=${SMTP_USER}
- SMTP_PASS=${SMTP_PASS}
- SMTP_FROM=${SMTP_FROM}
- APP_URL=${APP_URL}
volumes:
- plumio-data:/data
networks:
- plumio-network
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:3001/api/health",
]
interval: 5m
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M

# Automated backup service (optional - requires --profile backup)
# backup:
# image: alpine:latest
# container_name: plumio-backup
# restart: unless-stopped
# profiles:
# - backup
# volumes:
# - plumio-data:/data:ro # Read-only access to data
# - ./backups:/backups # Backup destination
# - ./backup.sh:/backup.sh # Backup script (read-write for chmod)
# environment:
# - BACKUP_RETENTION=7 # Keep backups for 7 days
# - BACKUP_SCHEDULE=0 2 * * * # Daily at 2 AM
# command: sh /backup.sh
# depends_on:
# - plumio
# networks:
# - plumio-network

volumes:
plumio-data:
driver: local

networks:
plumio-network:
driver: bridge

2. Start Plumio

docker-compose up -d

3. View logs

docker-compose logs -f

From Source

For development or custom deployments, you can run Plumio from source.

1. Clone the repository

git clone https://github.com/albertasaftei/plumio.git
cd plumio

2. Set up Backend

cd backend
npm install

Create backend/.env:

BACKEND_INTERNAL_PORT=3001
DOCUMENTS_PATH=./documents
DB_PATH=./data/plumio.db
JWT_SECRET=$(openssl rand -base64 32)
ENCRYPTION_KEY=$(openssl rand -base64 32)
ENABLE_ENCRYPTION=true

Optional password reset email variables:

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM="Plumio <your-email@gmail.com>"
APP_URL=http://localhost:3000

These are optional. Only configure them if you want users to be able to receive password reset emails.

Build and start backend:

npm run build
npm start

3. Set up Frontend

In a new terminal:

cd frontend
pnpm install

Create frontend/.env:

VITE_API_URL=http://localhost:3001

Build and start frontend:

pnpm dev

4. Access Plumio

Open your browser and navigate to http://localhost:3000

Updating

Docker/Docker Compose

# Pull latest image
docker pull ghcr.io/albertasaftei/plumio:latest

# Restart container
docker-compose down
docker-compose up -d

From Source

git pull
cd backend && npm install && npm run build
cd ../frontend && pnpm install && pnpm build
# Restart both services

Data Backup

Your data is stored in the following locations:

  • Docker volumes: /data (contains plumio.db and documents/)
  • From source: backend/data/ and backend/documents/

Backup Docker volumes

docker run --rm \
-v plumio-data:/data \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/plumio-backup-$(date +%Y%m%d).tar.gz /data

Reverse Proxy (Optional)

To use Plumio with a reverse proxy like Nginx or Caddy:

Nginx

server {
listen 80;
server_name your-domain.com;

location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

location /api {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Caddy

your-domain.com {
reverse_proxy localhost:3000
reverse_proxy /api/* localhost:3001
}

Troubleshooting

Container won't start

Check logs: docker logs plumio or docker-compose logs

Common issues:

  • Missing or invalid JWT_SECRET/ENCRYPTION_KEY
  • Port already in use
  • Insufficient permissions on data volume

Cannot connect to API

Ensure:

  • Backend is running on port 3001
  • VITE_API_URL points to correct backend URL
  • Firewall allows connections to both ports

Database errors

The SQLite database is automatically created on first run. If you encounter errors:

# Backup and reset database
docker-compose down
docker volume rm plumio-data
docker-compose up -d