Overview
Portfolio Hub API is configured entirely through environment variables, following the 12-Factor App methodology. This approach allows the same application build to be deployed across different environments without code changes.All environment variables can be set in a
.env file for local development or configured directly in your deployment platform.Database Configuration
These variables configure the MySQL database connection.MYSQL_HOST
The hostname or IP address of your MySQL server.Default: None (required)Examples:
localhost- Local developmentmysql-db- Docker Compose service namedb.example.com- Remote database server10.0.1.5- IP address
MYSQL_PORT
The port number on which MySQL is listening.Default:
3306Note: This is optional. If not provided, defaults to 3306.MYSQL_DATABASE
The name of the database schema to use.Default: None (required)Expected Value:
studiostkoh.portafolioMYSQL_USER
The MySQL username for authentication.Default: None (required)Permissions Required: The user must have:
SELECT,INSERT,UPDATE,DELETEon all tablesCREATE,ALTER,DROPfor Flyway migrations
MYSQL_PASSWORD
The password for the MySQL user.Default: None (required)Security: Use strong passwords (minimum 16 characters, mix of letters, numbers, symbols)
MYSQL_ROOT_PASSWORD
Required only for Docker Compose to initialize the MySQL container.Default: NoneUsage: Only needed when running MySQL in Docker. Not used by the application.
JWT Security Configuration
These variables configure JSON Web Token (JWT) authentication.JWT_TOKEN
The secret key used to sign and verify JWT tokens.Default: None (required)Security Requirements:
- Minimum 256 bits (32 characters) for HS256 algorithm
- Use cryptographically secure random strings
- Never commit to version control
- Rotate regularly in production
How to generate a secure JWT secret
How to generate a secure JWT secret
Use one of these methods to generate a secure random key:
OpenSSL
Node.js
Python
JWT_EXPIRATION_TIME
Token expiration time in minutes.Default: None (required)Recommended Values:
15-30minutes for high-security applications60minutes for standard applications480(8 hours) for development environments
Shorter expiration times increase security but require more frequent re-authentication. Consider implementing refresh tokens for better user experience.
Google Drive Integration
These variables configure the Google Drive API for file uploads (avatars, resumes, project covers, certificates).OAuth 2.0 Credentials
Create Google Cloud Project
Go to Google Cloud Console and create a new project.
DRIVE_OAUTH_CLIENT_ID
The OAuth 2.0 Client ID from Google Cloud Console.Default: None (required)Format:
xxxxxxxxxxxxx.apps.googleusercontent.comDRIVE_OAUTH_CLIENT_SECRET
The OAuth 2.0 Client Secret from Google Cloud Console.Default: None (required)Security: Keep this secret secure and never expose it publicly.
DRIVE_OAUTH_REFRESH_TOKEN
The OAuth 2.0 Refresh Token for long-term access.Default: None (required)Note: This token allows the application to access Google Drive without user interaction.
Google Drive Folder IDs
These variables specify the Google Drive folder IDs where different file types are stored.How to find Google Drive Folder IDs
How to find Google Drive Folder IDs
- Open Google Drive in your browser
- Navigate to the desired folder
- The URL will look like:
https://drive.google.com/drive/folders/FOLDER_ID_HERE - Copy the
FOLDER_ID_HEREpart
https://drive.google.com/drive/folders/1A2B3C4D5E6F7G8H9I0JFolder ID: 1A2B3C4D5E6F7G8H9I0JDRIVE_FOLDER_USER_AVATARS
Folder ID for storing user avatar images.
DRIVE_FOLDER_USER_RESUMES
Folder ID for storing user resume/CV files (PDF).
DRIVE_FOLDER_PROJECTS_COVER
Folder ID for storing project cover images.
DRIVE_FOLDER_SKILLS_ICON
Folder ID for storing skill icons.
DRIVE_FOLDER_CERTIFICATES
Folder ID for storing certificate files.
Email Configuration
These variables configure SMTP for sending emails (e.g., contact form submissions).SMTP_HOST
The SMTP server hostname.Default: None (required)Common Values:
smtp.gmail.com- Gmailsmtp-mail.outlook.com- Outlooksmtp.sendgrid.net- SendGridsmtp.mailgun.org- Mailgun
SMTP_PORT
The SMTP server port.Default: None (required)Common Ports:
587- TLS/STARTTLS (recommended)465- SSL25- Unencrypted (not recommended)
GMAIL_APP_EMAIL
The email address used to send emails.Default: None (required)Format: Valid email address
GMAIL_APP_PASSWORD
The password or app-specific password for SMTP authentication.Default: None (required)For Gmail: You must use an App Password, not your regular Gmail password.
How to create a Gmail App Password
How to create a Gmail App Password
- Go to your Google Account Security Settings
- Enable 2-Step Verification if not already enabled
- Go to “App passwords” section
- Generate a new app password for “Mail”
- Copy the 16-character password (spaces are optional)
CORS Configuration
CORS_ALLOWED_ORIGINS
Comma-separated list of allowed origins for Cross-Origin Resource Sharing (CORS).Default: None (required)Format:
origin1,origin2,origin3 (no spaces)Examples:- Development:
http://localhost:3000,http://localhost:5173 - Production:
https://yourdomain.com,https://www.yourdomain.com
Application Properties
The following properties are defined inapplication.properties and reference the environment variables above:
Complete .env Template
Here’s a complete.env file template with all required variables:
.env
Environment-Specific Configurations
- Development
- Docker Compose
- Production
.env.development
- Local database
- Longer JWT expiration for convenience
- Multiple localhost origins for different frontend ports
Security Best Practices
Use Strong Secrets
Generate cryptographically secure random values for all secrets, especially
JWT_TOKEN and passwords.Rotate Credentials
Regularly rotate JWT secrets, database passwords, and API credentials in production.
Never Commit Secrets
Add
.env to .gitignore. Use environment-specific templates (.env.example) instead.Use Secrets Management
In production, use dedicated secrets management tools like AWS Secrets Manager or HashiCorp Vault.
Validation Checklist
Before starting the application, verify:Troubleshooting
Application fails to start with 'JWT_TOKEN must be at least 256 bits'
Application fails to start with 'JWT_TOKEN must be at least 256 bits'
Your Update your
JWT_TOKEN is too short. Generate a longer secret:.env file with the new value.Database connection refused
Database connection refused
Verify:
- MySQL server is running
MYSQL_HOSTandMYSQL_PORTare correct- Firewall rules allow connection
- Database user has proper permissions
Google Drive upload fails
Google Drive upload fails
Check:
- OAuth credentials are valid and not expired
- Refresh token has
https://www.googleapis.com/auth/drive.filescope - All folder IDs exist and are accessible by the OAuth account
- Google Drive API is enabled in Google Cloud Console
Email sending fails
Email sending fails
For Gmail:
- Ensure 2-Step Verification is enabled
- Use an App Password, not your regular password
- Check that “Less secure app access” is not blocking the connection
- Verify SMTP host and port
- Check firewall rules for outbound SMTP traffic
CORS errors in browser
CORS errors in browser
Add your frontend origin to Restart the application after changing this value.
CORS_ALLOWED_ORIGINS:Next Steps
Docker Deployment
Deploy using Docker and Docker Compose
API Authentication
Learn how to authenticate with JWT