Productivity
The Solopreneur & Web Launch Stack
Everything a one-person team needs to launch a website, publish content, measure traffic, collect customer feedback and get paid — without a separate SaaS subscription for every piece. Ideal for solo founders, freelancers and creators launching their first product.
Combined minimum RAM
~6GB
Estimated savings
Save over $120/mo versus Typeform + Ghost Pro + Google Analytics
Overlapping tools
- Alternatives to each other for Google Analytics: Umami, Plausible Analytics. You may only need one of them.
Tools in this pack (5)
Strapi
Open source headless CMS on Node.js, an alternative to Contentful.
Dev ToolsOpen-Core🟡 Standard · ~1GB
docker-compose.yml
version: "3.9"
services:
strapi:
image: strapi/strapi:latest
restart: unless-stopped
ports:
- "1337:1337"
environment:
- DATABASE_CLIENT=postgres
- DATABASE_HOST=strapi-db
- DATABASE_NAME=strapi
- DATABASE_USERNAME=strapi
- DATABASE_PASSWORD=change-me-postgres-password # must match POSTGRES_PASSWORD below
volumes:
- strapi_data:/srv/app
depends_on:
- strapi-db
strapi-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=strapi
- POSTGRES_PASSWORD=change-me-postgres-password # REQUIRED: generate a random secret before first run
- POSTGRES_DB=strapi
volumes:
- strapi_pg_data:/var/lib/postgresql/data
volumes:
strapi_data:
strapi_pg_data:
Umami
Minimalist web analytics, very easy to self-host.
Web Analytics100% FOSS🟡 Standard · ~1GB
docker-compose.yml
version: "3.9"
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
restart: unless-stopped
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://umami:change-me-postgres-password@umami-db:5432/umami # password must match the canonical db password below
- APP_SECRET=change-me-super-secret
depends_on:
- umami-db
umami-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=umami
- POSTGRES_PASSWORD=change-me-postgres-password # REQUIRED: generate a random secret before first run
- POSTGRES_DB=umami
volumes:
- umami_pg_data:/var/lib/postgresql/data
volumes:
umami_pg_data:
Plausible Analytics
Cookie-free web analytics, an alternative to Google Analytics.
Web Analytics100% FOSS🔴 Full · ~2GB
docker-compose.yml
version: "3.9"
services:
plausible:
image: ghcr.io/plausible/community-edition:v2
restart: unless-stopped
ports:
- "8000:8000"
environment:
- BASE_URL=https://analytics.yourdomain.com # CHANGE THIS TO YOUR DOMAIN
- SECRET_KEY_BASE=change-me-64-char-secret # REQUIRED: generate a random secret before first run
- DATABASE_URL=postgres://postgres:change-me-db-password@plausible-db:5432/plausible
- CLICKHOUSE_DATABASE_URL=http://plausible-events-db:8123/plausible_events_db
depends_on:
- plausible-db
- plausible-events-db
plausible-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=change-me-db-password # must match DATABASE_URL above
volumes:
- plausible_pg_data:/var/lib/postgresql/data
plausible-events-db:
image: clickhouse/clickhouse-server:24-alpine
restart: unless-stopped
volumes:
- plausible_ch_data:/var/lib/clickhouse
volumes:
plausible_pg_data:
plausible_ch_data:
Typebot
AI-powered conversational forms, an alternative to Typeform.
Artificial IntelligenceOpen-Core🟡 Standard · ~1GB
docker-compose.yml
version: "3.9"
services:
typebot-builder:
image: baptistearno/typebot-builder:3.19
restart: unless-stopped
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://typebot:change-me-postgres-password@typebot-db:5432/typebot # password must match the canonical db password below
- ENCRYPTION_SECRET=change-me-32-char-secret
depends_on:
- typebot-db
typebot-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=typebot
- POSTGRES_PASSWORD=change-me-postgres-password # REQUIRED: generate a random secret before first run
- POSTGRES_DB=typebot
volumes:
- typebot_pg_data:/var/lib/postgresql/data
volumes:
typebot_pg_data:
Invoice Ninja
Invoicing and quotes with a client portal, an alternative to FreshBooks.
CRM & SupportSource-available🟡 Standard · ~1GB
docker-compose.yml
services:
app:
image: invoiceninja/invoiceninja:5
restart: unless-stopped
ports:
- "80:80"
environment:
APP_URL: http://localhost # CHANGE THIS TO YOUR DOMAIN
APP_KEY: change-me-32-char-app-key # REQUIRED: generate a random secret before first run
DB_HOST: db
DB_DATABASE: ninja
DB_USERNAME: ninja
DB_PASSWORD: change-me-mysql-password # REQUIRED: generate a random secret before first run
volumes:
- ninja_data:/var/www/app/public/storage
depends_on:
- db
db:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_DATABASE: ninja
MYSQL_USER: ninja
MYSQL_PASSWORD: change-me-mysql-password # must match DB_PASSWORD above
MYSQL_ROOT_PASSWORD: change-me-mysql-root-password # REQUIRED: generate a random secret before first run
volumes:
- ninja_db_data:/var/lib/mysql
volumes:
ninja_data:
ninja_db_data: