Skip to main content

Overview

Med Agenda uses environment variables for configuration, following the 12-factor app methodology. This allows the same application build to be deployed across different environments.

Configuration Sources

Environment variables can be provided through:
  • System environment variables: export VAR=value
  • .env file: For local development (Docker Compose)
  • application.properties: Default values and variable references
  • Docker: -e flag or env_file in docker-compose.yml
  • Cloud platforms: Platform-specific environment variable settings

Required Variables

These variables MUST be set for the application to function properly.

Database Configuration

SPRING_DATASOURCE_URL
string
required
PostgreSQL JDBC connection stringFormat: jdbc:postgresql://host:port/database?parametersExample:
jdbc:postgresql://localhost:5432/medagenda?sslmode=disable
Production Example (Neon.tech):
jdbc:postgresql://user:[email protected]/medagenda?sslmode=require
SPRING_DATASOURCE_USERNAME
string
required
Database usernameExample:
postgres
SPRING_DATASOURCE_PASSWORD
string
required
Database passwordExample:
your_secure_password
Never commit this to version control. Use secrets management in production.

Payment Integration

ABACATE-KEY
string
required
Abacate Pay API key for payment processingExample:
abct_live_xxxxxxxxxxxx
Keep this secret secure. Do not expose in logs or client-side code.

Optional Variables

Server Configuration

SERVER_PORT
integer
default:"8080"
Port number for the application serverExample:
SERVER_PORT=8080
If running in Docker, ensure the container exposes this port.

Database Pool Settings

DB_POOL_MAX
integer
default:"10"
Maximum number of connections in the HikariCP connection poolRecommended values:
  • Development: 5-10
  • Production: 20-50
  • High traffic: 50-100
Example:
DB_POOL_MAX=20

JPA/Hibernate Settings

JPA_DDL_AUTO
string
default:"update"
Hibernate DDL auto mode for schema managementOptions:
  • update: Auto-update schema (development)
  • validate: Validate schema only (production)
  • create: Drop and recreate schema (testing only)
  • none: No schema management
Example:
JPA_DDL_AUTO=validate
Use validate or none in production to prevent unintended schema changes.
JPA_SHOW_SQL
boolean
default:"false"
Enable SQL query loggingExample:
JPA_SHOW_SQL=true
Set to true for debugging, but disable in production for performance.

JVM Options (Docker only)

JAVA_OPTS
string
default:""
Custom JVM options for memory, garbage collection, etc.Example:
JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
Common options:
  • -Xms: Initial heap size
  • -Xmx: Maximum heap size
  • -XX:+UseG1GC: Use G1 garbage collector
  • -XX:+HeapDumpOnOutOfMemoryError: Create heap dump on OOM

Email Service Configuration

Med Agenda uses Resend for sending email notifications.
The Resend API key is currently hardcoded in the source (EmailService.java:16). For production, this should be configured via environment variable.
While not currently supported, these should be added for production:
# Email service configuration (to be implemented)
RESEND_API_KEY=re_xxxxxxxxxxxx
RESEND_FROM_EMAIL=[email protected]
Current behavior:
  • API Key: Hardcoded as re_6gEiCUYB_D8rKKD2XZPJRhUXQCh6gQwpX
  • From Email: [email protected]
Consider refactoring EmailService.java to read these from environment variables for better security.

Configuration Files

application.properties

The default configuration file with variable references:
spring.application.name=gestaoConsultasMedicas

# Database
spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/postgres?sslmode=disable}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME:postgres}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:postgres}
spring.datasource.hikari.maximum-pool-size=${DB_POOL_MAX:10}

# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=${JPA_DDL_AUTO:update}
spring.jpa.show-sql=${JPA_SHOW_SQL:false}
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect

# Server
server.port=${SERVER_PORT:8080}

# Payment
abacatepay.api-key=${ABACATE-KEY}

.env File Example

Create a .env file for local development:
# Database Configuration
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/medagenda?sslmode=disable
SPRING_DATASOURCE_USERNAME=postgres
SPRING_DATASOURCE_PASSWORD=postgres

# Server Configuration
SERVER_PORT=8080

# Database Pool
DB_POOL_MAX=10

# JPA Settings
JPA_DDL_AUTO=update
JPA_SHOW_SQL=true

# Payment API
ABACATE-KEY=your_dev_api_key_here

Setting Environment Variables

