TeamGlimpse Deployment Guide
This guide covers deploying TeamGlimpse on Linux.
Architecture Overview
- Backend: Rust binary running as a systemd service on port 8080
- Frontend: Static files served by nginx
- Database: PostgreSQL (one control database + per-organization databases created at runtime)
┌─────────────────┐
│ nginx │
│ (port 80/443) │
└────────┬────────┘
│
┌──────────────┴──────────────┐
│ │
▼ ▼
┌────────────────┐ ┌──────────────────┐
│ /api/* proxy │ │ /* static files │
│ to backend │ │ SPA routing │
└───────┬────────┘ └──────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ teamglimpse │ │ /var/www/ │
│ (port 8080) │ │ teamglimpse/ │
└────────┬────────┘ └──────────────────┘
│
▼
┌─────────────────┐
│ PostgreSQL │
│ (port 5432) │
└─────────────────┘
Single-instance deployment
TeamGlimpse is designed to run as a single backend process. Several subsystems keep state in process memory and are not shared across replicas:
- Job queue runner and live status stream — the in-memory broadcast registry (
JobRegistry) that powers theGET /jobs/:id/streamSSE endpoint lives in the process that started the job. A second replica would deliver only the initial database snapshot, then close the stream, and cancel requests routed there would update the row without emitting a live event. - Background scheduler — periodic data-fetch jobs are scheduled in-process. Running two replicas would run every scheduled job twice.
- LLM rate-limit tracker — the per-provider concurrency and rate-limit state is in process memory; replicas would not coordinate.
Run a single backend instance. To scale, increase resources on the host rather than adding replicas. Horizontal scale would require a shared pub/sub backbone (e.g. Redis, NATS, or Postgres LISTEN/NOTIFY), scheduler leader election, and a shared rate-limit store — none of which are present today.
Migrating from ActivityPulse
TeamGlimpse was called ActivityPulse up to version 0.9.6. New versions are published only under the new name, so an existing ActivityPulse install is moved over once. The move keeps the data, the logins, the port and the address; only the names on the machine change (directories, the service, the database and its user, the Docker image and volume).
Run the command for the way ActivityPulse was installed. Each one stops ActivityPulse, moves it, and starts TeamGlimpse; the application is offline in between.
| Installed with | Command |
|---|---|
| Docker | curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/migrate-to-teamglimpse.sh | sudo bash |
| Debian package | curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/install-deb.sh | sudo bash |
| tar.gz bundle | curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/install-tarball.sh | sudo bash |
If a step fails, the old names are put back and ActivityPulse is started again.
Docker
- The script expects the install in
/opt/activitypulse. For a Compose directory elsewhere, add--from:... | sudo bash -s -- --from /path/to/directory. - The database volume is copied, not moved. The old volume is kept as a fallback and the script prints the command that deletes it once you are satisfied.
- The machine needs free disk space for a second copy of the database.
- Changes made by hand to the old
docker-compose.ymlare not carried over. The old directory is kept as/opt/activitypulse.migrated-<date>; apply them to/opt/teamglimpse/docker-compose.yml. - Do not start the new
docker-compose.ymlfrom the release page in an old Compose directory: it uses a new, empty database volume.
Debian package and tar.gz bundle
- A dump of all databases is written to
/var/backups/teamglimpse-migration-<date>.sql.gzbefore anything is renamed. - The configuration moves to
/etc/teamglimpse/teamglimpse.conf(package) or/opt/teamglimpse/teamglimpse.conf(bundle). Settings namedACTIVITYPULSE_EMAIL_...are renamed toTEAMGLIMPSE_EMAIL_.... - The nginx site is carried over under the name
teamglimpse, with your host names and certificates. - The service is now
teamglimpse:sudo systemctl status teamglimpse,sudo journalctl -u teamglimpse -f. - A database on another server, or one whose user or name you chose yourself, is not
renamed; its
DATABASE_URLis carried over as it is. - When installing the package by hand (
sudo apt install ./teamglimpse_<version>_amd64.deb) instead of with the command above, finish withsudo dpkg --purge activitypulse.
Prerequisites
Ubuntu Server Requirements
- Ubuntu 22.04 LTS or newer
- Minimum 2 GB RAM
- 20 GB disk space
- Root or sudo access
Required Software
Install the following packages:
sudo apt update
sudo apt install -y nginx postgresql postgresql-client
Installation via Debian Package
The easiest way to install TeamGlimpse on Debian/Ubuntu is using the .deb package. It handles all setup automatically: dependencies, system user, database initialization, nginx configuration, and the systemd service.
Quick Install
curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/install-deb.sh | sudo bash
This downloads and installs the latest .deb package with all dependencies (nginx, PostgreSQL). The package post-install script handles database initialization, JWT secret generation, and service startup. The script is non-interactive and safe to inspect before running.
If TeamGlimpse is already installed, the script prints the current version and upgrade instructions, then exits without making changes.
Manual Install
1. Install the Package
sudo apt install ./teamglimpse_1.0.0_amd64.deb
apt will install the required dependencies (nginx, postgresql, postgresql-client) and then run the post-install script, which:
- Creates the
teamglimpsesystem user - Initializes the PostgreSQL database and user
- Generates a random JWT secret
- Enables and activates the nginx site (removing the default site if present)
- Enables and starts the
teamglimpsesystemd service
2. Configure the Application
Review and update the configuration file:
sudo nano /etc/teamglimpse/teamglimpse.conf
At minimum verify:
DATABASE_URL— set automatically during install, confirm it is correctJWT_SECRET— generated automatically; replace if you prefer your own valueAPP_URL— auto-detected from hostname; update to your actual domain if using DNS or TLS (required for SSO)
3. Start the Service
sudo systemctl restart teamglimpse
sudo systemctl status teamglimpse
Updating via Debian Package
To upgrade to a newer version, install the new package the same way:
sudo apt install ./teamglimpse_1.1.0_amd64.deb
The post-install script will automatically run any pending database migrations and restart the service. Your existing configuration in /etc/teamglimpse/teamglimpse.conf is preserved.
Uninstalling the Debian Package
1. Remove the package:
sudo apt remove teamglimpse
This stops the systemd service, removes the binary, frontend files, and nginx configuration. The configuration file at /etc/teamglimpse/teamglimpse.conf is kept in case you reinstall later.
To also remove the configuration file:
sudo apt purge teamglimpse
2. (Optional) Remove the PostgreSQL database:
The package does not drop the database on removal. Because TeamGlimpse creates a separate database for each organization, you must drop all of them before removing the user.
Drop the control database and all organization databases owned by teamglimpse:
# Drop all databases owned by the teamglimpse user
sudo -u postgres psql -tAc \
"SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname = 'teamglimpse');" \
| while read -r db; do
sudo -u postgres psql -c "DROP DATABASE IF EXISTS \"$db\";"
done
# Now drop the user
sudo -u postgres psql -c "DROP USER IF EXISTS teamglimpse;"
This permanently deletes all data. If you want to keep a backup, run export-db.sh first.
3. (Optional) Remove nginx:
If nginx was installed only for TeamGlimpse and is not used by other applications:
sudo apt purge nginx nginx-common
sudo apt autoremove
This removes nginx, its configuration files, and any dependencies that are no longer needed.
4. (Optional) Remove PostgreSQL:
If PostgreSQL was installed only for TeamGlimpse and is not used by other applications:
sudo apt purge postgresql postgresql-client
sudo apt autoremove
Warning: This removes the PostgreSQL server and all databases on the system, not just the TeamGlimpse database. Only do this if no other applications depend on PostgreSQL.
Deployment via Docker
Quick Install
curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/install-docker.sh | sudo bash
This sets up TeamGlimpse in /opt/teamglimpse with auto-generated credentials. Requires Docker with the Compose plugin. The script is non-interactive and safe to inspect before running.
If TeamGlimpse is already installed, the script prints update instructions and exits without making changes.
Manual Docker Setup
Docker is the easiest way to run TeamGlimpse when you don’t want to manage system dependencies directly. A single docker compose command starts the application and a PostgreSQL database.
The Docker container runs as a non-root user (teamglimpse) for improved security. Inside the container, nginx listens on port 8080 and the backend on port 8081 — both unprivileged ports. The HTTP_PORT variable (default 8080) controls which port is exposed on the host. To serve on port 80 or 443, place a reverse proxy (e.g. host nginx or Caddy with TLS) in front of the container.
Prerequisites
- Docker Engine 24+ and Docker Compose v2
1. Get the Docker Image
Option A — Pull from GitHub Container Registry (recommended)
docker pull ghcr.io/teamglimpse/teamglimpse:latest
To pin to a specific version:
docker pull ghcr.io/teamglimpse/teamglimpse:0.6.0
Option B — Load from a downloaded archive
If you have a teamglimpse-<version>-docker.tar.gz file:
docker load -i teamglimpse-0.6.0-docker.tar.gz
2. Get the Compose File
Download docker-compose.yml from the releases page or copy it directly:
curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/docker-compose.yml \
-o docker-compose.yml
The released docker-compose.yml is preconfigured to pull ghcr.io/teamglimpse/teamglimpse:latest. If you loaded the image from a downloaded archive instead, edit the image: line in docker-compose.yml to match the local tag (e.g. teamglimpse:0.6.0).
3. Generate Credentials
Run the setup script once to create a .env file with randomly generated credentials:
./docker-setup.sh
This creates a .env file next to docker-setup.sh with a strong random POSTGRES_PASSWORD and JWT_SECRET, plus an APP_URL guessed from the host name. The script will not overwrite an existing .env, so it is safe to re-run.
Manual setup (optional): If you prefer to set credentials yourself, create
.envmanually:POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=' | head -c 32) JWT_SECRET=$(openssl rand -base64 64 | tr -d '\n') # HTTP_PORT=8080 # JWT_EXPIRY_HOURS=24 # RUST_LOG=info # APP_URL=http://localhost:8080
| Variable | Required | Default | Description |
|---|---|---|---|
POSTGRES_PASSWORD | Yes | — | PostgreSQL password |
JWT_SECRET | Yes | — | JWT signing secret (auto-generated if missing, but not persistent) |
HTTP_PORT | No | 8080 | Host port for HTTP (mapped to container port 8080) |
JWT_EXPIRY_HOURS | No | 24 | Token expiry in hours |
RUST_LOG | No | info | Log level (info, debug, warn) |
APP_URL | No | Auto-detected | Base URL of the instance (e.g. http://host:8080). Required for SSO. |
ORG_POOL_CACHE_SIZE (maximum number of organization database connection pools kept open at once, default 32) is not read from .env by the bundled Compose file — Compose only substitutes the variables named in the environment: block. To change it under Docker, add a line to the teamglimpse service in docker-compose.yml:
environment:
ORG_POOL_CACHE_SIZE: "${ORG_POOL_CACHE_SIZE:-32}"
then set ORG_POOL_CACHE_SIZE in .env and recreate the container. Raise it only alongside PostgreSQL’s max_connections. See Configuring TeamGlimpse.
4. Start the Stack
docker compose --env-file .env up -d
TeamGlimpse will be available at http://localhost:8080 (or the port set by HTTP_PORT).
On first start the application automatically initializes the database schema before accepting connections.
Viewing Logs
Run these commands from the directory containing docker-compose.yml (e.g. /opt/teamglimpse):
# Follow all logs
docker compose logs -f
# Backend only
docker compose logs -f teamglimpse
Updating
If using GHCR:
docker pull ghcr.io/teamglimpse/teamglimpse:latest
docker compose up -d
If using a downloaded archive:
docker load -i teamglimpse-1.1.0-docker.tar.gz
docker compose up -d
The database and configuration in .env are preserved between updates.
One-time check: data volume name
TeamGlimpse stores its database in a Docker volume named teamglimpse_pgdata.
Releases before this fix derived the volume name from the deployment directory, so
some installs ended up with a different name (commonly docker_pgdata, or
infra_pgdata on very old installs). Starting the new version against a renamed
volume would create a fresh, empty database and leave your data stranded in the old
volume.
Run this check once, before the first update to this version:
docker volume ls --format '{{.Name}}' | grep '_pgdata$'
If the only line is teamglimpse_pgdata, nothing to do — continue updating
normally. Installs done with the install-docker.sh script (in /opt/teamglimpse)
are always already on teamglimpse_pgdata.
If you see a different name (e.g. docker_pgdata), copy the data into the canonical
volume while the stack is stopped:
docker compose stop
# Replace docker_pgdata with the name reported by the check above.
docker volume create teamglimpse_pgdata
docker run --rm -v docker_pgdata:/from -v teamglimpse_pgdata:/to \
alpine cp -a /from/. /to/
docker compose up -d
cp -a preserves the file ownership and permissions that PostgreSQL requires. After
confirming your data is present in the running app, remove the old volume:
docker volume rm docker_pgdata
Uninstalling
To completely remove the Docker deployment, stop the containers, remove them along with the data volume, and delete the install directory.
1. Stop and remove containers and volumes:
cd /opt/teamglimpse
docker compose --env-file .env down -v
The -v flag removes the pgdata volume containing all database data. This permanently deletes all data. If you want to keep a backup, run export-db.sh first (see Backup below).
To stop and remove containers but keep the data volume for later use:
docker compose --env-file .env down
2. Remove the install directory:
sudo rm -rf /opt/teamglimpse
3. (Optional) Remove the Docker image:
docker rmi ghcr.io/teamglimpse/teamglimpse:latest
docker rmi postgres:16
4. (Optional) Remove orphaned volumes:
If you ran down without -v and later decide to delete the data:
docker volume rm teamglimpse_pgdata
Persistent Data
PostgreSQL data is stored in the teamglimpse_pgdata Docker volume and survives container restarts and image updates. The volume name is fixed, so it stays the same regardless of where the deployment directory lives.
The volume is managed by Docker and its location on the host filesystem is determined by the Docker storage driver. You can inspect the exact path with:
docker volume inspect teamglimpse_pgdata
The Mountpoint field shows the host directory (typically under /var/lib/docker/volumes/). Do not modify files in this directory directly — use the backup and restore procedures below.
Backup (Export)
TeamGlimpse uses a multi-database architecture: one control database plus a separate database for each organization. The bundled export-db.sh script handles this automatically — it discovers all organization databases, dumps each one, and packages everything into a single archive with a manifest.
Where the scripts live:
export-db.shandimport-db.shship in the release tarball underinfra/, which is the path used in the examples below. In a source checkout of the repository they live inscripts/instead — adjust the paths accordingly.
DATABASE_URL="postgres://teamglimpse:yourpassword@localhost:5432/teamglimpse" \
./infra/export-db.sh
This produces a file like teamglimpse-export-20260320-143000.tar.bz2. To specify a custom output path:
DATABASE_URL="..." ./infra/export-db.sh -o /backups/teamglimpse-backup.tar.bz2
Docker users: The script runs on the host and connects to PostgreSQL over the network. Ensure the database port is reachable. If you have not published the PostgreSQL port, you can either:
- Temporarily add a
portsmapping to thepostgresservice and recreate the container, or - Run the export from inside the postgres container:
docker compose exec postgres \
pg_dumpall -U teamglimpse > teamglimpse-backup.sql
Note that pg_dumpall produces a single SQL file (not the structured archive format), which cannot be used with import-db.sh. For full export/import compatibility, use the scripts with a reachable DATABASE_URL.
Restore (Import)
The import-db.sh script restores an export archive. It reads the manifest, drops existing databases, and recreates everything from the archive.
WARNING: Import destroys all existing data in the target databases.
DATABASE_URL="postgres://teamglimpse:yourpassword@localhost:5432/teamglimpse" \
./infra/import-db.sh teamglimpse-export-20260320-143000.tar.bz2
The script will show a summary and ask for confirmation before proceeding. To skip the confirmation prompt (useful for scripted restores):
DATABASE_URL="..." ./infra/import-db.sh -y export.tar.bz2
Migrating to Another Host
- On the old server — export the database:
DATABASE_URL="postgres://teamglimpse:oldpass@localhost:5432/teamglimpse" \
./infra/export-db.sh -o teamglimpse-migration.tar.bz2
- Copy files to the new server:
scp teamglimpse-migration.tar.bz2 .env docker-compose.yml infra/import-db.sh \
newserver:/path/to/teamglimpse/
- On the new server — start the stack and import:
# Start the stack (the entrypoint initializes an empty database)
docker compose up -d
# Import the backup (replace credentials with those from the new .env)
DATABASE_URL="postgres://teamglimpse:newpass@localhost:5432/teamglimpse" \
./infra/import-db.sh teamglimpse-migration.tar.bz2
Migrating Between Docker and Bare-Metal
The export/import scripts work against any reachable PostgreSQL instance — Docker or bare-metal. Just point DATABASE_URL at the appropriate server.
Docker → bare-metal:
# Export from Docker PostgreSQL
DATABASE_URL="postgres://teamglimpse:pass@localhost:5432/teamglimpse" \
./infra/export-db.sh -o migration.tar.bz2
# Import into bare-metal PostgreSQL
DATABASE_URL="postgres://teamglimpse:pass@localhost:5432/teamglimpse" \
./infra/import-db.sh migration.tar.bz2
Bare-metal → Docker:
# Export from bare-metal PostgreSQL
DATABASE_URL="postgres://teamglimpse:pass@localhost:5432/teamglimpse" \
./infra/export-db.sh -o migration.tar.bz2
# Import into Docker PostgreSQL (ensure the postgres container port is reachable)
DATABASE_URL="postgres://teamglimpse:dockerpass@localhost:5432/teamglimpse" \
./infra/import-db.sh migration.tar.bz2
Note: After migrating, verify that the
DATABASE_URLandPOSTGRES_PASSWORDin your target environment match the credentials of the target PostgreSQL instance. The import script connects using theDATABASE_URLyou provide — it does not carry over credentials from the source.
Installation from a tar.gz bundle
Quick Install
curl -fsSL https://github.com/TeamGlimpse/teamglimpse-release/releases/latest/download/install-tarball.sh | sudo bash
This downloads the latest release tarball and performs a full bare-metal installation: installs dependencies (nginx, PostgreSQL) if missing, initializes the database with auto-generated credentials, deploys the backend binary, frontend files, nginx configuration, and systemd service. The script is non-interactive and safe to inspect before running.
If TeamGlimpse is already installed, the script prints upgrade instructions and exits without making changes.
Manual Install
1. Extract Release
# Create a temporary directory for extraction
cd /tmp
# Extract the release
tar -xzf teamglimpse-v1.0.0-linux-amd64.tar.gz
# Navigate to the release directory
cd teamglimpse-v1.0.0
2. Database Setup
Create the PostgreSQL database and user:
sudo -u postgres psql
-- Create user (CREATEDB is required because TeamGlimpse creates per-organization databases)
CREATE USER teamglimpse WITH ENCRYPTED PASSWORD 'your_secure_password' CREATEDB;
-- Create database
CREATE DATABASE teamglimpse OWNER teamglimpse;
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE teamglimpse TO teamglimpse;
-- Connect to the database
\c teamglimpse
-- Enable required extensions
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
\q
Initialize the schema using the provided SQL:
PGPASSWORD=<your_secure_password> psql -h localhost -p 5432 -U teamglimpse -d teamglimpse -f infra/init.sql
3. Run the Deployment Script
For first-time installation:
sudo ./infra/deploy.sh
The script will:
- Create the
teamglimpsesystem user - Install the backend binary to
/opt/teamglimpse/ - Install frontend files to
/var/www/teamglimpse/ - Set up systemd service
- Configure nginx
Important: If nginx still shows the default “Welcome to nginx!” page after deployment, disable the default site — it conflicts because both listen on port 80 with server_name _:
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
4. Configure the Application
Edit the configuration file:
sudo nano /opt/teamglimpse/teamglimpse.conf
At minimum, update:
DATABASE_URL- PostgreSQL connection stringJWT_SECRET- Generate a secure random stringAPP_URL- Auto-detected from hostname; update to your actual domain if using DNS or TLS (required for SSO)
# Generate a secure JWT secret
openssl rand -base64 64 | tr -d '\n'
5. Start the Service
sudo systemctl restart teamglimpse
sudo systemctl status teamglimpse
6. Configure Domain (Optional)
If you have a domain name:
- Update nginx configuration:
sudo nano /etc/nginx/sites-available/teamglimpse
Change server_name _; to your domain:
server_name example.com www.example.com;
- Reload nginx:
sudo systemctl reload nginx
- Set up SSL with Let’s Encrypt:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Updating
To update to a new version, download the new release tarball, then:
1. Run Update
sudo ./infra/deploy.sh --update
The --update flag:
- Skips user/directory creation
- Preserves existing
teamglimpse.confconfiguration - Only updates binaries and frontend files
2. Database Migrations
No separate step is needed: deploy.sh --update runs infra/migrations/run_migration.sh --all before it installs the new binaries, and aborts the update if a migration fails.
Do not apply migration .sql files by hand with psql. TeamGlimpse stores each organization in its own database, and run_migration.sh is what discovers those databases and applies every pending migration to the control database and each organization database, recording what it applied. Running a single file against the control database alone leaves the organization databases behind.
To run migrations on their own (for example after restoring a backup), invoke the script directly from the extracted release:
sudo DATABASE_URL="postgres://teamglimpse:yourpassword@localhost:5432/teamglimpse" \
./infra/migrations/run_migration.sh --all
Uninstalling
1. Stop and disable the service:
sudo systemctl stop teamglimpse
sudo systemctl disable teamglimpse
2. Remove installed files:
# Remove the systemd unit file
sudo rm /etc/systemd/system/teamglimpse.service
sudo systemctl daemon-reload
# Remove the backend binary and configuration
sudo rm -rf /opt/teamglimpse
# Remove the frontend files
sudo rm -rf /var/www/teamglimpse
# Remove the nginx site configuration
sudo rm /etc/nginx/sites-enabled/teamglimpse
sudo rm /etc/nginx/sites-available/teamglimpse
sudo systemctl reload nginx
3. (Optional) Remove the system user:
sudo userdel teamglimpse
4. (Optional) Remove the PostgreSQL database:
Because TeamGlimpse creates a separate database for each organization, you must drop all of them before removing the user.
# Drop all databases owned by the teamglimpse user
sudo -u postgres psql -tAc \
"SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname = 'teamglimpse');" \
| while read -r db; do
sudo -u postgres psql -c "DROP DATABASE IF EXISTS \"$db\";"
done
# Now drop the user
sudo -u postgres psql -c "DROP USER IF EXISTS teamglimpse;"
This permanently deletes all data. If you want to keep a backup, run export-db.sh first (see Backup).
5. (Optional) Remove nginx:
If nginx was installed only for TeamGlimpse and is not used by other applications:
sudo apt purge nginx nginx-common
sudo apt autoremove
6. (Optional) Remove PostgreSQL:
If PostgreSQL was installed only for TeamGlimpse and is not used by other applications:
sudo apt purge postgresql postgresql-client
sudo apt autoremove
Warning: This removes the PostgreSQL server and all databases on the system, not just the TeamGlimpse database. Only do this if no other applications depend on PostgreSQL.
TLS/HTTPS with Let’s Encrypt
Serving TeamGlimpse over HTTPS is strongly recommended for any public-facing deployment. Certbot automates certificate issuance and renewal via Let’s Encrypt.
Prerequisites
- A domain name pointed at your server (DNS A record)
- Port 80 open (required for the HTTP-01 ACME challenge)
- TeamGlimpse already running and reachable at
http://your-domain.com
1. Install Certbot
sudo apt install -y certbot python3-certbot-nginx
2. Obtain a Certificate
sudo certbot --nginx -d example.com -d www.example.com
Certbot will:
- Verify domain ownership via an HTTP challenge
- Issue a certificate signed by Let’s Encrypt
- Automatically update the nginx configuration to enable HTTPS and redirect HTTP → HTTPS
When prompted, choose Redirect to enforce HTTPS for all traffic.
3. Verify Automatic Renewal
Certbot installs a systemd timer (or cron job) that renews certificates before they expire. Test it with:
sudo certbot renew --dry-run
A successful dry-run means certificates will renew automatically.
4. Update APP_URL
After enabling HTTPS, update APP_URL in your configuration file to use https://:
# Debian package
sudo nano /etc/teamglimpse/teamglimpse.conf
# Tarball
sudo nano /opt/teamglimpse/teamglimpse.conf
Change APP_URL=http://example.com to APP_URL=https://example.com, then restart the service:
sudo systemctl restart teamglimpse
This ensures invitation links and SSO redirects use the correct protocol.
5. Check Certificate Status
sudo certbot certificates
Firewall
Make sure port 443 is open in addition to port 80:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Port 80 must remain open — Certbot needs it for renewal challenges.
Troubleshooting
Certificate issuance fails: Confirm the domain resolves to your server’s public IP and that port 80 is reachable from the internet.
nginx fails to reload after renewal: Check sudo nginx -t for configuration errors, then sudo systemctl reload nginx.
Certificate expires unexpectedly: Verify the Certbot timer is active: sudo systemctl status certbot.timer.
Troubleshooting
Permission Denied to Create Database
If the logs show permission denied to create database, the PostgreSQL user is missing the CREATEDB privilege. TeamGlimpse creates a separate database for each organization, so this privilege is required.
Fix:
sudo -u postgres psql -c "ALTER USER teamglimpse CREATEDB;"
sudo systemctl restart teamglimpse
Port Already in Use
The installer and deployment scripts pre-flight check that the backend port (default 8080) is free before starting the service. If something else is already bound to that port, the install or upgrade aborts with a message like:
[ERROR] Port 8080 is already in use:
[ERROR] LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("some-process",pid=1234,fd=3))
Identify the offending process:
sudo ss -tlnp 'sport = :8080'
Then either:
- Stop the conflicting service and re-run the installer (Debian:
sudo dpkg --configure teamglimpse; tarball:sudo ./infra/deploy.sh). - Run TeamGlimpse on a different port — set
PORT=<n>in/etc/teamglimpse/teamglimpse.conf(Debian package) or/opt/teamglimpse/teamglimpse.conf(tarball), update theupstream teamglimpse_backendblock in/etc/nginx/sites-available/teamglimpseto match, then restart:
sudo systemctl restart teamglimpse
sudo systemctl reload nginx
For Docker deployments, set HTTP_PORT in .env (or pass it to install-docker.sh) — the installer’s port check uses that value.
Service Won’t Start
Check the logs:
sudo journalctl -u teamglimpse -f
Common issues:
- Database connection failed: Verify
DATABASE_URLinteamglimpse.conf - Port already in use: Check if another service is using port 8080
- Permission denied: Ensure proper ownership of
/opt/teamglimpse
Nginx Returns 502 Bad Gateway
The backend service isn’t running or isn’t responding:
# Check if backend is running
sudo systemctl status teamglimpse
# Check if port 8080 is listening
ss -tlnp | grep 8080
# Check nginx error logs
sudo tail -f /var/log/nginx/teamglimpse_error.log
Frontend Shows Blank Page
- Check that files exist:
ls -la /var/www/teamglimpse/
- Check nginx configuration:
sudo nginx -t
- Check browser console for JavaScript errors
Checking Service Health
# Service status
sudo systemctl status teamglimpse
# Recent logs
sudo journalctl -u teamglimpse -n 50
# Test API endpoint
curl http://localhost:8080/health
Security Recommendations
- Firewall: Only expose ports 80 and 443
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
-
SSL/TLS: Always use HTTPS in production with Let’s Encrypt
-
Database: Use a strong password and restrict access to localhost
-
JWT Secret: Use a cryptographically secure random string (minimum 64 characters)
-
Updates: Regularly update Ubuntu packages
sudo apt update && sudo apt upgrade
Directory Structure Reference
/opt/teamglimpse/
├── teamglimpse-backend # Main binary
└── teamglimpse.conf # Environment configuration
/var/www/teamglimpse/
├── index.html # Frontend entry point
├── assets/ # JS/CSS bundles
└── ... # Other static files
/etc/nginx/sites-available/
└── teamglimpse # Nginx configuration
/etc/systemd/system/
└── teamglimpse.service # Systemd unit
Support
- Check service logs:
sudo journalctl -u teamglimpse -f - Check nginx logs:
sudo tail -f /var/log/nginx/teamglimpse_error.log - Check PostgreSQL logs:
sudo tail -f /var/log/postgresql/postgresql-*-main.log