Self-hosted bulk find and replace for Google Docs and Google Slides.
345
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
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.
The landing page walks you through these steps. They are also covered in detail below.
On first launch, MassEdit auto-creates [email protected] with a random 16-character password. The password is displayed:
/)docker compose logs massedit)You'll be forced to change it on first login.
MassEdit uses your own Google Cloud project so your data never goes through Exis LLC. You provide:
The Admin → Google Settings page has detailed step-by-step instructions covering:
The redirect URI MassEdit needs is shown on the page — copy it byte-for-byte into the OAuth client.
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:
MassEdit ships in trial mode by default. Trial limits:
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.
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.
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).
| Container | Purpose |
|---|---|
8080 | HTTP — 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.).
| Mount | Purpose |
|---|---|
/app/data | SQLite database, encrypted at rest. Back this up. |
The volume contains everything: users, jobs, settings, license info. Losing it means starting over.
All application configuration is done through the web UI. The only environment variable that matters at runtime:
| Variable | Default | Purpose |
|---|---|---|
ASPNETCORE_ENVIRONMENT | Production | Standard ASP.NET environment selector |
MFA__Required | false | Set to true to require MFA for every user |
That's intentional — secrets and configuration live in the encrypted database, not in environment variables.
massedit.example.com {
reverse_proxy localhost:8080
}
That's the entire production HTTPS setup with auto-renewing Let's Encrypt certificates.
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.
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
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
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.
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.
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].
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.
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.
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.
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).
Proprietary. See LICENSE.txt. Operation requires either a trial period or a valid corporate license key obtained from Exis LLC.
Built by Exis LLC. Uses:
Content type
Image
Digest
sha256:7693f8713…
Size
105.8 MB
Last updated
6 months ago
docker pull exisllc/massedit