Skip to main content

Overview

PrivyCode server uses environment variables for configuration. In local development, these are loaded from a .env file. In production, they should be set in your hosting platform’s environment settings.
The server automatically loads .env files when GO_ENV is not set to production. In production environments, set GO_ENV=production to skip .env file loading.

Required Variables

These variables must be set for the server to function properly.

PORT

PORT
string
default:"8080"
The port number the server will listen on.Example:
PORT=8080
If not set, the server defaults to port 8080. Some platforms like Railway may override this with their own PORT variable.

DATABASE_URL

DATABASE_URL
string
required
PostgreSQL connection string for the database.Format:
postgresql://username:password@host:port/database?options
Examples:
DATABASE_URL=postgresql://postgres:password@localhost:5432/privycode?sslmode=disable
Security: Always use sslmode=require in production. Only use sslmode=disable for local development.
Used in:
  • config/config.go:27 - Database connection initialization

GITHUB_CLIENT_ID

GITHUB_CLIENT_ID
string
required
OAuth application Client ID from GitHub.Example:
GITHUB_CLIENT_ID=Iv1.a1b2c3d4e5f6g7h8
How to get:
  1. Go to GitHub Developer Settings
  2. Click “OAuth Apps” → “New OAuth App”
  3. Copy the Client ID after creating the app
Used in:
  • internal/github/oauth.go:14 - OAuth configuration

GITHUB_CLIENT_SECRET

GITHUB_CLIENT_SECRET
string
required
OAuth application Client Secret from GitHub.Example:
GITHUB_CLIENT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
How to get:
  1. In your GitHub OAuth App settings
  2. Click “Generate a new client secret”
  3. Copy the secret immediately (it won’t be shown again)
Security: Never commit this value to version control. Keep it secret and rotate it if exposed.
Used in:
  • internal/github/oauth.go:15 - OAuth configuration

GITHUB_CALLBACK_URL

GITHUB_CALLBACK_URL
string
required
The callback URL GitHub will redirect to after authentication.Format:
{your_server_url}/github/callback
Examples:
GITHUB_CALLBACK_URL=http://localhost:8080/github/callback
This URL must exactly match the “Authorization callback URL” in your GitHub OAuth App settings.
Used in:
  • internal/github/oauth.go:17 - OAuth redirect configuration

FRONTEND_URL

FRONTEND_URL
string
required
The URL of your frontend application.Examples:
FRONTEND_URL=http://localhost:5173
Used for:
  • CORS configuration (must be added to internal/middleware/cors.go)
  • Redirecting users after authentication
  • Setting cookies with correct domain
If your frontend runs on a different port during development (e.g., Vite default is 5173), update this accordingly.

MOBILE_URL

MOBILE_URL
string
required
The URL for mobile app deep linking or mobile web access.Examples:
MOBILE_URL=http://localhost:5173
If you don’t have a separate mobile app, set this to the same value as FRONTEND_URL.

Optional Variables

GO_ENV

GO_ENV
string
default:"development"
Environment mode that controls .env file loading.Values:
  • production - Skips loading .env file, uses system environment variables
  • Any other value or unset - Loads .env file from project root
Examples:
# Don't set this variable, or set to:
GO_ENV=development
Code reference:
config/config.go
// To only load .env file in local development
if os.Getenv("GO_ENV") != "production" {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }
}
Always set GO_ENV=production when deploying to production platforms to prevent the server from looking for a .env file.

Example Configuration Files

.env.example (Included in Repository)

.env.example
PORT=8080
DATABASE_URL=your_database_url
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_CALLBACK_URL=http://localhost:8080/github/callback
GO_ENV="production" # For Production only
FRONTEND_URL=http://localhost:5173
MOBILE_URL=http://localhost:5173

Local Development (.env)

.env
PORT=8080
DATABASE_URL=postgresql://postgres:mypassword@localhost:5432/privycode?sslmode=disable
GITHUB_CLIENT_ID=Iv1.abc123def456
GITHUB_CLIENT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
GITHUB_CALLBACK_URL=http://localhost:8080/github/callback
FRONTEND_URL=http://localhost:5173
MOBILE_URL=http://localhost:5173

Production (Railway)

1

Navigate to your Railway service

Go to your project → Select your service → Variables tab
2

Add variables

GO_ENV=production
PORT=8080
GITHUB_CLIENT_ID=Iv1.abc123def456
GITHUB_CLIENT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
GITHUB_CALLBACK_URL=https://your-app.up.railway.app/github/callback
FRONTEND_URL=https://privycode.com
MOBILE_URL=https://privycode.com
3

