Sign inSign up

manfredsteger/polly

By manfredsteger

•Updated about 2 months ago

Self-hosted polling & scheduling platform — open-source Doodle/Calendly alternative

Image
Integration & delivery
Developer tools
0

1.4K

manfredsteger/polly repository overview

⁠Polly - Open-Source Polling & Scheduling Platform

GitHub License: MIT

Self-hosted Doodle/Calendly alternative for teams who need GDPR-compliant, cloud-independent coordination tools.

⁠Quick Start

docker pull manfredsteger/polly:beta

# Option 1: Docker Compose (recommended)
git clone --branch v0.1.0-beta.9 --depth 1 https://github.com/manfredsteger/polly.git
cd polly
cp .env.example .env
# Set POSTGRES_PASSWORD, SESSION_SECRET and ADMIN_PASSWORD to strong values
docker compose -f docker-compose.image.yml up -d
# Open http://localhost:3080

# Option 2: Docker Compose with an external database
git clone --branch v0.1.0-beta.9 --depth 1 https://github.com/manfredsteger/polly.git
cd polly
cp .env.example .env
# Set DATABASE_URL, SESSION_SECRET and ADMIN_PASSWORD in .env
docker compose -f docker-compose.image.external-db.yml up -d

# Option 3: Docker Run with external database
docker run -d \
  --name polly \
  -p 3080:5000 \
  -e DATABASE_URL=postgresql://user:pass@your-db:5432/polly \
  -e SESSION_SECRET=$(openssl rand -base64 32) \
  -e APP_URL=http://localhost:3080 \
  -v polly-uploads:/app/uploads \
  manfredsteger/polly:0.1.0-beta.9

Default Admin Login: admin / Admin123!

⁠Features

  • 3 Poll Types: Schedule coordination, surveys, and organization/booking lists
  • Real-Time Voting: Live results via WebSocket with fullscreen presentation mode
  • Multi-Language: German and English with automatic browser detection
  • Authentication: Anonymous, local email/password, and Keycloak OIDC (SSO)
  • Email Notifications: Configurable reminders with customizable templates
  • Data Export: CSV, PDF, ICS calendar feed, and QR code sharing
  • Admin Dashboard: User management, branding, security scanning, email templates
  • WCAG 2.1 AA: Automatic color contrast auditing and correction
  • ClamAV Integration: Optional virus scanning for file uploads
  • AI Poll Assistant: Create polls via natural language with GWDG SAIA (OpenAI-compatible API)
  • Voice Input: Speech-to-text for AI chat using Whisper
  • GDPR Compliant: All data stays on your server, no external tracking

⁠Available Tags

TagDescription
manfredsteger/polly:latestLatest stable release
manfredsteger/polly:betaLatest beta release
manfredsteger/polly:rcLatest release candidate
manfredsteger/polly:<version>Specific version (e.g., 0.1.0-beta.9)

⁠Environment Variables

⁠Required
VariableDescriptionDefault
DATABASE_URLPostgreSQL connection stringAuto-configured in Docker Compose
SESSION_SECRETSession encryption key (min 32 chars)Change in production!

External / Managed PostgreSQL: Set DATABASE_URL directly (e.g. postgresql://user:pass@your-db-host:5432/polly) — the entrypoint automatically parses host and port from it. Special characters in passwords are supported (URL-encoded). The POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, and POSTGRES_HOST variables are only used by the integrated Docker Compose setup and are ignored when DATABASE_URL is set.

⁠Application
VariableDescriptionDefault
APP_URLPublic URL of your instancehttp://localhost:3080
ADMIN_USERNAMEInitial admin usernameadmin
ADMIN_PASSWORDInitial admin passwordAdmin123!
ADMIN_EMAILAdmin email address[email protected]
SEED_DEMO_DATALoad demo data on first startfalse
MFA_ADMIN_REQUIREDSet to false only to temporarily bypass the admin MFA setting during authenticator recovery. Remove or leave unset to use the admin-panel setting.—

Legacy aliases: BASE_URL, VITE_APP_URL are supported as backward-compatible aliases for APP_URL.

⁠Branding (Optional)

These values can also be edited from the Admin Panel after first start. When set via ENV, the corresponding form field becomes read-only.

VariableDescriptionExample
SITE_NAMESite name shown in navbar/titlePoll
SITE_NAME_ACCENTAccented letter of the site namey
FAVICON_URLPublic URL of a custom favicon (PNG/ICO/SVG)https://example.com/favicon.png
LOGO_URLPublic URL of a custom logohttps://example.com/logo.png
PRIMARY_COLORPrimary brand colour (hex)#F97316
POLLY_COPYRIGHT_TEXTFooter copyright text. When set, the admin field is locked© 2026 My Org
FORCE_HTTPSForce secure cookies (set true behind a TLS-terminating reverse proxy)true
⁠Email (Optional)
VariableDescriptionDefault
SMTP_HOSTSMTP server hostname—
SMTP_PORTSMTP port587
SMTP_USERSMTP username—
SMTP_PASSWORDSMTP password—
FROM_EMAILSender addressnoreply@localhost
⁠Keycloak SSO (Optional)
VariableDescription
KEYCLOAK_REALMKeycloak realm name
KEYCLOAK_CLIENT_IDOIDC client ID
KEYCLOAK_CLIENT_SECRETOIDC client secret
KEYCLOAK_AUTH_SERVER_URLKeycloak base URL
⁠ClamAV Virus Scanning (Optional)
VariableDescriptionDefault
CLAMAV_ENABLEDEnable virus scanningfalse
CLAMAV_HOSTClamAV daemon host— (set clamav when using the Compose profile)
CLAMAV_PORTClamAV daemon port3310

Start with ClamAV:

CLAMAV_ENABLED=true CLAMAV_HOST=clamav docker compose --profile clamav up -d
⁠AI Assistant (Optional)
VariableDescriptionDefault
AI_API_URLOpenAI-compatible API endpoint—
AI_API_KEYAPI key for AI services—
AI_API_KEY_FALLBACKFallback key (on HTTP 429)—
AI_MODELAI model namellama-3.3-70b-instruct

⁠Docker Compose

docker-compose.image.yml starts the pinned public image together with PostgreSQL:

services:
  postgres:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data

  app:
    image: manfredsteger/polly:0.1.0-beta.9
    ports:
      - "3080:5000"
    volumes:
      - uploads_data:/app/uploads
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres_data:
  uploads_data:

Set POSTGRES_PASSWORD, SESSION_SECRET, and ADMIN_PASSWORD in .env before starting. Use the pinned version tag for production; :beta intentionally advances to the newest beta release.

The release image supports linux/amd64 and linux/arm64, making it suitable for compatible x86_64 and ARM64 Portainer or Synology Container Manager hosts.

⁠Data Persistence

VolumeContent
postgres_dataDatabase (survives rebuilds)
uploads_dataUploaded files (logos, etc.)

The container runs as UID:GID 1001:1001 (nodejs). The uploads volume must be owned by this user, otherwise image uploads fail with EACCES (the container logs a [Uploads] WARNING at startup). Fix from the Docker host:

docker run --rm -v uploads_data:/data alpine chown -R 1001:1001 /data

⁠Health Check

curl http://localhost:3080/api/v1/health
# {"status":"ok","timestamp":"..."}

⁠Documentation

⁠License

Polly is open-source software licensed under the MIT License⁠.

Tag summary

Content type

Image

Digest

sha256:5b3b52842…

Size

779.2 MB

Last updated

about 2 months ago

docker pull manfredsteger/polly:beta