System Preparation and Dependency Installation
Rocky Linux 9 Base System Configuration
Begin with a comprehensive system update. This process ensures all existing packages receive the latest security patches and bug fixes. Run dnf update -y to refresh your package cache and upgrade installed software. Reboot the server if the kernel receives an update. A current system prevents conflicts with newer dependencies that Odoo 18 requires.
Configure SELinux for enforcement mode. Odoo operates within strict security contexts. Install the necessary management tools with dnf install -y policycoreutils-python-utils. Set SELinux to enforcing using setenforce 1 and modify /etc/selinux/config for persistence across reboots. These measures protect your system from unauthorized access attempts.
Open the required firewall ports for initial access. Odoo needs port 80 for HTTP and port 443 for HTTPS traffic. Execute firewall-cmd --permanent --add-port=80/tcp and firewall-cmd --permanent --add-port=443/tcp. Reload the firewall configuration with firewall-cmd --reload. These rules enable web browser access to your Odoo instance after installation completes.
Create a dedicated system user for Odoo processes. Isolating the application enhances security and simplifies permission management. Run useradd -m -d /opt/odoo -U -r -s /bin/bash odoo. This command creates a user with a home directory at /opt/odoo and assigns the correct system account attributes. The Odoo service will run under this non-privileged account.
Core Dependency Package Installation
Install the Python development tools and compilation packages. Odoo 18 requires Python 3.9 or newer, along with specific build dependencies. Execute dnf install -y python3 python3-devel git gcc redhat-rpm-config openssl-devel openldap-devel. These packages provide the compilation toolchain for Python wheels and critical development headers.
Add the Node.js repository for additional JavaScript dependencies. Odoo uses Node.js for asset processing and management. Run curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - to configure the NodeSource repository. Install Node.js with dnf install -y nodejs. This step ensures you have the correct runtime for Odoo’s web client components.
Install wkhtmltopdf for report generation. Odoo converts HTML content to PDF documents for invoices and other business documents. Use dnf install -y https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox-0.12.6.1-2.almalinux9.x86_64.rpm. This specific version maintains compatibility with Odoo’s reporting engine and includes necessary patches.
Install additional system libraries for database connectivity and image processing. Run dnf install -y postgresql-devel libjpeg-turbo-devel libpng-devel libxml2-devel libxslt-devel freetype-devel. These libraries enable Odoo to connect to PostgreSQL, process images for product catalogs, and handle XML data transformations for various business documents.
PostgreSQL Database Configuration
PostgreSQL Installation and Initial Setup
Install the PostgreSQL server and client packages. Odoo requires a robust database backend for all its operations. Execute dnf install -y postgresql-server postgresql-contrib. This command installs the database engine along with additional modules that enhance functionality. Initialize the database cluster with postgresql-setup --initdb.
Start and enable the PostgreSQL service. Run systemctl enable postgresql and systemctl start postgresql. These commands ensure the database service starts automatically with the system and begins running immediately. Verify the service status with systemctl status postgresql. A green active status confirms the database engine operates correctly.
Configure PostgreSQL authentication for the Odoo user. Switch to the postgres system account with su - postgres. Create a dedicated database user for Odoo using createuser --createdb --username postgres --no-createrole --no-superuser --pwprompt odoo. Enter a strong password when prompted. This user will own all Odoo database instances.
Modify PostgreSQL’s host-based authentication rules. Edit the /var/lib/pgsql/data/pg_hba.conf file. Locate the lines for local connections and change the authentication method from ident to md5. This adjustment allows password-based authentication for local connections. Restart PostgreSQL with systemctl restart postgresql to apply the changes.
Database Security and Performance Tuning
Adjust PostgreSQL configuration for better performance. Edit /var/lib/pgsql/data/postgresql.conf. Increase the max_connections parameter to 80, as Odoo can require numerous database connections under load. Set shared_buffers to 25% of your system’s available RAM. These modifications help the database handle concurrent Odoo users without performance degradation.
Create the first Odoo database instance. As the postgres user, run createdb --owner=odoo odoo-prod. This command creates a production database owned by the Odoo user. Test the connection with psql --username=odoo --password odoo-prod. Successful login confirms the database setup completes correctly before proceeding to Odoo installation.
Configure connection limits and resource constraints. Execute ALTER USER odoo WITH CONNECTION LIMIT 75; within the PostgreSQL prompt. This restriction prevents the database user from exhausting all available connections. Consider setting statement timeouts for long-running queries with ALTER DATABASE odoo-prod SET statement_timeout = '30s';. These measures protect database stability.
Implement regular backup procedures. Configure pg_dump in a cron job for daily database backups. Create a script at /usr/local/bin/odoo-backup.sh that executes pg_dump --username=odoo odoo-prod > /backup/odoo-$(date +%Y%m%d).sql. Secure the backup directory with proper permissions. Regular backups provide recovery options in case of data corruption or system failure.
Odoo 18 Application Installation
Python Environment and Source Code Deployment
Create an isolated Python virtual environment. This approach prevents conflicts with system Python packages and ensures dependency consistency. Run python3 -m venv /opt/odoo/venv as the odoo user. Activate the environment with source /opt/odoo/venv/bin/activate. Your command prompt will change, indicating the virtual environment activates successfully.
Install Odoo 18 dependencies using pip. The requirements.txt file specifies exact versions for compatibility. Execute /opt/odoo/venv/bin/pip3 install wheel. Then install the core dependencies with /opt/odoo/venv/bin/pip3 install -r /opt/odoo/odoo/requirements.txt. This process compiles and installs all necessary Python packages for Odoo operation.
Download the Odoo 18 source code from the official repository. Change to the odoo user with su - odoo. Clone the source code using git clone https://github.com/odoo/odoo.git /opt/odoo/odoo --branch 18.0 --depth=1. The depth parameter limits the download to the latest commit, reducing bandwidth usage and storage requirements.
Verify the installation by testing the Odoo command-line interface. Run /opt/odoo/venv/bin/python3 /opt/odoo/odoo/odoo-bin --help while the virtual environment activates. The command should display help information about available options and parameters. This confirmation validates the core installation completes without errors.
Application Configuration and Service Setup
Create the Odoo configuration file. Switch to the odoo user and navigate to the home directory. Generate a new configuration template using /opt/odoo/venv/bin/python3 /opt/odoo/odoo/odoo-bin --save --stop-after-init. This command creates /opt/odoo/.odoorc with default settings. We will modify this file with our specific production values.
Edit the Odoo configuration for production use. Open /opt/odoo/.odoorc in a text editor. Set critical parameters including the database host, port, and user credentials. Configure the addons path to include both core modules and custom development directories. Specify the admin password for database creation and management functions.
Create a systemd service file for Odoo. As root, create /etc/systemd/system/odoo.service. This file defines the service execution parameters, including the user context, environment variables, and executable path. Set proper resource limits and restart behavior to ensure high availability. The service file integrates Odoo with Rocky Linux’s init system.
Configure logging and process management. The systemd service directs standard output to journald for centralized logging. Specify log rotation policies in the Odoo configuration file to prevent disk space exhaustion. Set the log level to appropriate values for production (typically info or warn). These measures provide visibility into system operation and simplify troubleshooting.
Nginx Reverse Proxy and SSL Configuration
Nginx Installation and Basic Setup
Install the Nginx web server package. Execute dnf install -y nginx as the root user. This command installs the latest stable version of Nginx from the Rocky Linux repositories. Start and enable the service with systemctl enable nginx and systemctl start nginx. Verify the installation by accessing your server’s IP address in a web browser.
Configure Nginx as a reverse proxy for Odoo. Create a new configuration file at /etc/nginx/conf.d/odoo.conf. This file defines how Nginx handles incoming HTTP requests and forwards them to the Odoo backend service. The reverse proxy architecture improves security, enables SSL termination, and provides buffering for better performance.
Set up upstream connection handling. Define an upstream block pointing to your Odoo instance, typically running on port 8069. Configure connection keep-alive settings to maintain persistent connections between Nginx and Odoo. This approach reduces the overhead of establishing new connections for each request, improving response times for users.
Implement access control and rate limiting. Create rules that block suspicious user agents and implement connection rate limits to prevent brute force attacks. Configure client body size limits to protect against large request attacks. These security measures harden your Odoo installation against common web application threats.
SSL Certificate Deployment with Let’s Encrypt
Install the Certbot package for SSL certificate management. Run dnf install -y certbot python3-certbot-nginx. Certbot automates the process of obtaining and installing TLS certificates from Let’s Encrypt. This service provides free, trusted certificates that enable HTTPS encryption for your Odoo instance.
Obtain and install the SSL certificate. Execute certbot --nginx -d yourdomain.com where yourdomain.com represents your actual domain name. Certbot will modify your Nginx configuration to enable HTTPS and redirect HTTP traffic to the secure protocol. The certificate automatically renews before expiration through a systemd timer.
Configure strong SSL security settings. Implement modern cipher suites that provide forward secrecy. Set strict transport security headers to enforce HTTPS connections. Configure certificate revocation checking through OCSP stapling. These measures ensure your SSL implementation meets current security best practices.
Test the SSL configuration using external validation tools. Visit your domain with HTTPS and verify the browser displays a secure connection. Use SSL Labs’ SSL Test to evaluate your configuration and identify potential weaknesses. Address any issues the test reveals to maintain a robust security posture.
Security Hardening and Access Control
Application-Level Security Measures
Configure the Odoo master password for database operations. This password controls access to database management functions through the web interface. Set a strong, unique value in the Odoo configuration file. Never use default or easily guessable passwords, as this provides full control over all databases on the instance.
Implement IP address restrictions for administrative access. Modify the Odoo configuration to only allow connections from specific trusted networks. Use Nginx’s allow/deny directives to restrict access to the /web/database/manager path. These measures prevent unauthorized users from attempting to create or drop databases.
Secure file permissions for the Odoo installation. Ensure only the odoo user has write access to the configuration file containing database credentials. Set the ownership of the entire /opt/odoo directory to the odoo user and group. Restrict read access to sensitive configuration sections that contain passwords.
Disable potentially dangerous Odoo features in production. Consider disabling the database manager interface entirely if you manage databases through other methods. Review installed modules and remove any unnecessary components that increase attack surface. These precautions reduce the risk of accidental misconfiguration or malicious exploitation.
System-Level Security Enhancements
Configure regular security updates for all system packages. Enable the dnf-automatic package or set up a weekly security update process. Rocky Linux provides security patches that address vulnerabilities in the operating system and installed software. Timely application of these updates protects against known exploits.
Implement fail2ban for automated intrusion prevention. Install fail2ban with dnf install -y fail2ban. Create a custom jail configuration that monitors Odoo logs for repeated authentication failures. Configure bans that block IP addresses exhibiting suspicious behavior. This automated response mitigates brute force attacks.
Set up comprehensive firewall rules. Beyond the basic web ports, restrict SSH access to specific management networks. Close all unnecessary ports to reduce the system’s attack surface. Use firewall-cmd to make these rules permanent so they persist across reboots and service restarts.
Configure filesystem integrity monitoring. Install AIDE (Advanced Intrusion Detection Environment) to create a database of file hashes. Schedule regular checks that compare current file states against the known good baseline. This monitoring detects unauthorized changes to critical system and application files.
Performance Optimization and Monitoring
Database and Application Tuning
Optimize PostgreSQL configuration for Odoo workloads. Increase the work_mem setting for better sorting and hash operation performance. Adjust the maintenance_work_mem parameter for faster index creation and vacuum operations. Set effective_cache_size to reflect your available system memory. These changes improve database responsiveness under load.
Configure Odoo’s built-in caching mechanisms. Enable the in-memory cache for frequently accessed data. Set appropriate timeouts for different data types to balance freshness and performance. Consider implementing a Redis-based cache for distributed deployment scenarios. Caching reduces database load and improves page response times.
Implement worker process configuration for multi-core systems. Calculate the optimal number of workers based on available CPU cores and RAM. Set the limit_memory_soft and limit_memory_hard parameters to prevent worker process memory exhaustion. Configure the limit_time_cpu and limit_time_real settings to terminate long-running requests.
Optimize static asset delivery through Nginx. Configure long expiration headers for JavaScript, CSS, and image files. Enable gzip compression for text-based content to reduce bandwidth usage. Set up a separate static file location block that serves assets directly without hitting the Odoo backend. These measures decrease page load times for users.
System Monitoring and Maintenance
Implement comprehensive logging and log analysis. Configure Odoo to log at the appropriate level for your environment. Set up log rotation to prevent disk space exhaustion. Consider implementing a centralized logging solution for easier analysis and long-term retention. Monitoring logs helps identify performance issues and security events.
Set up system resource monitoring. Install and configure tools like htop, iotop, and nethogs for real-time system observation. Implement Prometheus and Grafana for long-term metric collection and visualization. Monitor key indicators including CPU utilization, memory usage, disk I/O, and database connection counts.
Create regular maintenance procedures for database housekeeping. Schedule periodic vacuum and analyze operations to maintain PostgreSQL performance. Monitor database growth and plan for storage expansion before reaching capacity limits. Archive old records according to your business retention policies to control database size.
Develop a backup and recovery testing regimen. Verify that your database backups complete successfully and contain recoverable data. Test the restoration process on a regular schedule to ensure business continuity. Document recovery procedures so multiple team members can execute them during an emergency.
Troubleshooting and Common Issues
Startup and Service Failure Diagnosis
Investigate Odoo service startup problems. Use systemctl status odoo to check the service state and view recent log entries. Examine the full journalctl output with journalctl -u odoo --no-pager. Common issues include Python import errors, database connection failures, and permission problems with required directories.
Diagnose database connection errors. Verify the PostgreSQL service runs and accepts connections. Confirm the odoo user exists in PostgreSQL and has the necessary privileges. Check the password in the Odoo configuration file matches the database user password. Test the connection manually using psql with the same credentials.
Resolve module import and dependency conflicts. Examine the virtual environment activation and Python path configuration. Verify all requirements install correctly without version conflicts. Check for missing system libraries that Python packages might need. Isolate the problem by testing imports in a Python shell with the same environment.
Address permission and file access issues. Ensure the odoo user owns all application files and has read access. Verify the user has write permission to the log directory and filestore location. Check SELinux contexts if filesystem access fails despite correct permissions. Use restorecon to reset security contexts if needed.
Runtime Performance and Operational Problems
Debug memory exhaustion and worker process crashes. Monitor system memory usage during peak operation. Adjust worker limits or add swap space if processes terminate unexpectedly. Investigate possible memory leaks in custom modules by testing with standard Odoo modules only. Consider horizontal scaling if resource demands exceed single-server capacity.
Resolve database performance degradation. Identify long-running queries using PostgreSQL’s pg_stat_activity view. Check for missing indexes on frequently queried columns. Monitor database locks that might block operations. Consider periodic reindexing of heavily updated tables to maintain query performance.
Troubleshoot email sending and receiving configuration. Verify SMTP server settings and authentication credentials. Check firewall rules that might block outbound SMTP connections. Configure proper DNS records for your domain to prevent email delivery issues. Test both sending and receiving functionality separately to isolate problems.
Address backup and recovery failures. Verify adequate disk space exists in the backup destination. Check that the backup user has the necessary database permissions. Test backup file integrity by performing trial restorations to a development environment. Automate verification checks to catch backup problems early.