DATABASE_URL is auto-provided

Railway automatically injects DATABASE_URL when you add a PostgreSQL service.

Production (Docker)

# Create .env file
GO_ENV=production
PORT=8080
DATABASE_URL=postgresql://user:pass@db-host:5432/privycode?sslmode=require
GITHUB_CLIENT_ID=Iv1.abc123def456
GITHUB_CLIENT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
GITHUB_CALLBACK_URL=https://api.yourdomain.com/github/callback
FRONTEND_URL=https://yourdomain.com
MOBILE_URL=https://yourdomain.com

# Run with .env file
docker run -d --env-file .env privycode-server

Environment Variable Loading

The server loads environment variables in the following order:
1

Check GO_ENV

The server checks if GO_ENV is set to production
2

Load .env file (development only)

If GO_ENV != "production", the server attempts to load .env from the project root using github.com/joho/godotenv
3

Read from system environment

All variables are read using os.Getenv(), which checks system environment variables
4

Use defaults where applicable

Some variables like PORT have default values if not set

Code References

Here’s where each environment variable is used in the codebase:

Database Configuration

config/config.go:18-31
func ConnectDB() {
    // To only load .env file in local development
    if os.Getenv("GO_ENV") != "production" {
        err := godotenv.Load()
        if err != nil {
            log.Fatal("Error loading .env file")
        }
    }

    dsn := os.Getenv("DATABASE_URL")
    database, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatalf("Error connecting to DB: %v", err)
    }
    // ...
}

GitHub OAuth Configuration

internal/github/oauth.go:11-20
func GetGitHubOAuthConfig() *oauth2.Config {
    return &oauth2.Config{
        ClientID:     os.Getenv("GITHUB_CLIENT_ID"),
        ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
        Endpoint:     github.Endpoint,
        RedirectURL:  os.Getenv("GITHUB_CALLBACK_URL"),
        Scopes:       []string{"read:user", "repo"},
    }
}

Server Port Configuration

cmd/server/main.go:28-31
port := os.Getenv("PORT")
if port == "" {
    port = "8080"
}

Validation Checklist

Use this checklist to ensure your environment is configured correctly:
1

All required variables are set

  • DATABASE_URL
  • GITHUB_CLIENT_ID
  • GITHUB_CLIENT_SECRET
  • GITHUB_CALLBACK_URL
  • FRONTEND_URL
  • MOBILE_URL
2

GitHub OAuth is configured

  • Callback URL in .env matches GitHub OAuth App settings
  • Client ID and Secret are correct
  • OAuth scopes include read:user and repo
3

Database connection works

  • PostgreSQL is running and accessible
  • DATABASE_URL format is correct
  • SSL mode is appropriate for your environment
4

CORS is configured

  • FRONTEND_URL is added to CORS allowed origins in internal/middleware/cors.go
  • No trailing slashes in URLs
5

Production settings

  • GO_ENV=production is set in production
  • Using sslmode=require for database in production
  • All secrets are stored securely (not in code)

Security Best Practices

Never commit sensitive environment variables to version control!

Use .gitignore

Ensure .env is in your .gitignore file

Rotate secrets

Regularly rotate GITHUB_CLIENT_SECRET and database passwords

Use secrets management

Consider using Railway secrets, AWS Secrets Manager, or similar

Minimal permissions

Use database users with minimal required permissions

Troubleshooting

Cause: .env file not found or GO_ENV=production is setSolution:
  • Ensure .env exists in project root
  • Don’t set GO_ENV=production in local development
  • Check file permissions: chmod 644 .env
Cause: Invalid DATABASE_URL or database not accessibleSolution:
  • Verify DATABASE_URL format
  • Test connection: psql "$DATABASE_URL"
  • Check if PostgreSQL is running
  • Verify network/firewall settings
Cause: Mismatch between callback URLs or invalid credentialsSolution:
  • Verify GITHUB_CALLBACK_URL exactly matches GitHub settings
  • Regenerate client secret if needed
  • Check OAuth app is not suspended
Cause: Frontend URL not in allowed originsSolution:
  • Add your FRONTEND_URL to internal/middleware/cors.go
  • Rebuild and restart server after changes
  • Ensure no trailing slashes in URLs

Next Steps

Setup Guide

Follow the complete local setup guide

Deployment

Deploy to production with proper configuration

Security

Learn about security best practices

API Reference

Explore available endpoints

Build docs developers (and LLMs) love