Skip to main content

Overview

The Muebles Roble application uses environment variables for configuration management, loaded from a .env file using python-dotenv.
Environment variables allow you to configure the application without hardcoding values, making it easy to switch between development, testing, and production environments.

Environment File Setup

Creating the .env File

  1. Copy the template:
cp .env-template .env
  1. Edit .env with your configuration
Never commit .env to version control. It’s already included in .gitignore.

Template File

The .env-template provides a reference:
.env-template
FLASK_APP=app.py
FLASK_ENV=development

DB_USER=example_user
DB_PASSWORD=example_password
DB_HOST=localhost
DB_PORT=3306
DB_NAME=example_db

Configuration Variables

Flask Configuration

FLASK_APP

FLASK_APP
string
default:"app.py"
Specifies the application entry point for Flask CLI commands.
FLASK_APP=app.py

FLASK_ENV

FLASK_ENV
string
default:"development"
Sets the Flask environment mode.Options:
  • development - Enable debug mode, auto-reload
  • production - Disable debug, optimize for performance
# Development
FLASK_ENV=development

# Production
FLASK_ENV=production
Never use FLASK_ENV=development in production. It exposes debugging information and is a security risk.

Database Configuration

DB_USER

DB_USER
string
required
MySQL database username.
DB_USER=muebles_user

DB_PASSWORD

DB_PASSWORD
string
required
MySQL database password.
DB_PASSWORD=secure_password_here
Use strong passwords in production. Consider using a password manager.

DB_HOST

DB_HOST
string
default:"localhost"
MySQL server hostname or IP address.
# Local development
DB_HOST=localhost

# Remote server
DB_HOST=192.168.1.100

# Cloud database
DB_HOST=mysql.example.com

DB_PORT

DB_PORT
integer
default:"3306"
MySQL server port.
DB_PORT=3306

DB_NAME

DB_NAME
string
required
MySQL database name.
DB_NAME=muebles_roble_db

Security Configuration

SECRET_KEY

SECRET_KEY
string
required
Secret key for session management and CSRF protection.Critical for:
  • Session encryption
  • CSRF token generation
  • Cookie signing
SECRET_KEY=your-very-secure-random-secret-key-here
The application requires SECRET_KEY in production and will raise an error if not set.

Generating a Secure SECRET_KEY

Generate a cryptographically secure key:
import secrets
print(secrets.token_hex(32))
Example output:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Configuration Loading

How Config is Loaded

The application loads configuration in config.py:
config.py
import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    # Database configuration
    DB_USER = os.getenv("DB_USER")
    DB_PASSWORD = os.getenv("DB_PASSWORD")
    DB_HOST = os.getenv("DB_HOST")
    DB_PORT = os.getenv("DB_PORT")
    DB_NAME = os.getenv("DB_NAME")

    # Build database URI
    SQLALCHEMY_DATABASE_URI = (
        f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
    )

    SQLALCHEMY_TRACK_MODIFICATIONS = False

    # SECRET_KEY is required for session management and CSRF protection
    SECRET_KEY = os.getenv("SECRET_KEY")
    if not SECRET_KEY:
        # Only allow default in development
        if os.getenv("FLASK_ENV") == "production":
            raise ValueError("SECRET_KEY must be set in production environment")
        SECRET_KEY = "dev-secret-key-change-in-production"

Loading Order

1

Load .env file

load_dotenv() reads .env file and loads variables
2

Access with os.getenv()

Variables are accessed using os.getenv("VAR_NAME")
3

Build config values

Config class builds database URI and other settings
4

Validate production

Raises error if SECRET_KEY missing in production

Environment-Specific Configurations

Development Environment

.env (development)
FLASK_APP=app.py
FLASK_ENV=development

# Local database
DB_USER=dev_user
DB_PASSWORD=dev_password
DB_HOST=localhost
DB_PORT=3306
DB_NAME=muebles_roble_dev

# Optional in development (auto-generated)
# SECRET_KEY=dev-secret-key

Production Environment

.env (production)
FLASK_APP=app.py
FLASK_ENV=production

