FreeBSD Port for Tryton

A happy new year to all,

This is to those who may be interested to run Tryton on FreeBSD:

I have created a bunch of FreeBSD ports for Tryton 7.0 and managed to start up a simple configuration from it which uses just werkzeug and an sqlite database.

The project has reached a level where I need to (re-)learn a good lot more about using and running Tryton but I consider it worth sharing as-is meanwhile.

May I suggest the interested to start at https://github.com/pc-consulting/ports/tree/main/finance/tryton-server . I have the ports linked from my ports tree so that I can run normal port builds from it (manually, or using poudriere testport).

Comments and support very welcome. Questions, I’ll try to respond to to the best of my knowledge.

For the forum, may I suggest to stick to English where possible but if anyone needs it:

  • Me puede escribir en Castellano.
  • Sie können mich auf deutsch anschreiben.

Kind regards,

Peter.

Hi @pcc , I’m a fellow FreeBSD and Tryton user. I run -RELEASE with quarterly packages and use pkg to install system services, but have found third-party SaaS applications are often updated on a schedule that doesn’t necessarily align well with the quarterly pkg update schedule (e.g. Solved - odoo pkg (odoo v16) requires "latest" pkg repo | The FreeBSD Forums).

I have been installing Tryton from PyPI. What would be the advantages of using pkg instead?

Fwiw, I published my notes on installing Tryton manually on FreeBSD:

Since I wrote these posts, I created an rc.d script to run trytond etc. using daemon, but still have to configure a production-grade server stack, probably using Gunicorn and Apache per recent posts from edbo with comments from others:

Cheers,
Dale

Thank you Dale @dales,

I did see your conversations with edbo and actually learnt quite some from them, so very much thanks for that, indeed.
I also noted that uwsgi is in maintenance mode so I may have to take a closer look at gunicorn for a more production setup proposal but I did not well get my head around that yet.

I do appreciate the attractiveness of PyPI which actually is the base of the port effort. However, I feel that any software which installs ignoring the package mechanism of the OS does so in an untidy way which may or may not be more tedious to maintain the system in a longer term. I want one place to see what I have, basically, not two, nor three, nor ten. In particular, if the software is more a tool, rather than the operational focus.

Cheers,

Peter.

Nice to see that others learned something. That’s why I put it here in the first place.

That’s the nice thing about using a Python Virtual Environment. It’s a kind of container and keeps the packages there which are not available system-wide. In that way you can run multiple versions besides each other. Maintenance is done by pip upgrading the packages in the environment without disrupting the rest of the system.

I’m also looking into FreeBSD as an alternative for Linux, but more as a container platform and I am looking into BastilleBSD how it works etc.

I don’t disagree with you, but I’ve found that pragmatically it’s simpler to manually install and maintain the SaaS apps I host to support my consulting work (Mantisbt, Moodle, Nextcloud, ProjeQtOr, SeedDMS, SuiteCRM, Timetracker, WackoWiki and WordPress), even if a pkg exists (although I use pkg to install and maintain their dependencies).

My roadmap for trytoncloud.ca is to use FreeBSD jails to host per-client instances of trytond and PostgreSQL to claim secure separation of client instances (although I feel more for perception than actual need). Jail creation and population will be scripted, potentially using Bastille, and a front-end client e-commerce store (using Tryton!) will initiate creation of a new jail and bill clients (or at least that’s the roadmap… :wink: ).

Cheers all,
Dale

I tried with cbsd but kind of stranded. BastilleBSD’s next. Happy to hear from your experience with it… The server sits behind me and waits :slight_smile:

I appreciate that but why would one need that if deployment was into a jail, anyways? Again, I’d just again move away from the OS into specifics …

But I may be a bit radical :slight_smile:

Cheers,

Peter.

Yes, I know. But, that’s not an excuse for untidiness. Just for a call for better vendor awareness. Writing all that knowing that also vendors economically cannot support any OS there is. Again, I’m probably a bit of a radical … :wink:

That sounds quite like my line of thought. Create a good base jail, install Tryton into it in a controlled manner, and be done with it, basically.

I got a bit tied up with cbsd on the way but already have bastille on the list (I used to use ezjail but that seems without much maintainer love now).

Cheers,

Peter.

To whom it may concern,

Dependency checks improved significantly with today’s changes. I’m finding and resolving the items I observe as poudriere and my local test install progress.
I’ll call it a day for now though (normal day job routine back tomorrow, and need some sleep, please bear with me).
I try to keep the README up to date with where I’m at.

