Sign inSign up

exisllc/massedit

By exisllc

•Updated 6 months ago

Self-hosted bulk find and replace for Google Docs and Google Slides.

Image
0

345

exisllc/massedit repository overview

⁠MassEdit for Google Docs & Slides — Docker Edition

Self-hosted bulk find & replace for Google Docs and Google Slides. Run it inside your own infrastructure — your documents stay in your Google Drive, your data stays in your container.

Website: massedit.app⁠ · Docker page: massedit.app/Docker⁠ · Hosted version: massedit.app⁠

Website Docker Pulls Docker Image Version


⁠What it does

  • Bulk find & replace across hundreds of Google Docs and Slides at once
  • Regex support with capture groups, lookaheads, and case-insensitive matching
  • Formatting-aware — find by bold/italic/colour, apply formatting to replacements
  • Image replacement — swap logos and graphics across all selected documents
  • Folder browser — navigate My Drive, Shared with me, and Shared Drives
  • Multi-user — admin provisions accounts; each user signs in with their own Google account
  • Optional email — Gmail / Office 365 SMTP / Microsoft Graph OAuth for password resets and welcome emails

⁠Quick start

mkdir massedit && cd massedit
curl -O https://raw.githubusercontent.com/exisllc/massedit-docker/main/docker-compose.yml
docker compose up -d

Open http://localhost:8080 in your browser. The landing page will show a one-time bootstrap admin password — sign in, change it, then complete the setup checklist.

That's it. No environment variables required.

⁠Setup checklist

The landing page walks you through these steps. They are also covered in detail below.

  1. Sign in with the bootstrap credentials shown on the homepage
  2. Change the admin password when prompted
  3. Configure Google OAuth in Admin → Google Settings (required to access Drive)
  4. (Optional) Configure email in Admin → Email Settings
  5. (Optional) Add a corporate license key in Admin → License Settings (otherwise runs in trial mode)
  6. Add team members in Admin → Users
⁠1. Bootstrap admin

On first launch, MassEdit auto-creates [email protected] with a random 16-character password. The password is displayed:

  • On the homepage (the very first time you visit /)
  • In the container logs (docker compose logs massedit)

You'll be forced to change it on first login.

⁠2. Google OAuth

MassEdit uses your own Google Cloud project so your data never goes through Exis LLC. You provide:

  • OAuth Client ID
  • OAuth Client Secret

The Admin → Google Settings page has detailed step-by-step instructions covering:

  • Creating a Google Cloud project
  • Enabling the Docs / Slides / Drive APIs
  • Configuring the OAuth consent screen (Google Auth Platform)
  • Choosing Internal vs External user type
  • Creating the OAuth client and setting the redirect URI
  • Adding test users (External only)

The redirect URI MassEdit needs is shown on the page — copy it byte-for-byte into the OAuth client.

⁠3. Email (optional)

Without email, the admin shares temporary passwords manually when creating users. With email, MassEdit can send welcome emails and password reset links automatically.

Supported providers:

  • Gmail (SMTP with app password)
  • Office 365 (SMTP with app password)
  • Custom SMTP (any provider)
  • Microsoft Graph OAuth (M365 with Azure AD app — recommended for orgs that disabled SMTP basic auth)
⁠4. License key

MassEdit ships in trial mode by default. Trial limits:

  • 5 documents per job
  • 10 replacement rules per job
  • Cannot modify originals (must create copies)

To unlock unlimited use, get a corporate license key from [email protected] and enter it in Admin → License Settings. Each user consumes one seat on the corporate license. Adding/removing users automatically activates/releases seats.

⁠5. Adding users

In Admin → Users, click "Create New User", enter the email, and click Create. You'll see a temporary password to share with the user. They'll be required to change it on first login. If you've configured email, the user gets a welcome email instead.


⁠Docker reference

⁠Image
exisllc/massedit:latest    # tracks the most recent stable release
exisllc/massedit:1.0.0     # specific version (recommended for production)

Architectures: linux/amd64, linux/arm64 (Apple Silicon, Raspberry Pi 4+, AWS Graviton).

⁠Ports
ContainerPurpose
8080HTTP — the only port the application listens on

