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 -hex 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 -hex 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, Caddy or Traefik:

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
}

Traefik​

services:
plumio:
labels:
- "traefik.enable=true"
- "traefik.http.routers.plumio.rule=Host(`plumio.yourdomain.com`)"
- "traefik.http.routers.plumio.entrypoints=websecure"
- "traefik.http.routers.plumio.tls.certresolver=letsencrypt"
- "traefik.http.services.plumio.loadbalancer.server.port=3000"
networks:
- traefik
- plumio-network

networks:
traefik:
external: true

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