Linux/macOS

export SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:5432/medagenda"
export SPRING_DATASOURCE_USERNAME="postgres"
export SPRING_DATASOURCE_PASSWORD="your_password"
export ABACATE-KEY="your_api_key"

Windows

$env:SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:5432/medagenda"
$env:SPRING_DATASOURCE_USERNAME="postgres"
$env:SPRING_DATASOURCE_PASSWORD="your_password"

Docker

docker run -d \
  -e SPRING_DATASOURCE_URL="jdbc:postgresql://db:5432/medagenda" \
  -e SPRING_DATASOURCE_USERNAME="postgres" \
  -e SPRING_DATASOURCE_PASSWORD="postgres" \
  -e ABACATE-KEY="your_key" \
  med-agenda:latest

Security Best Practices

Follow these security practices to protect sensitive configuration:

1. Never Commit Secrets

Add .env to .gitignore:
.gitignore
# Environment variables
.env
.env.local
.env.production
*.env

# Application properties with secrets
application-local.properties
application-prod.properties

2. Use Different Keys per Environment

EnvironmentKey Type
DevelopmentTest/sandbox keys
StagingTest keys
ProductionLive production keys

3. Rotate Secrets Regularly

  • Change database passwords periodically
  • Rotate API keys every 90 days
  • Update credentials after team member changes

4. Use Secrets Management

For production deployments, use dedicated secrets management:
# Retrieve secret from AWS
export DB_PASSWORD=$(aws secretsmanager get-secret-value \
  --secret-id prod/medagenda/db-password \
  --query SecretString \
  --output text)

5. Restrict File Permissions

# Make .env readable only by owner
chmod 600 .env

# Verify permissions
ls -la .env
# Should show: -rw------- (600)

6. Validate Configuration

Create a startup check to ensure required variables are set:
@Component
public class ConfigValidator implements ApplicationListener<ApplicationReadyEvent> {
    @Value("${ABACATE-KEY:}")
    private String apiKey;
    
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        if (apiKey == null || apiKey.isEmpty()) {
            throw new IllegalStateException("ABACATE-KEY environment variable not set");
        }
    }
}

Verification

Verify your configuration is loaded correctly:

Check Environment Variables

# View all Java environment variables
env | grep -E '(SPRING|SERVER|JPA|DB_|JAVA_)'

# Test database connection
pg_isready -h your_host -p 5432 -U your_user

Application Startup Logs

Check logs for configuration values:
# Look for connection pool settings
docker-compose logs api | grep -i hikari

# Verify JPA DDL mode
docker-compose logs api | grep -i "ddl-auto"

# Check server port
docker-compose logs api | grep -i "Tomcat started on port"

Troubleshooting

Ensure variable is exported before running:
export VAR=value
echo $VAR  # Verify it's set
For Docker, ensure it’s in .env file or passed with -e flag.
Verify connection string format:
# Should be JDBC format, not PostgreSQL native
# Correct:
jdbc:postgresql://host:5432/db

# Incorrect:
postgresql://host:5432/db
Change the server port:
export SERVER_PORT=8081
Or kill process using the port:
lsof -ti:8080 | xargs kill -9
URL-encode special characters in connection string or use separate username/password variables:
# Preferred: separate variables
SPRING_DATASOURCE_USERNAME=user
SPRING_DATASOURCE_PASSWORD="p@ssw0rd!"

# Alternative: URL encode in connection string
# @ = %40, ! = %21, etc.

Environment Variable Reference

Complete List

VariableTypeDefaultRequiredDescription
SPRING_DATASOURCE_URLstringjdbc:postgresql://localhost:5432/postgresYesDatabase connection URL
SPRING_DATASOURCE_USERNAMEstringpostgresYesDatabase username
SPRING_DATASOURCE_PASSWORDstringpostgresYesDatabase password
ABACATE-KEYstring-YesAbacate Pay API key
SERVER_PORTinteger8080NoApplication server port
DB_POOL_MAXinteger10NoMax connection pool size
JPA_DDL_AUTOstringupdateNoHibernate DDL mode
JPA_SHOW_SQLbooleanfalseNoEnable SQL logging
JAVA_OPTSstring""NoCustom JVM options

Next Steps

Installation Guide

Complete installation setup

Docker Deployment

Deploy with Docker

Database Setup

Configure PostgreSQL

Build docs developers (and LLMs) love