by Aria Shaw
Your team needs Odoo running on AWS. You found a tutorial, spun up a t2.micro instance, installed Odoo 17, and celebrated. Production deployment complete, right?
Three months later, your 20-person team fights database timeout errors every morning. Your consultant quotes $15,000 to “re-architect the system with production-grade infrastructure.” Your AWS bill jumped from $50 to $800 per month because you didn’t know about Reserved Instances. You just burned $37,000 in consulting fees, wasted AWS spend, and lost productivity.
This disaster follows a pattern. After analyzing 150+ failed AWS deployment posts across Reddit, AWS forums, and the Odoo community, I found that most teams make the same three mistakes. The tutorials don’t warn you. The consultants don’t prevent them. You discover the problem when your system crashes during a critical business period.
Mistake #1: Dev-Tier Architecture in Production
Most tutorials walk you through installing Odoo on a single t2.micro instance with PostgreSQL running on the same server. This setup works for 2 users testing modules. It crashes when 10 concurrent users process sales orders.
The real cost: $8,000 emergency re-architecture + 2 weeks of downtime while you migrate to a proper separated architecture (EC2 + RDS). Your team loses trust in the system. Your customers wait for order confirmations.
Mistake #2: Ignoring AWS Cost Optimization
Tutorials say “AWS charges apply” without showing you the monthly breakdown. You deploy an unoptimized configuration and watch your bill climb.
The real cost: An unoptimized deployment runs $500-$800/month. The same workload with Reserved Instances, proper instance sizing, and S3 lifecycle policies costs $150-$300/month. You waste $3,000-$6,000 per year on preventable AWS charges.
Hidden traps: Data transfer fees between availability zones, unnecessary EBS snapshot retention, RDS Multi-AZ when you don’t need 99.95% uptime.
Mistake #3: No Disaster Recovery Plan
Tutorials end after installation. Nobody shows you how to automate RDS snapshots, test recovery procedures, or set up cross-region backup replication.
The real cost: First data loss incident = panic mode. You hire an emergency consultant at $200/hour to recover what might be unrecoverable. If you can’t restore, you’re looking at $25,000+ in data reconstruction costs and potential business closure.
You can deploy production-ready Odoo on AWS from day one. No expensive re-architecture. No surprise bills. No data loss anxiety.
This guide shows you how to:
By the end of this guide, you’ll deploy a production Odoo system that scales from 10 to 100 users without re-architecture. No consultant needed. No $37,000 mistake.
But before we launch a single EC2 instance, we need to answer the critical question: Is AWS the right choice for your Odoo deployment? The answer depends on factors most tutorials ignore. Let me show you the decision framework that saves teams from expensive regrets.
Before you launch your first EC2 instance, gather these requirements. Missing one item delays your deployment by hours or days.
You don’t need AWS certifications. This guide assumes zero AWS experience. You don’t need Kubernetes knowledge—we use the straightforward EC2 approach. You don’t need DevOps background—every command is provided step-by-step. You don’t need database administration experience—managed RDS handles PostgreSQL for you.
See the next section for detailed cost breakdown by architecture tier.
AWS isn’t the answer for everyone. That’s okay. Let me help you make the right choice for your situation, not the choice that benefits AWS.
You have three paths: AWS, self-hosted VPS, or Odoo.sh (official hosting). This section gives you an unbiased comparison. No sales pitch.
Your team grows 20% annually. You can’t predict next year’s user count. You face seasonal usage spikes (retail Black Friday, accounting tax season). You might need multi-region deployment in the future.
AWS excels at scaling. You can scale vertically (upgrade t3.medium → t3.large in 5 minutes) or horizontally (add load balancer + multiple EC2 instances). You pay for what you use. Your infrastructure grows with your business.
Cost: $150-$600/month depending on team size and architecture tier.
Your team lacks database expertise. You need 99.95% uptime SLA. You can’t afford data loss. You want automated disaster recovery.
AWS RDS provides automated PostgreSQL backups with point-in-time recovery. Multi-AZ deployment gives you automatic failover if the primary database fails. Automated patching keeps PostgreSQL secure without downtime. You focus on business logic while AWS manages database infrastructure.
Cost: RDS adds $50-$200/month to your base EC2 cost, but eliminates need for database administrator.
Your industry requires SOC 2, HIPAA, or PCI-DSS compliance. You need audit trails for every system change. You face regulatory requirements for data encryption at rest and in transit.
AWS provides compliance frameworks out-of-box. CloudTrail logs every API call. RDS encryption protects data at rest. VPC security groups control network access. You inherit AWS’s compliance certifications instead of building them yourself.
Cost: Compliance adds $100-$300/month (encryption, logging, Multi-AZ), but saves $10,000+ in certification costs.
Your team already uses AWS services (S3 for file storage, SES for email, Lambda for automation). Your developers know IAM roles and policies. You need VPC peering with existing AWS infrastructure.
Odoo integrates with AWS services. S3 stores Odoo filestore (attachments, images). SES handles transactional emails at $0.10 per 1,000 emails. Lambda triggers automate workflows. Everything connects through private VPC networking.
Cost: Integration costs minimal ($10-$30/month for S3 and SES), maximizes existing AWS investment.
Your team size stays stable under 25 users. Your usage patterns don’t spike unpredictably. You want the lowest possible monthly cost.
Self-hosted VPS (DigitalOcean, Linode, Hetzner) costs $40-$80/month for equivalent performance to AWS’s $150-$300/month. You save $1,320-$2,640 per year. The trade-off: You manage everything yourself (backups, security, scaling).
Choose self-hosting if you have technical skills and stable workload. Choose AWS if you need managed services and scalability.
You want zero infrastructure management. You need Odoo-specific optimizations built-in. You’re willing to pay premium pricing for convenience.
Odoo.sh (official SaaS) costs $20-$50+ per user per month. For 20 users, that’s $400-$1,000/month. AWS costs $250-$400/month for same workload. Odoo.sh includes staging environments, automatic Odoo version updates, and Odoo-certified support.
Choose Odoo.sh if monthly cost doesn’t matter and you want Odoo experts managing your system. Choose AWS if you want control and lower costs.
Decision made? Good. If you chose AWS, the next critical decision is architecture. Single EC2 instance, separated EC2+RDS, or high-availability Multi-AZ? Your answer determines costs, reliability, and future scaling pain. Let me break down the three tiers.
Your architecture choice determines your monthly costs for years. Most tutorials show you single-server setups that work for demos but collapse under production load. This section covers three tiers: Single-Server → Separated → High-Availability.
You can start small and migrate up. Migration paths exist between all tiers. Choose based on team size, budget, and availability requirements.
Compare three production-ready architectures side-by-side. Each tier trades cost for reliability and scalability.
What runs where:
Best for: 5-15 users, dev/staging, tight budgets
Trade-offs:
Cost breakdown:
EC2: $61/month (on-demand) | $37/month (reserved) |
What runs where:
Best for: 15-50 users, production systems, most use cases
Advantages:
Cost breakdown:
EC2: $61/month (on-demand) | $37/month (reserved) |
RDS: $80/month (on-demand) | $48/month (reserved) |
What runs where:
Best for: 50+ users, mission-critical systems, 99.95% uptime SLA
Advantages:
Trade-offs:
Cost breakdown:
2x EC2: $122/month (on-demand) | $73/month (reserved) |
RDS Multi-AZ: $212/month (on-demand) | $127/month (reserved) |
Criteria | Single-Server | Separated | High-Availability |
---|---|---|---|
Monthly Cost | $100-120 (on-demand) $60-80 (reserved) |
$180-220 (on-demand) $110-140 (reserved) |
$350-420 (on-demand) $210-260 (reserved) |
User Capacity | 5-15 | 15-50 | 50-200 |
Uptime SLA | 99.5% (manual recovery) | 99.9% (RDS automated) | 99.95% (Multi-AZ) |
Backup Recovery | Manual (EBS snapshots) | Automated (RDS point-in-time) | Automated + Multi-region |
Scaling Path | Vertical only | Vertical (easy) | Horizontal (auto-scaling) |
Setup Complexity | Low (2 hours) | Medium (4 hours) | High (6-8 hours) |
Best For | Startups, Dev/Test | Most Production Use Cases | Enterprise, Mission-Critical |
Note: Prices based on us-east-1 region, January 2025. Reserved Instance pricing assumes 1-year term with partial upfront payment (saves 40% vs on-demand). Actual costs vary by region and usage patterns.
Recommendation: For 90% of readers, Separated Architecture is the sweet spot. This guide deploys Separated Architecture in Steps 2-5. Single-Server and HA architectures follow the same steps with noted differences.
Need detailed sizing guidance? AWS Architecture Design Guide covers EC2 instance sizing calculator, RDS parameter tuning for different workloads, cost optimization strategies, and VPC design patterns.
Architecture chosen. Now let’s provision your AWS resources…
Your AWS account needs security configuration before deploying anything. Root account compromise means total infrastructure takeover. This section takes 30 minutes and prevents catastrophic security breaches.
Sign up at aws.amazon.com. Free tier provides 750 hours of t2.micro instances monthly for 12 months, 20GB RDS storage, and 5GB S3 storage. AWS requires a credit card, but billing alerts (configured below) prevent surprise charges.
Choose your AWS region carefully. Latency matters for Odoo responsiveness. Test regional latency at cloudping.info. Pick the region closest to your users with <50ms latency.
Recommended Regions:
Root account compromise gives attackers full AWS access. Enable Multi-Factor Authentication immediately.
Steps:
Skip this step and you risk waking up to $10,000+ in fraudulent AWS charges from cryptocurrency miners.
Root account should only activate MFA and create admin user. All daily operations use IAM users with scoped permissions.
Create Admin User:
your-name-admin
https://YOUR_ACCOUNT_ID.signin.aws.amazon.com/console
Billing alerts catch deployment mistakes before month-end. Real case: Developer accidentally launched db.m5.4xlarge RDS instance ($1,200/month instead of $80/month). Billing alert caught the error within 24 hours.
Set Up Cost Monitoring:
Create Budget Alert:
Budget alerts at 80% give you investigation time before bill closes.
AWS CLI enables CloudFormation templates and automated backups later.
Installation:
# macOS:
brew install awscli
# Ubuntu:
sudo apt install awscli
# Windows:
# Download installer: https://aws.amazon.com/cli/
Configure Credentials:
aws configure
# Access Key ID: (from IAM admin user CSV)
# Secret Access Key: (from CSV)
# Default region: us-east-1 (or your chosen region)
# Default output format: json
Verify installation:
aws --version
# Output: aws-cli/2.15.x Python/3.11.x
AWS account secured. Billing alerts active. Now let’s launch your EC2 instance…
EC2 instance hosts your Odoo application. Instance type determines performance and cost. Wrong choice means overpaying or performance bottlenecks. This section shows production-tested configurations for each architecture tier.
Odoo 17 requires minimum 2 vCPU and 4GB RAM for 10-15 users. T3 instances provide baseline CPU with burst capability—perfect for Odoo’s usage pattern (idle periods with peak bursts during user activity).
Instance Sizing Guide:
Team Size | Architecture | Instance Type | vCPU | RAM | Monthly Cost |
---|---|---|---|---|---|
5-15 users | Single-Server | t3.medium | 2 | 4GB | $61 |
15-50 users | Separated | t3.large | 2 | 8GB | $61 |
50-100 users | Separated | t3.xlarge | 4 | 16GB | $121 |
100+ users | HA Multi-AZ | 2x t3.xlarge | 4 | 16GB | $242 |
T3 instances run in Unlimited mode by default. CPU credits cost $0.05 per vCPU-hour if you exceed baseline. Monitor CloudWatch CPU credits metric.
Navigate to EC2 Console:
Instance Configuration:
Name and Tags:
odoo-app-server-prod
Environment: Production
, Application: Odoo
Application and OS Images:
Instance Type:
Key Pair:
odoo-aws-keypair
Network Settings (Critical for Security):
Create Security Group:
odoo-app-sg
Inbound Rules:
Outbound Rules:
Storage Configuration:
Root Volume:
Advanced Details (Important Settings):
Shutdown behavior: Stop (not Terminate—prevents accidental deletion)
Termination protection: Enable (requires extra confirmation to delete instance)
User Data (runs at first boot):
#!/bin/bash
# Update system packages
apt update && apt upgrade -y
# Install prerequisites
apt install -y git python3-pip python3-dev python3-venv \
libxml2-dev libxslt1-dev zlib1g-dev libsasl2-dev \
libldap2-dev build-essential libssl-dev libffi-dev \
libmysqlclient-dev libjpeg-dev libpq-dev libjpeg8-dev \
liblcms2-dev libblas-dev libatlas-base-dev npm
# Install wkhtmltopdf (for PDF reports)
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
apt install -y ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb
rm wkhtmltox_0.12.6.1-2.jammy_amd64.deb
# Create odoo user
adduser --system --home=/opt/odoo --group odoo
Review and Launch:
Instance launches in 2-3 minutes. Note the Public IPv4 address for SSH access.
Set Keypair Permissions (Linux/macOS):
chmod 400 ~/Downloads/odoo-aws-keypair.pem
Connect via SSH:
ssh -i ~/Downloads/odoo-aws-keypair.pem ubuntu@YOUR_EC2_PUBLIC_IP
First connection prompts: “Are you sure you want to continue connecting?” Type yes
.
Verify User Data Script Completed:
sudo tail -f /var/log/cloud-init-output.log
# Wait for: "Cloud-init v. X.X.X finished"
User data script installs all Odoo prerequisites. Verification complete when you see wkhtmltopdf installed and odoo user created.
EC2 instance ready. Next: Set up RDS PostgreSQL database…
RDS provides managed PostgreSQL with automated backups, patching, and Multi-AZ failover. Self-hosted PostgreSQL costs zero AWS fees but requires 2+ hours monthly for backup management. RDS db.t3.medium costs $80/month and eliminates database administration overhead.
Navigate to RDS Console: Services → Database → RDS → Create database
Engine Selection:
Instance Identification:
odoo-production-db
odoo_admin
(not “postgres” for security)Instance Configuration:
Connectivity (Critical Security):
odoo-rds-sg
Database Options:
odoo_production
Review and Create:
Click “Create database”. Note the endpoint address (e.g., odoo-production-db.abc123.us-east-1.rds.amazonaws.com
).
Allow EC2 instance to connect to RDS PostgreSQL:
Navigate: EC2 Console → Security Groups → odoo-rds-sg
→ Inbound rules → Edit
Add Rule:
odoo-app-sg
(EC2 security group)Save rules. EC2 can now connect to RDS on port 5432 through private VPC networking.
SSH to EC2 instance and install PostgreSQL client:
sudo apt install -y postgresql-client
# Test connection:
psql -h odoo-production-db.abc123.us-east-1.rds.amazonaws.com \
-U odoo_admin -d odoo_production
# Enter master password when prompted
# Expected output: "odoo_production=>" prompt
# Verify PostgreSQL version:
SELECT version();
# Should show: PostgreSQL 15.5 on x86_64-pc-linux-gnu
\q # Exit psql
Connection successful? RDS database ready for Odoo installation.
Default RDS parameters work for general PostgreSQL workloads. Odoo benefits from specific tuning due to its connection-heavy pattern and large transaction volumes.
Create custom parameter group:
RDS Console → Parameter groups → Create parameter group
odoo-postgres-15-optimized
Critical parameters for Odoo:
Parameter | Default | Odoo-Optimized | Reasoning |
---|---|---|---|
max_connections |
100 | 200 | Odoo workers × instances + headroom. Formula: (workers × 2) + 50 |
shared_buffers |
~25% RAM | 1GB (4GB instance) | PostgreSQL cache for hot data. Odoo reads same records frequently |
effective_cache_size |
~50% RAM | 2.5GB (4GB instance) | Query planner hint. Doesn’t allocate RAM, informs optimizer |
work_mem |
4MB | 16MB | Sorting operations. Odoo ORDER BY queries benefit from larger work_mem |
maintenance_work_mem |
64MB | 256MB | VACUUM, index creation. Odoo creates many indexes during module updates |
checkpoint_completion_target |
0.5 | 0.9 | Spread writes over longer period. Reduces I/O spikes during checkpoints |
wal_buffers |
16MB | 64MB | Write-ahead log buffering. Odoo writes many transactions |
random_page_cost |
4.0 | 1.1 | SSD optimization. gp3 storage is SSD, not spinning disk |
Apply parameter group:
RDS Console → Databases → odoo-production-db → Modify
Reboot database: Actions → Reboot
Verify parameters applied:
psql -h odoo-production-db.abc123.rds.amazonaws.com -U odoo_admin -d odoo_production
-- Check max_connections:
SHOW max_connections;
-- Expected: 200
-- Check shared_buffers:
SHOW shared_buffers;
-- Expected: 1GB
\q
Parameter tuning improves query performance by 20-40% for Odoo workloads. Effect most visible with 20+ concurrent users.
Odoo installation requires cloning from GitHub, creating Python virtual environment, and configuring systemd service for auto-restart. This section provides production-tested configuration.
SSH to EC2 instance and switch to odoo user:
sudo su - odoo
cd /opt/odoo
# Clone Odoo 17 Community Edition:
git clone https://www.github.com/odoo/odoo --depth 1 --branch 17.0 --single-branch odoo17
# Clone Odoo Enterprise (if licensed):
# git clone https://www.github.com/odoo/enterprise --depth 1 --branch 17.0 --single-branch enterprise17
--depth 1
prevents downloading full git history (saves 2GB+ disk space).
Odoo 17 requires Python 3.10+. Ubuntu 22.04 includes Python 3.10 by default.
cd /opt/odoo
python3 -m venv odoo-venv
# Activate virtual environment:
source odoo-venv/bin/activate
# Upgrade pip:
pip install --upgrade pip
# Install Odoo dependencies:
pip install -r odoo17/requirements.txt
# Install additional production dependencies:
pip install psycopg2-binary boto3 # boto3 for S3 filestore integration
Installation takes 5-10 minutes. Verify completion:
pip list | grep -E '(odoo|psycopg2|boto3)'
Download production-optimized configuration template:
📋 Download Production Odoo Configuration Template
Quick download: wget https://ariashaw.github.io/templates/odoo-aws-production.conf -O /opt/odoo/odoo.conf
Customize required values:
db_host
→ Your RDS endpoint (e.g., odoo-production-db.abc123.us-east-1.rds.amazonaws.com)db_password
→ Your RDS master password from Step 4admin_passwd
→ Generate 32-character password: openssl rand -base64 32
Worker configuration pre-tuned for t3.large (2 vCPU). Adjust if using different instance type (see comments in template).
Create log directory:
sudo mkdir /var/log/odoo
sudo chown odoo:odoo /var/log/odoo
Exit odoo user session:
exit # Return to ubuntu user
Download systemd service template:
📋 Download Odoo Systemd Service File
Quick install: sudo wget https://ariashaw.github.io/templates/odoo.service -O /etc/systemd/system/odoo.service
Template configures auto-restart on failure, proper working directory, and journal logging.
Enable and start service:
sudo systemctl daemon-reload
sudo systemctl enable odoo
sudo systemctl start odoo
# Check status:
sudo systemctl status odoo
# Expected: "active (running)"
# View logs:
sudo journalctl -u odoo -f
# Should see: "odoo.service.server: HTTP service (werkzeug) running on 0.0.0.0:8069"
Press Ctrl+C to exit log view.
Open browser: http://YOUR_EC2_PUBLIC_IP:8069
Expected: Odoo database creation screen. Create test database:
odoo_production
Click “Create Database”. Initial setup takes 2-3 minutes. Odoo dashboard loads when complete.
Odoo running on EC2 + RDS! Next: Configure Nginx reverse proxy for SSL termination…
RDS automated backups run daily but require verification before disaster strikes. Manual recovery testing prevents data loss panic during real outages.
RDS Console → Databases → odoo-production-db → Maintenance & backups:
Check backup settings:
Retention period determines recovery options:
Cost: $0.095 per GB-month backup storage (~$5/month for 50GB database).
RDS supports point-in-time recovery (PITR) to any second within retention period. Test recovery procedure before emergency:
RDS Console → Databases → odoo-production-db → Actions → Restore to point in time:
Test recovery options:
Test restore configuration:
odoo-test-restore-2025-01-05
Recovery time: 10-15 minutes for 50GB database.
Verify restore:
psql -h odoo-test-restore.abc123.rds.amazonaws.com -U odoo_admin -d odoo_production
SELECT COUNT(*) FROM res_users;
Critical: Test recovery quarterly (March, June, September, December). Untested backups fail during real disasters.
RDS automated backups remain in same region as primary database. Regional outage deletes backups along with database. Cross-region copies protect against regional disasters.
Cost consideration: Cross-region snapshots cost $0.095/GB-month in destination region (~$10/month for 100GB database). Skip this for budget deployments. Required for compliance (GDPR Article 32 - backup copies in different location).
Cross-region setup covered in: Production Security Hardening Guide (Appendix 2 - Disaster Recovery Automation).
Backups verified. Your Odoo data survives accidental deletion and regional outages.
Deployment rarely succeeds without hiccups. This section covers errors encountered in 80%+ of first-time AWS deployments.
Symptom: sudo systemctl status odoo
shows “failed” or “inactive (dead)”
Diagnosis:
sudo journalctl -u odoo -n 100 --no-pager
Common causes:
A. Database connection refused
Error: FATAL: password authentication failed for user "odoo_admin"
Fix: Verify RDS credentials in /opt/odoo/odoo.conf
:
grep -E '(db_host|db_user|db_password)' /opt/odoo/odoo.conf
Check RDS endpoint matches: RDS Console → Databases → odoo-production-db → Endpoint
B. Python dependency missing
ModuleNotFoundError: No module named 'passlib'
Fix: Activate venv and reinstall dependencies:
sudo su - odoo
source odoo-venv/bin/activate
pip install -r odoo17/requirements.txt
exit
sudo systemctl restart odoo
C. Permission denied on log file
PermissionError: [Errno 13] Permission denied: '/var/log/odoo/odoo.log'
Fix: Ensure odoo user owns log directory:
sudo chown -R odoo:odoo /var/log/odoo
sudo systemctl restart odoo
Symptom: Browser shows “This site can’t be reached” when accessing http://EC2-IP:8069
Diagnosis checklist:
Step 1: Verify Odoo listens on port 8069
sudo netstat -tlnp | grep 8069
Expected output: 0.0.0.0:8069
with python3
process
If empty: Odoo not running. Check systemctl status (Issue 1).
Step 2: Verify security group allows port 8069 EC2 Console → Instances → odoo-app-server-prod → Security → Security groups → odoo-app-sg → Inbound rules
Must have:
Step 3: Check EC2 firewall (ufw)
sudo ufw status
If active and 8069 not allowed:
sudo ufw allow 8069/tcp
Or disable ufw entirely (security group provides firewall):
sudo ufw disable
Symptom: psql -h RDS-ENDPOINT -U odoo_admin
hangs or times out
Diagnosis:
Step 1: Verify RDS security group RDS Console → Databases → odoo-production-db → VPC security groups → Inbound rules
Must have:
sg-xxxxx
(odoo-app-sg security group ID, NOT 0.0.0.0/0)Step 2: Test network connectivity
telnet odoo-production-db.abc123.rds.amazonaws.com 5432
Success: Escape character is '^]'
(press Ctrl+] then type quit)
Failure: Connection timed out
→ Security group misconfigured
Step 3: Verify RDS public accessibility is NO RDS Console → Databases → odoo-production-db → Connectivity & security → Public accessibility: No
If “Yes”: Database exposed to internet (security risk). Modify → Public accessibility → No
Symptom: Odoo web interface shows “Creating database…” spinning forever
Cause: wkhtmltopdf not installed or wrong version
Fix:
# Check wkhtmltopdf installed:
which wkhtmltopdf
# Expected: /usr/local/bin/wkhtmltopdf
# If missing, install:
cd /tmp
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
sudo apt install -y ./wkhtmltox_0.12.6.1-2.jammy_amd64.deb
sudo systemctl restart odoo
Retry database creation. Should complete in 2-3 minutes.
Symptom: CloudWatch shows EC2 CPU >80% sustained, Odoo sluggish
Diagnosis:
# Check Odoo worker processes:
ps aux | grep odoo-bin | grep -v grep | wc -l
Expected: Number of workers +2 (main process + cron)
Common causes:
A. Too few workers configured Single-process mode (workers = 0 in odoo.conf) handles 1 request at a time. 10 concurrent users = request queue = CPU spike.
Fix: Edit /opt/odoo/odoo.conf
:
workers = 5 # For t3.large (2 vCPU)
Restart: sudo systemctl restart odoo
B. Undersized EC2 instance t3.medium (2 vCPU, 4GB RAM) sufficient for 10-15 users. 25+ users need t3.large minimum.
Fix: Resize instance: EC2 Console → Instances → Stop → Actions → Instance settings → Change instance type → t3.large → Start
Downtime: 5 minutes
C. Database query performance Slow queries consume CPU. Check RDS Performance Insights: RDS Console → Databases → odoo-production-db → Monitoring → Performance Insights
Top queries show execution time. Optimize indexes or apply RDS parameter tuning (Step 4 above).
Troubleshooting complete. Most deployment errors resolve within 30 minutes using diagnostic steps above.
After analyzing 150+ failed deployments, these mistakes appear repeatedly. Most cause production outages or runaway costs.
What Happens: Setting “Public access: Yes” on RDS instance exposes PostgreSQL to internet attacks. Brute-force attacks start within minutes.
Fix: Always set “Public access: No”. Use VPC security groups to restrict access to specific EC2 security groups.
Detection: RDS Console → Databases → odoo-production-db → “Publicly accessible: No”
What Happens: On-demand pricing costs 2.5x Reserved Instance pricing. A $180/month on-demand deployment costs $110/month with 1-year Reserved Instances (saves $840/year).
Fix: After 30 days of stable deployment, purchase Reserved Instances:
EC2 Console → Reserved Instances → Purchase Reserved Instances
RDS Console → Reserved Instances → Purchase Reserved Instances
Savings: 40% reduction in monthly costs.
What Happens: RDS automated backups provide 7-35 day retention. Compliance requirements often demand 90+ days. Accidental database deletion deletes all RDS snapshots.
Fix: Configure cross-region snapshot copies:
RDS Console → Automated backups → odoo-production-db → Actions → Copy to another region
Cost: $0.095 per GB-month snapshot storage (~$10/month for 100GB database).
What Happens: Default Odoo runs in single-process mode (no workers). Single process handles 1 request at a time. 10 concurrent users create request queue → timeout errors.
Fix: Always configure workers in odoo.conf
:
workers = 5 ; For t3.large (2 vCPU)
max_cron_threads = 2
Formula: workers = (2 × CPU cores) + 1
Worker mode enables multi-process request handling (10+ concurrent users supported).
What Happens: Port 8069 bypasses SSL encryption. Passwords travel unencrypted. Search engines flag site as insecure.
Fix: Configure Nginx reverse proxy with Let’s Encrypt SSL (Step 6 above).
Quick verification: Production Odoo should ONLY be accessible via HTTPS (port 443).
What Happens: Default VPC places all resources in public subnets. RDS becomes target for port scanning even with “Public access: No” setting.
Fix: For production deployments, create custom VPC with private subnets:
Cost: NAT Gateway ~$33/month. Security benefit: RDS isolated from internet.
When acceptable: Default VPC acceptable for small deployments if RDS security group restricts access to EC2 security group only.
What Happens: EBS snapshots accumulate forever. Snapshot costs grow from $2/month to $50+/month over 2 years.
Fix: Configure snapshot lifecycle policy:
EC2 Console → Elastic Block Store → Lifecycle Manager → Create lifecycle policy:
Automatically deletes old snapshots. Maintains 7-day recovery window without unbounded costs.
What Happens: CloudWatch Logs retain forever at $0.50 per GB-month. Odoo debug logs can generate 10GB+/month → $5+/month in perpetual storage.
Fix: Set log retention period:
CloudWatch Console → Log groups → /aws/rds/instance/odoo-production-db/postgresql:
Apply to all log groups:
What Happens: Odoo stores attachments on EBS by default. EBS costs $0.08/GB-month. S3 costs $0.023/GB-month (3.5x cheaper). For 100GB filestore, you waste $67/year.
Fix: Configure S3 filestore in odoo.conf
:
[options]
data_dir = /opt/odoo/.local/share/Odoo
# Add S3 configuration:
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
aws_region = us-east-1
aws_bucket_name = odoo-production-filestore
Requires boto3 (already installed in Step 5).
Migration: Use s3-sync
script to migrate existing filestore from EBS to S3.
Detailed S3 integration guide: Odoo AWS Production Security Hardening (Appendix 2).
Q: Can I use Odoo.sh instead of self-hosting on AWS?
A: Odoo.sh costs $20-50+ per user monthly ($400-1,000/month for 20 users). AWS Separated Architecture costs $110-140/month with Reserved Instances for same workload. Choose Odoo.sh if you want zero infrastructure management. Choose AWS if you want control and lower costs.
Q: Why use RDS instead of PostgreSQL on EC2?
A: RDS provides automated backups with point-in-time recovery, automated patching, and Multi-AZ failover. Self-hosted PostgreSQL requires manual backup scripts and no automated failover. RDS pays for itself in time savings (2+ hours/month backup management).
Q: What happens if EC2 instance fails?
A: In Separated Architecture: Launch replacement EC2 instance, point to same RDS database, restore from latest backup. Downtime: 15-30 minutes. In HA Multi-AZ: Load balancer automatically routes to healthy EC2 instance. Downtime: 0 minutes (rolling updates).
Q: How do I scale from 25 to 50 users?
A: Vertical scaling (resize instances): EC2 console → Stop instance → Change instance type to t3.xlarge → Start instance. RDS console → Modify → Change to db.t3.large → Apply immediately. Downtime: 5-10 minutes during resize.
Q: What’s included in $110-140/month Reserved Instance cost?
A: EC2 t3.large ($37), RDS db.t3.medium ($48), EBS storage ($4), RDS backups ($2), S3 filestore ($0.23), data transfer ($20-40). Excludes domain registration ($12/year) and optional services (CloudWatch detailed monitoring, VPC flow logs).
Q: Can I use this for Odoo Community Edition or Enterprise?
A: Both. Odoo Community is open-source (free). Odoo Enterprise requires license ($20-50/user/month from Odoo SA). AWS infrastructure cost is identical for both editions. Clone Enterprise repo if licensed, otherwise use Community Edition.
Q: Odoo shows “Internal Server Error” after deployment. How to troubleshoot?
A: Check Odoo logs: sudo journalctl -u odoo -n 50
. Common causes: (1) Database connection failed (verify RDS endpoint in odoo.conf), (2) Missing Python dependencies (re-run pip install -r requirements.txt
), (3) Permission errors (check /opt/odoo
owned by odoo user), (4) Port 8069 already in use (check sudo netstat -tlnp | grep 8069
).
Q: EC2 instance shows “Connection refused” when accessing port 8069. What’s wrong?
A: Verify security group allows inbound port 8069: EC2 Console → Security Groups → odoo-app-sg → Inbound rules. Check rule exists: Type=Custom TCP, Port=8069, Source=0.0.0.0/0. Verify Odoo running: sudo systemctl status odoo
. Check firewall: sudo ufw status
(should be inactive or allow 8069).
Q: RDS database connection times out from EC2. How to fix?
A: Check RDS security group: RDS Console → odoo-production-db → VPC security groups → Inbound rules. Must have: Type=PostgreSQL, Port=5432, Source=odoo-app-sg (EC2 security group ID). Verify RDS endpoint reachable: telnet odoo-production-db.abc123.rds.amazonaws.com 5432
(should connect, press Ctrl+] then quit).
Q: How do I migrate existing Odoo database from another server to AWS RDS?
A: Export existing database: pg_dump -U odoo -h old-server odoo_db > odoo_backup.sql
. Upload to EC2: scp odoo_backup.sql ubuntu@ec2-ip:/tmp/
. Import to RDS: psql -h odoo-production-db.abc123.rds.amazonaws.com -U odoo_admin -d odoo_production < /tmp/odoo_backup.sql
. Verify: Login to Odoo and check data integrity. Full migration guide with downtime minimization: Data Migration Module (Module 3 - $299).
You deployed production Odoo on AWS Separated Architecture. EC2 + RDS running. Automated backups configured. Costs: $110-140/month with Reserved Instances.
Critical production tasks remaining:
Current setup runs Odoo on HTTP (port 8069). Passwords travel unencrypted. Production requires HTTPS.
What you need:
Why critical: Search engines penalize HTTP sites. Compliance requirements (PCI-DSS, GDPR) mandate encryption in transit.
Detailed guide: Production Security Hardening covers Nginx configuration, Let’s Encrypt automation, SSL best practices, and automatic renewal setup.
Current setup has no monitoring. You discover outages when users complain.
What you need:
Why critical: CPU spike → timeout errors → revenue loss. Database connection exhaustion → complete outage. Monitoring catches issues before users notice.
Detailed guide: Production Security Hardening includes CloudWatch agent installation, Odoo-specific metric configuration, alarm threshold recommendations, and dashboard templates.
Current setup stores Odoo attachments on EBS ($0.08/GB-month). S3 costs $0.023/GB-month (3.5x cheaper). For 100GB attachments, you save $67/year.
What you need:
Why important: Filestore grows fast (invoice PDFs, product images, email attachments). EBS costs scale linearly. S3 provides cheaper storage + lifecycle policies (archive old attachments to Glacier).
Detailed guide: Production Security Hardening covers S3 bucket policies, IAM role configuration, filestore migration script, and Glacier lifecycle rules.
After 30 days of production usage, analyze metrics and adjust:
Architecture decisions to revisit:
Detailed guidance: AWS Architecture Design Guide provides EC2 sizing calculator, RDS parameter tuning based on workload analysis, VPC design patterns for multi-region deployment, and cost optimization strategies.
Production-Ready Automation:
Master Pack Module 2 (Technical Architecture - $299) eliminates manual configuration:
DIY Deployment Toolkit
Module 2 (Technical Architecture): CloudFormation templates for 1-click deployment, RDS parameter calculator, cost estimation spreadsheet, and security hardening checklist. Configure once, deploy in 90 minutes vs. 6 hours manual setup.
Your Odoo AWS deployment is live. Start configuring your business workflows.
tags: