Install Odoo
Run Odoo Community in Docker: your own cloud server with HTTPS or your own computer, a ready-made compose file, Swedish localization with chart of accounts and the right VAT settings, and a backup.
Last reviewed:
What you get out of this
When you are done, your business has its own ERP system running, with customers, products, quotes and invoices in one place. You own the installation yourselves, the license costs zero SEK, and the whole company can reach the system from a browser whether they are at home or at the office. You also learn Docker along the way, which is one of the most marketable technical skills you can have on a CV.
Be honest with yourselves before you start: this is the hardest guide in the whole guide collection. You will type commands in a black box and you will handle passwords that actually matter. Every command is explained, and nothing here requires you to understand Linux beforehand. But if nobody in the company thinks this sounds like fun, go with Bookkeeping and a spreadsheet instead. An ERP system that nobody can be bothered to maintain is worse than a spreadsheet that everyone uses.
What you need before you start
- An account with DigitalOcean if you choose path A, the cloud server.
- A payment card that can be linked to the DigitalOcean account, even when you pay with the credit. Talk to the person who handles the finances in the company first, it is the company's money and not your own.
- Docker Desktop if you choose path B and run on your own computer. Our guide Install Docker goes through the installation step by step.
- A password manager or at least a shared document where the company's passwords are saved. You will create four of them and you will need them again.
- A domain name where you can add a DNS record, for example
odoo.foretaget.se, if you choose path A. It is needed so the system can be reached over encrypted HTTPS. If you do not have a domain, start with Domain and email. - Two people in the company who do this together. The person who installs alone also ends up sitting alone the day something goes wrong.
Time and difficulty level
Allow an afternoon, three to four hours, for the whole guide including the basic settings. The installation itself takes twenty minutes when things go smoothly. The rest goes to the account with the cloud provider, to setting up the company and to typing the commands correctly. The difficulty level is high compared with everything else we have published, because you administer a real server and a real database. No prior knowledge is required, but patience is.
What a business system is, and what Community means
A business system, in English ERP which stands for Enterprise Resource Planning, is a program where the different parts of the company share the same information. The salesperson enters a customer. The same customer appears when someone writes a quote. If the quote becomes an order, the lines remain when the invoice is created, and when the invoice is paid it shows in the accounting. The point is not that each part is advanced, the point is that no one has to enter the same thing twice.
Odoo comes in two editions. Community Edition is open source: the code is free to read, use and change, the license costs nothing, and there is no user fee no matter how many people in the company log in. In return, you handle the operation yourselves. There is also a cloud variant where Odoo runs the server for you for a monthly fee, but here we run the open version that you own yourselves.
Run version 18.0. The Swedish localization we use, with chart of accounts and Swedish VAT codes, is available for 18.0, and that is the version this guide is written for. Then do not upgrade unnecessarily: version changes are by far the most common reason an Odoo installation breaks. Set the version once, and change only when you have a concrete reason and a recent backup.
Path A: Odoo on a cloud server
This is the path we recommend. A cloud server, called a droplet at DigitalOcean, is a computer in a data center that you reach through your web browser. No one needs to keep a computer running at home, and everyone in the company can reach the system from any device.
- Create the account at digitalocean.com. If the account gets a starting credit, it is added right away and is used before the card is charged.
- Click Create at the top right and choose Droplets.
- Choose the region Frankfurt or Amsterdam. Both are inside the EU, which is the only reasonable choice when you are going to store customer data, and they are closest to Sweden so the system feels faster.
- Choose the image Ubuntu and the version marked 24.04 (LTS). LTS means Long Term Support, that is, a version that is maintained for several years.
- Choose the size: the Basic tab, processor type Regular, and the plan with 4 GB of memory and 2 vCPU. It cost 24 USD per month when this was written. Server credits of this kind often have a limited period of validity, so exactly how far the credit goes you will see when you redeem it; count on it covering the startup and budget for the months after that yourself. Odoo wants 4 GB to run smoothly, and a smaller server starts to struggle as soon as you add products with images.
- Under Choose Authentication Method, choose Password and make up a long password for root, that is, the server's administrator account. Save it where the company keeps its passwords. SSH keys are safer but add a step you do not need right now.
- Give the server a name, for example
foretag-odoo, and click Create Droplet. After about a minute an IP address appears next to the name, four numbers with dots between them. That address is your server. - Click the droplet name and then Console. A black window opens in the browser and asks for a username and password. Type
rootand the password you chose. Now you are on the server, without having installed a single program on your own computer. - Install Docker with the official installation script:
The command fetches Docker's own installation script and runs it. It takes a couple of minutes and installs both Docker and the docker compose add-on, which is what we use in the next section.curl -fsSL https://get.docker.com | sh - Create a folder for the installation and move into it:
mkdir -p /opt/odoo/config /opt/odoo/addons cd /opt/odoomkdircreates folders, the-pflag makes it create the whole chain at once.cdmoves you there.
Path B: Odoo on your own computer to test
If you want to try it first, or you do not have a card and account right now, everything can run locally. Install Docker Desktop according to Install Docker, open the program and leave it running. Then create a folder called odoo where you usually save files, and two folders inside it: config and addons. The files in the next section are exactly the same, and you run the commands in Terminal on Mac or Linux Mint, or in PowerShell on Windows, instead of in the console window.
Two differences are worth knowing. The system can only be reached from that computer, so the rest of the company cannot access it. And if you turn off the computer, Odoo shuts down. That is perfectly fine for learning, but not for taking a real customer order.
If you run Linux Mint, the path is shorter, because there you do not need Docker Desktop. Install Docker Engine according to the section on Linux Mint in Install Docker, create the folders with mkdir -p ~/odoo/config ~/odoo/addons and then run exactly the same commands in Terminal. One thing differs: if you have not added your user to the docker group, every command must start with sudo, and then the files Odoo creates are owned by root instead of by you. Add the user to the group instead and log out and in once, so you avoid that.
Get the Swedish localization
Odoo has its own basic Swedish localization. We use the complete one at github.com/vertelab/odoo-l10n_se instead, with the BAS chart of accounts, Swedish VAT codes and add-ons for SIE export and bank files, among other things. It goes in the addons folder, which Odoo reads at startup.
git clone -b 18.0 --depth 1 https://github.com/vertelab/odoo-l10n_se.git addons/odoo-l10n_se
git clone fetches the code, -b 18.0 selects the branch for Odoo 18 and --depth 1 skips the history so that it goes fast. If you do not have git on a Windows computer, you can download branch 18.0 as a zip file from GitHub instead and unpack it to addons/odoo-l10n_se.
The base module works with what is already in Odoo. Some of the other modules in the same repo, for example the VAT report, need modules from OCA and Python packages; they are listed in the files requirements.repo and requirements.txt in the repo, and the repo's README links to the installation instructions. Wait with those until the base works.
The files you paste in
- Create the settings file. Type
nano config/odoo.confand press return. Nano is a text editor that runs in the terminal. Paste this in:
The[options] addons_path = /mnt/extra-addons/odoo-l10n_se data_dir = /var/lib/odoo admin_passwd = byt-ut-mig-mot-nagot-langt-och-eget list_db = True proxy_mode = Trueadmin_passwdline is the master password that protects the database manager. The default value in Odoo is the word admin, which every person on the internet knows. Replace the text with at least twenty characters that you make up yourselves.list_db = Trueturns on the database manager so that you can create the database; you turn it off again right afterwards.proxy_mode = Trueis needed for Odoo to work behind the web server that handles HTTPS. Save with Ctrl and O, return, and close with Ctrl and X. - Create the start file. Type
nano docker-compose.ymland paste in:
The file describes two programs that will run: Odoo itself, and PostgreSQL, which is the database where all information is saved.services: odoo: image: odoo:18.0 depends_on: - db ports: - "127.0.0.1:8069:8069" environment: - HOST=db - USER=odoo - PASSWORD=ett-annat-langt-losenord volumes: - odoo-data:/var/lib/odoo - ./config:/etc/odoo - ./addons:/mnt/extra-addons restart: unless-stopped db: image: postgres:16 environment: - POSTGRES_DB=postgres - POSTGRES_USER=odoo - POSTGRES_PASSWORD=ett-annat-langt-losenord volumes: - db-data:/var/lib/postgresql/data restart: unless-stopped volumes: odoo-data: db-data:portsmakes Odoo reachable on port 8069, but only from the computer itself:127.0.0.1means that nobody from outside can reach the port directly.volumesare storage spaces that remain even when the programs restart, and that is where your invoices actually live.restart: unless-stoppedmeans everything starts again on its own if the server restarts. - Replace both occurrences of
ett-annat-langt-losenordwith the same password of your own. The two lines must be identical, otherwise Odoo will not get into the database. Save and close with Ctrl and O, return, Ctrl and X. - Start everything:
The command downloads Odoo and PostgreSQL and starts them in the background, which is whatdocker compose up -d-dmeans. The first time it takes a few minutes because the files are fetched. - Open Odoo in the browser. On your own computer you type
http://localhost:8069. On the cloud server you can only reach Odoo from the server itself, so you create the database through an SSH tunnel from your own computer. Open Terminal on Mac or Linux Mint, or PowerShell on Windows, and type with the server's IP address:
Log in with the root password and leave the window open. As long as the tunnel is up you reach Odoo atssh -L 8069:127.0.0.1:8069 root@123.45.67.89http://localhost:8069in your own browser, and the traffic goes encrypted through SSH.
Never expose Odoo directly to the internet over unencrypted HTTP. Then passwords and customer data are sent in plain text, and the database manager becomes accessible to anyone who finds the address. That is why the port is bound to 127.0.0.1, the database manager is turned off once the database is created, and the rest of the company reaches the system via HTTPS as described in the section further down.
Create the database and choose apps
- Fill in the form that meets you. Master Password is the main password from
odoo.conf. Database Name can be the company name in lowercase and without spaces. The email and password become your login account, so use the company's shared email address. - Set Language to Svenska and Country to Sverige. The country choice makes Odoo install the Swedish localization and add the chart of accounts automatically. If you switch to the wrong country, you can change it under Accounting, Settings, Fiscal Localization, but only until you have posted the first journal entry, so set it correctly now instead of relying on that.
- Leave the Demo data box unchecked. With demo data the system is filled with made-up customers and products that you then have to clean out by hand.
- Click Create database and wait. Odoo builds the database, which takes a minute or two.
- Install Invoicing in the app overview that meets you after login. Search for the app and click Activate. That is the app that gives you customers, products, invoices and accounting records.
- Install CRM the same way. CRM stands for Customer Relationship Management and is where you track every customer contact from the first call to a closed deal. For a company it is mainly a shared to-do list of which customers someone has promised to get back to.
- Check the localization. Go to Apps, remove the filter in the search box and search for
l10n_se. The module l10n_se: Sweden - Accounting should show as installed. If it does not, turn on developer mode at the bottom under Settings, update the app list from the menu in Apps and install the module. - Stop there. Odoo has hundreds of apps and the temptation to install Inventory, Manufacturing and Project is strong. Every app you install adds menus and fields that the rest of the company has to understand. Add more only when someone concretely misses something.
Close the database manager
The database now exists, and the database manager is no longer needed. Open config/odoo.conf again, change the line to list_db = False and restart Odoo:
docker compose restart odoo
Now it is not possible to list, copy, delete or create databases from the browser. You take backups from the terminal instead, as described further down.
HTTPS with certbot (path A)
To let the rest of the company reach Odoo, you put a web server in front, nginx, and a free certificate from Let's Encrypt that the program certbot fetches and renews for you. Then all traffic goes encrypted over HTTPS.
- Add an A record for example
odoo.foretaget.sethat points to the server's IP address, where the domain's DNS is managed. Wait until the address responds; it takes from a few minutes to a few hours. - Install nginx and certbot on the server:
apt update apt install -y nginx certbot python3-certbot-nginx - Create the web server's configuration with
nano /etc/nginx/sites-available/odooand paste in, with your own address on theserver_nameline:server { listen 80; server_name odoo.foretaget.se; client_max_body_size 50m; location / { proxy_pass http://127.0.0.1:8069; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } location /websocket { proxy_pass http://127.0.0.1:8069; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } - Enable the configuration, check it and reload nginx:
ln -s /etc/nginx/sites-available/odoo /etc/nginx/sites-enabled/ rm /etc/nginx/sites-enabled/default nginx -t systemctl reload nginxnginx -tshould answer that the syntax is ok. If it does not, open the file again and look for a missing bracket or semicolon. - Fetch the certificate:
certbot asks for an email address for reminders and whether you accept the terms, fetches the certificate and rewrites the nginx configuration so that all traffic goes over HTTPS. The certificate is valid for 90 days and is renewed automatically;certbot --nginx -d odoo.foretaget.secertbot renew --dry-runshows that the renewal works. - Only let in what is needed in the firewall:
OpenSSH first, otherwise you lock yourselves out. Port 8069 does not need to be opened, since Odoo only listens onufw allow OpenSSH ufw allow "Nginx Full" ufw enable127.0.0.1.
Now everyone in the company reaches the system at https://odoo.foretaget.se, with the padlock in the address bar.
Set up the company for Swedish operations
- Go to Settings, then Users and Companies, then Companies. Click the company row and enter the company name and address, the organization number and the VAT registration number if the company has one. For a sole trader (enskild firma), the organization number is your personal identity number. Add the logo if you have one, it will appear on all invoices.
- Write the text that should appear at the bottom of the invoice. It is set under Settings, the Companies section, Configure document layout, the Footer field. If the company has F-tax, write "Approved for F-tax" there. The Swedish Tax Agency (Skatteverket) states that this information must appear on every invoice, and a customer who sees it does not need to deduct tax from what they pay. A limited company (aktiebolag) must also include the board's registered office on its invoices, and the footer is a good place for that.
For UF companies
Enter the UF company name and address and leave the organization number field empty. A UF company has no organization number and no other number that fits there, and Odoo does not require the field. Do not write anything about F-tax in the footer.
VAT
The country selection for Sweden made Odoo include the Swedish chart of accounts with ready-made VAT rates: 25, 12 and 6 percent on sales and purchases, split between goods and services, plus 0 percent for sales to other EU countries and exports. Open Invoicing, then Configuration, then Settings and look under the heading for taxes.
- VAT-registered company: the default tax on sales should be 25 percent and on purchases 25 percent input VAT. If something else is there, choose the right tax and click Save. Goods with 12 or 6 percent get their tax on the product.
- VAT-exempt company: clear the fields for default tax on sales and on purchases and click Save. Then no VAT is added to the invoices.
For UF companies
Clear the fields for standard tax on sales and on purchases and click Save. A UF company cannot be registered for VAT and does not add VAT to its prices. What that means for your customers is described in Payment gateways.
The VAT settings follow how we read the rules. Check with the Swedish Tax Agency (Skatteverket) what applies to your company before the first real invoice goes out.
- Set up your products under Invoicing, Customers, Products. Set the price you charge the customer. If the company is registered for VAT, the product must have the correct VAT rate; otherwise you leave the tax field empty.
- Invite the company. Settings, Users and Companies, Users, New. Enter the name and email address for each person. In Community Edition users cost nothing, so there is no reason to share one account.
- Write a test invoice to yourselves and send it as a PDF. That is the only way to see that company details, VAT, currency and layout are actually correct before a real customer gets one.
Back up the database
Everything you have done is stored in the database, and the database sits on a server that can break or be deleted by mistake. Take a backup every month, and always an extra one before anything big is changed.
The database manager is turned off, so the backup is taken in the terminal, in the folder where docker-compose.yml is located. Replace foretaget with the name of your database.
- Copy the database:
docker compose exec -T db pg_dump -U odoo -Fc foretaget > foretaget-$(date +%F).dump - Copy the attached files, for example the logo and saved PDF invoices, which sit outside the database:
docker compose exec -T odoo tar -czf - -C /var/lib/odoo/filestore foretaget > filer-$(date +%F).tar.gz - Move both files from the server to the company's shared storage, and one copy to the person who handles the finances. From your own computer you can use
scp root@123.45.67.89:/opt/odoo/foretaget-*.dump .and the same for the file archive. Accounting records must be kept for seven years under the Swedish Bookkeeping Act (bokföringslagen).
The command docker compose down -v deletes your volumes, meaning the entire database and all invoices, without asking. The -v flag is the whole difference. If you only want to stop Odoo, you write docker compose down without the flag, and you start again with docker compose up -d. If you lose the master password, it cannot be reset through the browser, you have to edit config/odoo.conf on the server again.
How you know it worked
The command docker compose ps lists both services with the status Up. The address https://odoo.foretaget.se shows Odoo's login box with the padlock in the address bar from a different computer than the one you installed from, and two people in the company can be logged in at the same time. The address http:// followed by the server's IP address and :8069 does not respond at all, and /web/database/manager says the database manager is turned off. The menus are in Swedish, the currency is SEK, and you can create a test invoice and download it as a PDF with your company name at the top. If the company is registered for VAT, the VAT is on its own line; otherwise there is no VAT line. If you restart the server from the DigitalOcean panel, Odoo is up again on its own within a couple of minutes. And you have a backup of the database and the files saved somewhere other than on the server.
If something goes wrong
- The page does not respond at all after
docker compose up -d: give it another two minutes, Odoo finishes building in the background. Rundocker compose logs odooto see what is happening. The lineHTTP service (werkzeug) runningmeans it is up. - An error message saying the database cannot be reached: the password under
PASSWORDfor odoo and underPOSTGRES_PASSWORDfor db are not identical. Correct the file, rundocker compose downand thendocker compose up -dagain. - certbot says the domain cannot be verified: the A record does not point to the server yet, or port 80 is closed. Check the address with
ping odoo.foretaget.se, thatufw statusshows Nginx Full, and try again. - The master password is not accepted when you create the database: the
configfolder was not where you thought it was. Check withls configthat the fileodoo.confis there, and that you are in the/opt/odoofolder when you run docker compose. - Odoo becomes slow or shuts down by itself: the server has too little memory. Upgrade the droplet to 8 GB in the DigitalOcean panel under Resize, you can do that afterwards without anything disappearing.
- The wrong country or language was selected when the database was created: if you have not posted anything yet, the country can be changed under Accounting, Settings, Fiscal Localization. If you have already posted, create a new database and start over: temporarily set
list_db = True, restart Odoo, create the database through the SSH tunnel and close the database manager again. It is cheaper to redo it now than later. - The credit has run out and the card starts being charged: take a backup first, then you can shut down the server under Destroy. The database remains in the backup and can be loaded into a local installation according to option B with
pg_restore.
What you do next
With the business system up and running, the next step is to get money flowing into it. Payment gateways shows how you take payment from customers and what applies around VAT. If you have not set up your bookkeeping yet, Bookkeeping is the next guide to take, because Odoo does not replace that routine, it feeds it. If you are going to sell online at the same time, there is WordPress and WooCommerce.