HTTPS termination is your responsibility. In production, put a reverse proxy in front of the container (Caddy, Nginx, Traefik, Cloudflare Tunnel, etc.).

⁠Volumes
MountPurpose
/app/dataSQLite database, encrypted at rest. Back this up.

The volume contains everything: users, jobs, settings, license info. Losing it means starting over.

⁠Environment variables

All application configuration is done through the web UI. The only environment variable that matters at runtime:

VariableDefaultPurpose
ASPNETCORE_ENVIRONMENTProductionStandard ASP.NET environment selector
MFA__RequiredfalseSet to true to require MFA for every user

That's intentional — secrets and configuration live in the encrypted database, not in environment variables.

⁠Reverse proxy example (Caddy)
massedit.example.com {
    reverse_proxy localhost:8080
}

That's the entire production HTTPS setup with auto-renewing Let's Encrypt certificates.

⁠Reverse proxy example (Nginx)
server {
    listen 443 ssl;
    server_name massedit.example.com;

    ssl_certificate /etc/letsencrypt/live/massedit.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/massedit.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 50M;
    }
}

The redirect URI you give Google must match https://massedit.example.com/api/google/callback.

⁠Backup and restore

⁠Backup
docker compose stop
docker run --rm -v massedit_massedit-data:/data -v $(pwd):/backup busybox \
    tar czf /backup/massedit-backup-$(date +%F).tar.gz /data
docker compose start
⁠Restore
docker compose down
docker volume rm massedit_massedit-data
docker volume create massedit_massedit-data
docker run --rm -v massedit_massedit-data:/data -v $(pwd):/backup busybox \
    tar xzf /backup/massedit-backup-2026-04-09.tar.gz -C /
docker compose up -d

⁠Updating

docker compose pull
docker compose up -d

The container will automatically apply database migrations on startup. Pin to a specific version (exisllc/massedit:1.0.0) instead of latest if you want full control over when updates happen.

⁠Health check

The container exposes GET /health on port 8080:

curl http://localhost:8080/health
# {"status":"healthy","version":"1.0.0"}

The container's built-in HEALTHCHECK uses this endpoint, so docker ps shows liveness status.

⁠Troubleshooting

⁠"License key was rejected by the licensing server"

The corporate license key you entered doesn't match a product registered as Mass Edit Docker in the ExisOne dashboard. Double-check the key, or contact [email protected].

⁠"Error 400: invalid_request" from Google OAuth

The redirect URI in your Google OAuth client doesn't exactly match what MassEdit is sending. The exact URL is shown on the Google Settings page (yellow code box). It must match byte-for-byte: scheme, host, port, path. Wait 1–5 minutes after saving in the Google Cloud Console — Google's OAuth changes don't propagate instantly.

⁠"Access blocked: app has not completed verification"

Your OAuth consent screen is set to External and the user signing in is not on the Test users list. Either add them as a test user, or switch to Internal if you have Google Workspace.

⁠Can't see the bootstrap password

It's logged on the very first container start. Check the logs:

docker compose logs massedit | grep -A 5 "FIRST-RUN BOOTSTRAP"

Or visit / in your browser before logging in for the first time — the password is shown there.

⁠Trial limits when I want unlimited

Add a corporate license key in Admin → License Settings. Without one, the app runs in trial mode (5 docs/job, 10 rules/job, must create copies of originals).

⁠Support

  • Website: massedit.app⁠
  • Email: [email protected]⁠
  • Built-in support form: Help → Support inside the app (uses ExisOne support tickets)
  • Built-in error reporter: when an error occurs, click "View Message Center" and use the "Report to support" button

⁠License

Proprietary. See LICENSE.txt. Operation requires either a trial period or a valid corporate license key obtained from Exis LLC.

⁠Credits

Built by Exis LLC. Uses:

  • ASP.NET Core 8.0
  • SQLite (encrypted via SQLCipher)
  • Google Docs / Slides / Drive APIs
  • ExisOne licensing
  • HTMX for the UI

Tag summary

Content type

Image

Digest

sha256:7693f8713…

Size

105.8 MB

Last updated

6 months ago

docker pull exisllc/massedit