Deploying Odoo manually is a recurring task that many developers need to perform on a daily basis: connect to the server via SSH, pull the latest code, restart the service, update the modules, and wait for the changes to take effect. It is not a quick process, and when working with several custom modules, it may easily become error-prone. GitHub Actions addresses both of these issues by automating the process of deployment and serving as a CI (Continuous Integration) for your Odoo project. It is a perfect solution for deploying private modules that require server access because every time you commit your changes to GitHub, the actions may trigger and deploy your changes to the server automatically. In this article, you will learn how to set up such a CI/CD (Continuous Integration / Continuous Deployment) workflow for your Odoo project by using GitHub Actions. The process will involve the following steps:
- Preparing your project's repository to be used with GitHub Actions
- Storing your server credentials as secrets within GitHub
- Deploying your custom modules to the server over SSH
- Automatically restarting your Odoo server with every commit
By the end of this article, you will be able to make your Odoo deployments fast and reliable by only pushing your commits to GitHub. Let's dive in.
Prerequisites
Before anything else, let's make sure we have these things prepared:
- An Odoo project hosted on GitHub (typically), a repository that contains our custom addons (a custom_addons/ folder).
- A deployment server - a VPS or cloud instance (Ubuntu is used in the examples) where Odoo is already installed and running, either natively or in Docker. SSH access to the server.
- Basic knowledge of Git and YAML
Step 1: Structure Your Odoo Repository
A clean repository structure makes automation much easier. The simplest layout for this deployment style is to make the repository itself your addons folder:
custom_addons/ <-- this is your Git repository
+-- sales_extension/
¦ +-- __manifest__.py
¦ +-- ...
+-- inventory_reports/
¦ +-- __manifest__.py
¦ +-- ...
+-- requirements.txt
+-- .github/
¦ +-- workflows/
¦ +-- deploy.yml
+-- README.md
Key points:
- Each custom module is located in the root of the repository so that the repository can be cloned directly to /opt/odoo/custom_addons on the server, which is the same path that your addons_path in odoo.conf points to.
- List any extra Python dependencies in requirements.txt.
- Workflows live in .github/workflows/
- GitHub automatically detects any .yml file placed there.
Step 2: Add Secrets to Your GitHub Repository
GitHub Secrets keeps sensitive values encrypted and out of your codebase. In your repository, go to:
Settings > Secrets and variables > Actions > New repository secret
Add the following:
- SSH_PRIVATE_KEY — contents of the gh_actions_key private file
- SSH_HOST — your server IP or hostname
- SSH_USER — deployer
You also need to clone the repository once on the server (in /opt/odoo/custom_addons), setting the origin’s URL so that it can pull changes without asking for a username and password (use a freshly generated GitHub personal access token for that).:
git remote set-url origin https://<your_token>@github.com/<username>/<repository>.git
Step 3: Add the Deployment Job
Create .github/workflows/deploy.yml. This job runs on every push to the main branch:
name: Deploy Odoo
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
set -e
cd /opt/odoo/custom_addons
git pull origin main
sudo systemctl restart odoo
This is an example of using a GitHub workflow: with a single YAML file, a previously tedious and error-prone process turns into an automated pipeline where each push is deployed to the server, and the service is reloaded.
To read more about A Complete Comparison Guide to Odoo Deployment Options, refer to our blog, A Complete Comparison Guide to Odoo Deployment Options.