Cheers,

Peter.

Wow. Updated to recent module versions (state Jan 1, 2024), et voila… no more failures as it seems, all modules active. I’m impressed.

“Thank you.”

Hm.

I have

uri = sqlite://
path = /var/db/trytond/db

in my [database] section of my tryton config file.
When I start trytond via rc.d (service trytond start), the server comes up and the tryton client connects to it.

I deactivate the listen in the [web] section, e. g.

# listen = localhost:8421

, fire up via uwsgi, and get a complaint from trytond that there was no database, i. e.

OSError: Database '/var/db/trytond/db/db.sqlite' doesn't exist!

And, of course, the tryton client falls over, failing to connect.

But the database is there, at the indicated location, and world-readable.

Odd.

Cheers,

Peter.

58638 7261055426560 [2024-01-20 19:33:26,353] WARNING py.warnings /usr/local/lib/python3.9/site-packages/trytond/protocols/jsonrpc.py:129: DeprecationWarning: The 'charset' attribute is deprecated and will not be used in Werkzeug 2.4. Interpreting bytes as text in body, form, and cookie data will always use UTF-8.
  getattr(self, 'charset', 'utf-8'),

58638 7261055426560 [2024-01-20 19:33:26,353] WARNING py.warnings /usr/local/lib/python3.9/site-packages/trytond/protocols/jsonrpc.py:130: DeprecationWarning: The 'encoding_errors' attribute is deprecated and will not be used in Werkzeug 3.0.
  getattr(self, 'encoding_errors', 'replace')),

58638 7261055426560 [2024-01-20 19:33:26,348] INFO trytond.wsgi <JSONRequest 127.0.0.1 'http://localhost:8080/' [POST] common.authentication.services>

==> /var/log/nginx/access.log <==
127.0.0.1 - - [20/Jan/2024:20:33:26 +0100] "POST / HTTP/1.1" 200 20 "-" "Python-xmlrpc/3.9"

==> /var/log/uwsgi.log <==
[pid: 58638|app: 0|req: 1/1] 127.0.0.1 () {38 vars in 471 bytes} [Sat Jan 20 19:33:26 2024] POST / => generated 20 bytes in 8 msecs (HTTP/1.1 200) 2 headers in 71 bytes (1 switches on core 0)
58638 7261720379648 [2024-01-20 19:33:30,834] INFO trytond.wsgi <JSONRequest 127.0.0.1 'http://localhost:8080/' [POST] common.server.version>

==> /var/log/nginx/access.log <==
127.0.0.1 - - [20/Jan/2024:20:33:30 +0100] "POST / HTTP/1.1" 200 25 "-" "Python-xmlrpc/3.9"

==> /var/log/uwsgi.log <==
[pid: 58638|app: 0|req: 2/2] 127.0.0.1 () {38 vars in 471 bytes} [Sat Jan 20 19:33:30 2024] POST / => generated 25 bytes in 1 msecs (HTTP/1.1 200) 2 headers in 71 bytes (1 switches on core 1)
58638 7261720379648 [2024-01-20 19:33:31,687] INFO trytond.wsgi <JSONRequest 127.0.0.1 'http://localhost:8080/db/' [POST] common.db.login>
58638 7261720379648 [2024-01-20 19:33:31,689] DEBUG trytond.wsgi Exception when processing <JSONRequest 127.0.0.1 'http://localhost:8080/db/' [POST] common.db.login>
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/trytond/transaction.py", line 179, in start
    database = backend.Database(database_name).connect()
  File "/usr/local/lib/python3.9/site-packages/trytond/backend/sqlite/database.py", line 365, in connect
    self._make_uri(), uri=True,
  File "/usr/local/lib/python3.9/site-packages/trytond/backend/sqlite/database.py", line 439, in _make_uri
    raise IOError("Database '%s' doesn't exist!" % db_path)
OSError: Database '/var/db/trytond/db/db.sqlite' doesn't exist!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/trytond/transaction.py", line 239, in stop
    self.rollback()
  File "/usr/local/lib/python3.9/site-packages/trytond/transaction.py", line 356, in rollback
    for datamanager in self._datamanagers:
AttributeError: 'Transaction' object has no attribute '_datamanagers'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/trytond/wsgi.py", line 109, in dispatch_request
    return endpoint(request, **request.view_args)
  File "/usr/local/lib/python3.9/site-packages/trytond/protocols/dispatcher.py", line 43, in rpc
    return methods.get(request.rpc_method, _dispatch)(
  File "/usr/local/lib/python3.9/site-packages/trytond/protocols/dispatcher.py", line 53, in login
    session = security.login(
  File "/usr/local/lib/python3.9/site-packages/trytond/security.py", line 29, in login
    with Transaction().start(dbname, 0, context=context) as transaction:
  File "/usr/local/lib/python3.9/site-packages/trytond/transaction.py", line 218, in start
    self.stop(False)
  File "/usr/local/lib/python3.9/site-packages/trytond/transaction.py", line 241, in stop
    self.database.put_connection(
AttributeError: 'NoneType' object has no attribute 'put_connection'

==> /var/log/nginx/access.log <==
127.0.0.1 - - [20/Jan/2024:20:33:31 +0100] "POST /db/ HTTP/1.1" 200 2065 "-" "Python-xmlrpc/3.9"

==> /var/log/uwsgi.log <==
[pid: 58638|app: 0|req: 3/3] 127.0.0.1 () {38 vars in 477 bytes} [Sat Jan 20 19:33:31 2024] POST /db/ => generated 2065 bytes in 7 msecs (HTTP/1.1 200) 2 headers in 73 bytes (1 switches on core 1)
sudo ls -la /var/db/trytond/db/db.sqlite
-rw-rw-rw-  1 tryton uwsgi 27295744 Jan  9 23:08 /var/db/trytond/db/db.sqlite

Ok, I actually resolved my issues with the uWSGI installation and leave the above here for people to find – a classic Un*x shot in the foot: Access rights.

It’s not only the database file which must be read/writable by the calling user. As it seems, the directories ‘above’ it also must be, as if the call to the file was not direct but rather descending the directory tree, at including the directory containing the actual database file. Kind of makes sense if you move files, wish to touch a lock file or the like.

In case of the call via uwsgi, this meant that the rights I set during install are too restrictive and need be resolved by a chgrp -R uwsgi /var/db/trytond/db, followed by a chmod g+rwx /var/db/trytond/db and a chmod go+rw /var/db/trytond/db/db.sqlite. I’ll see wether I can dynamically adjust that in some way during install, in accordance with the options picked.

Cheers,

Peter.

To whom it may concern.

I’ve been able to run up a trytond server from the tryton-server ‘meta’ port with and without a postgresql server, and with and without uWSGI, and activated all trytond package both on an sqlite file-based database as well as on a postgres database. Modules should be current LTS 7.0.x as per today.

Subsequently, I consider the set of ports generally ready for the wild. The tryton-server port installs corresponding config files sufficient for starting up a server and do the first clickabouts if instructions in the overly long pkg-message are followed.

As usual, and in good porting tradition, the good admin will have to adjust to her or his likings and local requirement but I feel I’ve been left in the middle of nowhere too many times that I consider the effort worth the while it took me (along with learning sme myself, of course).

In any case, I hope that someone finds this useful, and maybe some other even be willing to contribute to maintaining the ports bunch. I’ll continue to keep a bit of an eye to it, set up some jail and be done with it for the time being as it was intended as a ‘quick port’ of what is a tool to me at this time (which does not lessen its importance) but which has consumed much more time than I anticipated. I now intend to move towards actually using Tryton… :slight_smile:

When I see module updates on pypi, I intend to add them (unless someone else is faster than me). If I can figure out how to add the web interface to the ports, I eventually may do that, because the tryton client seems to have some funny GUI issues on my box; gunicorn possibly also but it currently has a lesser prio, to be honest, since uWSGI seems to work.

Again, thank you very much indeed to those who responded and gave guidance, here, and via documentation elsewhere, and a big hand to all who developed and develop Tryton.

Likely read you soon, and please be in touch if you think I can be of help.

Cheers,

Peter.

PS. If anyone had investigated how much the new (?) German ‘eRechnung’ requirements (cf. [1], [2] below) would deviate from the ‘French’ UN/CEFACT which we already seem to have in the modules, I’d love to learn eventually (true beginner at this stage, though, sorry).

[1] Pflicht zur E-Rechnung im XML-Format: Das ist der Status quo | heise online
[2] Gemeinsamer Rechnungsstandard: ZUGfeRD und Factur-X | heise online