# Production database
DB_USER=prod_user
DB_PASSWORD=very_strong_production_password
DB_HOST=prod-mysql-server.example.com
DB_PORT=3306
DB_NAME=muebles_roble_production

# REQUIRED in production
SECRET_KEY=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Production checklist:
  • FLASK_ENV=production
  • Strong SECRET_KEY set
  • Strong database password
  • .env file not committed to version control

Database URI Construction

The database URI is automatically constructed from environment variables:
mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}

Example URIs

# Development
mysql+pymysql://dev_user:dev_password@localhost:3306/muebles_roble_dev

# Production
mysql+pymysql://prod_user:strong_password@prod-server:3306/muebles_roble_prod

SQLAlchemy Configuration

SQLALCHEMY_DATABASE_URI

Automatically built from database environment variables (see above).

SQLALCHEMY_TRACK_MODIFICATIONS

SQLALCHEMY_TRACK_MODIFICATIONS = False
Disables Flask-SQLAlchemy event system (not needed and saves resources).

Accessing Environment Variables

In Python Code

import os

# Get environment variable
db_user = os.getenv("DB_USER")

# With default value
db_port = os.getenv("DB_PORT", "3306")

# Required variable (raises error if not set)
db_user = os.environ["DB_USER"]

In Application Config

Variables are accessed through the Config class:
from config import Config

app.config.from_object(Config)

# Access in application
db_uri = app.config['SQLALCHEMY_DATABASE_URI']
secret = app.config['SECRET_KEY']

Environment Variable Best Practices

Always add .env to .gitignore:
.gitignore
.env
.env.local
.env.*.local
Keep .env-template updated with all required variables:
.env-template
FLASK_APP=app.py
FLASK_ENV=development
DB_USER=example_user
# ... all variables with example values
Generate cryptographically secure keys:
import secrets
secrets.token_hex(32)
Check for required variables at startup:
if not SECRET_KEY and FLASK_ENV == "production":
    raise ValueError("SECRET_KEY required in production")
Comment your .env-template file:
# Flask application entry point
FLASK_APP=app.py

# Environment: development or production
FLASK_ENV=development

Troubleshooting

Common Issues

Error: ValueError: SECRET_KEY must be set in production environmentSolution: Add SECRET_KEY to your .env file:
SECRET_KEY=$(python -c "import secrets; print(secrets.token_hex(32))")
echo "SECRET_KEY=$SECRET_KEY" >> .env
Error: Can’t connect to MySQL serverCheck:
  • Verify DB_HOST, DB_PORT, DB_USER, DB_PASSWORD in .env
  • Ensure MySQL is running: sudo systemctl status mysql
  • Test connection: mysql -h $DB_HOST -u $DB_USER -p
  • Check firewall rules
Problem: Variables from .env not availableSolutions:
  • Ensure .env file is in project root
  • Check file is named exactly .env (not .env.txt)
  • Verify load_dotenv() is called in config.py
  • Restart the application
Problem: Using wrong database (dev vs prod)Solution: Check FLASK_ENV and DB_NAME:
echo $FLASK_ENV
echo $DB_NAME

Quick Reference

Required Variables

VariableRequiredDefaultDescription
DB_USERYes-Database username
DB_PASSWORDYes-Database password
DB_HOSTYes-Database host
DB_PORTYes-Database port
DB_NAMEYes-Database name
SECRET_KEYProddev-keySecret key for sessions
FLASK_APPNoapp.pyApplication entry point
FLASK_ENVNodevelopmentEnvironment mode

Example .env File

.env
FLASK_APP=app.py
FLASK_ENV=development

DB_USER=muebles_user
DB_PASSWORD=secure_password
DB_HOST=localhost
DB_PORT=3306
DB_NAME=muebles_roble_db

SECRET_KEY=your-secret-key-here

Next Steps

Setup Guide

Complete environment setup instructions

Deployment

Deploy to production

Project Structure

Understand the application architecture

Coding Conventions

Follow best practices

Build docs developers (and LLMs) love