Skip to content

Server & Infrastructure

Ketan edited this page Mar 23, 2026 · 3 revisions

Backend Architecture

Multi-server

The compass backend runs 4 independent http servers within a single Go process each serving a distinct domain on its own port.

Server Port Responsibility
Auth Server 8080 User auth, profile management
Maps Server 8081 Location and review management
Assets Server 8082 Static files and uploads
Search Server 8083 Student Search

Database

The codebase uses GORM v2 as the ORM layer for PostgreSQL database interactions. Database connections are managed through a global connection pool accessible via connections.DB, which provides the primary *gorm.DB instance used across all services.

Entity-Relationship Diagram

erDiagram
    User ||--o| Profile : "has one"
    User ||--o{ ChangeLog : "tracked by"
    User ||--o{ Location : "contributed"
    User ||--o{ Review : "authored"
    User ||--o{ Notice : "published"
    User ||--o{ Image : "uploaded (OwnerID)"
    User ||--o{ Image : "biopics (polymorphic)"
    
    Location ||--o{ Review : "has many"
    Location ||--o{ Image : "polymorphic"
    Review ||--o{ Image : "polymorphic"
    Notice ||--o{ Image : "polymorphic"

    User {
        uuid user_id PK
        string email UK
        string password
        bool is_verified
        bool profile_pic
        string verification_token
        int role
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    Profile {
        uuid user_id PK,FK
        string email
        string name
        string roll_no
        string dept
        string course
        string gender
        string hall
        string room_number
        string home_town
        string bachhas
        string bapu
        bool visibility
        timestamp deleted_at
    }

    ChangeLog {
        uuid log_id PK
        uuid user_id FK
        string action
        timestamp created_at
    }

    Location {
        uuid location_id PK
        uuid contributed_by FK
        string name
        string description
        float32 latitude
        float32 longitude
        string location_type
        string status
        float32 average_rating
        int64 review_count
        string tag
        string contact
        string time
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    Review {
        uuid review_id PK
        uuid location_id FK
        uuid contributed_by FK
        string description
        int8 rating
        string status
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    Notice {
        uuid notice_id PK
        uuid contributed_by FK
        string entity
        string title
        string description
        string body
        string location
        timestamp event_time
        timestamp event_end_time
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    Image {
        uuid image_id PK
        uuid owner_id FK
        uuid parent_asset_id FK
        string parent_asset_type
        string status
        string path
        bool submitted
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

Loading

Migrations

Database migrations are done automatically through GORM's AutoMigrate feature during application startup, which creates and updates database schemas based on the Go model definitions.

Indexed Columns

Users Table

  • deleted_at: soft delete index for efficient filtering of deleted records
  • email: Unique constraint

Profiles Table

  • user_id: Unique index enforcing one-to-one relationship with User table

ChangeLog Table

  • user_id: Primary key index for efficient changelog lookups by user

Infrastructure

Configuration Management

Backend uses Viper for hierarchical configuration loading from multiple sources.

  1. config.yaml: primary configuration with non-sensitive keys.
  2. secret.yml: secrets like API keys, database passwords, SMTP credentials.

Note: A secret.yml.template for backend and .env.template for frontend is in the respective directories for easier setup.

Containerization (Docker)

Postgres

The PostgreSQL service provides the primary data store for all application data including users, profiles, locations, reviews, and notices.

Environment Variables

POSTGRES_USER: Database username (default: this_is_mjk)
POSTGRES_PASSWORD: Database password (default: postgres)
POSTGRES_DB: Database name (default: compass)

Health Check: The service uses pg_isready to verify database availability before dependent services start. The health check runs every 10 seconds with a 5-second timeout and 5 retry attempts.

healthcheck:
  test: ["CMD-SHELL", "pg_isready -U this_is_mjk -d compass"]
  interval: 10s
  timeout: 5s
  retries: 5

RabbitMQ

The RabbitMQ service handles asynchronous job processing for email delivery and content moderation tasks.

Environment Variables:

RABBITMQ_DEFAULT_USER: RabbitMQ username (default: this_is_mjk)
RABBITMQ_DEFAULT_PASS: RabbitMQ password (default: guest)

Health Check: The service uses rabbitmq-diagnostics ping to verify message broker readiness. The health check configuration matches PostgreSQL timing (10s interval, 5s timeout, 5 retries).

Management Interface: The RabbitMQ management UI is accessible at http://localhost:15672 for monitoring queues, connections, and message throughput. The UI credentials match the RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS values.

Multi Stage Docker Build

The application uses a multi-stage Dockerfile to minimize the final image size.

Stage 1: Builder

The builder stage uses golang:1.24.4-bookworm as the base image and installs build-time dependencies required for compiling the Go application with CGO-enabled libraries.

Build Dependencies Installed:

build-essential - GCC compiler and build tools
pkg-config - Library configuration helper
cmake - Build system for libheif
git - Source code retrieval
libde265-dev - HEVC/H.265 video codec (development headers)
libx265-dev - x265 encoder (development headers)
libvips-dev - Image processing library (development headers)
ca-certificates - SSL/TLS certificate validation

libheif Compilation: The Dockerfile builds libheif v1.18.2 from source to support HEIC/HEIF image format conversion. This library is essential for processing iPhone photos uploaded by users.

Go Build Process:

  • Copy go.mod and go.sum for dependency caching
  • Run go mod download to fetch dependencies
  • Copy application source code
  • Enable CGO with ENV CGO_ENABLED=1
  • Build static binary: go build -a -o server ./cmd

The -a flag forces rebuild of all packages. This ensures a clean build independent of cached artifacts.

Stage 2: Runtime

The runtime stage uses debian:bookworm-slim to create a minimal production image containing only runtime dependencies.

Exposed Ports: All four HTTP server ports are exposed: 8080, 8081, 8082, 8083.

Entrypoint: The container runs /server directly as the entrypoint, which starts all servers and workers defined in cmd/main.go.

Deployment Workflow

Starting the Application

# from the server directory
docker compose up -d

The -d flag runs containers in detached mode.

Monitoring Services

View running containers and their status

docker compose ps

Viewing logs for a specific service

docker compose logs -f server
docker compose logs -f postgres
docker compose logs -f rabbitmq

Access RabbitMQ management interface

http://localhost:15672

Stopping the Application

# Stop containers (preserves volumes)
docker compose down
 
# Stop containers and remove volumes (WARNING: deletes docker volumes)
docker compose down -v

Troubleshooting

Common Issues

Issue: server crash on startup with RabbitMQ connection error

This is a known race condition where RabbitMQ opens its port before fully initializing. The restart: on-failure policy automatically retries the connection. If crashes persist:

# check rabbitmq logs
docker compose logs rabbitmq

Issue: Database Migration errors

Ensure PostgreSQL is healthy before the server starts

# check PostgreSQL health
docker exec db_postgres pg_ready -U this_is_mjk -d compass

# view server logs for GORM errors
docker compose logs server | grep "GORM"

Issue: Port conflicts

If ports 5432, 5672, or 8080-8083 are already in use:

# check port usage
lsof -i :5432
lsof -i :5672

# stop conflicting services or modify docker compose port mappings

Issue: Volume permission errors

Ensure asset directory exits and are writable:

mkdir -p ./assets/{pfp,public,tmp}
chmod 755 ./assets/{pfp,public,tmp}