Building a Tryton Server on FreeBSD

This article is part of a series on the Tryton framework, to complement the Maestro project on GitHub. This article describes installing the Tryton server (trytond) on FreeBSD.

Caution – this is a Work in Progress  updating original 2014-05-24 post for Tryton 5.2 on FreeBSD 12.0 using Virtualenv.

Install FreeBSD

Boot vm from boot CD/DVD and follow the standard install procedure, including creating an admin user and including it in the wheel group.

I always configure remote access using ssh keys only for for security, Copy the public ssh key for the admin user to ~/.ssh, edit /etc/ssh/sshd_config to add “AllowUsers adminusername” and restart sshd.

Check for and install available FreeBSD OS updates, and install the pkg packaging system port..

# freebsd-update fetch
# freebsd-update install
# pkg update   

You can check the installed packages for reported vulnerabilities (-F is required for initial use only to download a new vulnerability database).

# pkg audit -F

Install PostgreSQL

The files belonging to the Postgresql database system will be owned by user “postgres”, who must also own the server process.

# pkg install postgresql93-server-9.3.4
# echo "postgresql_enable=YES" >> /etc/rc.conf
# /usr/local/etc/rc.d/postgresql initdb
# /usr/local/etc/rc.d/postgresql start

The default configuration file (/var/db/postgres/data96/postgresql.conf is acceptable and does not need editing. Only localhost will have access to PostgreSQL, which is adequate as Tryton will be served from the same server. 

Add a PostgreSQL “tryton” super-user.

dale@casper:~ % sudo su postgres
$ createuser -sdrP tryton
Enter password for new role:
Enter it again:
$ exit
dale@casper:~ %

The “tryton” super-user password will ned to be entered in trytond.conf (the trytond daemon configuration file) for Tryton to access its database.

Restart PostgreSQL.

dale@casper:~ % sudo /usr/local/etc/rc.d/postgresql restart
LOG:  ending log output to stderr
HINT:  Future log output will go to log destination "syslog".
dale@casper:~ %

Confirm localhost can connect to the PostgreSQL server (“-W” causes psql to prompt for the user password).

dale@casper:~ % psql --username=tryton -W --list
Password for user tryton:
List of databases
Name       | Owner    | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres   | postgres | UTF8     | C       | C     |
template0  | postgres | UTF8     | C       | C     | =c/postgres +
           |          |          |         |       | postgres=CTc/postgres
template1  | postgres | UTF8     | C       | C     | =c/postgres +
           |          |          |         |       | postgres=CTc/postgres
(3 rows)
dale@casper:~ %

Install Tryton Dependencies

Install Python and other dependencies using pkg.

% sudo pkg install python
% sudo pkg install py36-pip
% sudo pkg install bash
% sudo pkg install py36-virtualenv
% sudo pkg install py36-virtualenvwrapper
% sudo pkg install libxml2
% sudo pkg install libxslt
% sudo pkg install graphviz

Install the Python pydot package, the Python interface to Graphviz, and psycopg2, the Python interface to PostgreSQL.

% sudo pip install pydot
% sudo pip install psycopg2

Create a trytond system user

The “tryton” system user will execute the trytond daemen. The tryton user’s home directory (/home/tryton) will be configured as the root of the Tryton file system for storing document attachments. 

dale@casper:~ % sudo adduser
Username: tryton
Full name: trytond system user
Uid (Leave empty for default):
Login group [tryton]:
Login group is tryton. Invite tryton into other groups? []:
Login class [default]:
Shell (sh csh tcsh bash rbash nologin) [sh]:
Home directory [/home/tryton]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]: no
Lock out the account after creation? [no]: no
Username   : tryton
Password   : <disabled>
Full Name  : tryton system user
Uid        : 1002
Class      :
Groups     : tryton
Home       : /home/tryton
Home Mode  :
Shell      : /bin/sh
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (tryton) to the user database.
Add another user? (yes/no): no
Goodbye!
dale@casper:~ % 

Create a Tryton source directory

Create a sub-child directory in  the tryton user directory for Tryton source code.

dale@casper:~ % sudo mkdir /home/tryton/tryton
dale@casper:~ %

Configure a virtual environment

Create a “default” virtual environment to use for execution.

dale@casper:~ % su - Password:
root@casper:~ # bash
[root@casper /root]# cd /home/tryton/tryton 
[root@casper /home/tryton/tryton]# virtualenv default
Using base prefix '/usr/local'
New python executable in /usr/home/tryton/default/bin/python3.6
Also creating executable in /usr/home/tryton/default/bin/python
Installing setuptools, pip, wheel...done.
[root@casper /home/tryton/tryton]# source default/bin/activate
(default) [root@casper /home/tryton/tryton]# 

Install trytond and modules

Install trytond – the Trytond server daemon.

(default) [root@casper /home/tryton/tryton]# pip install trytond

trytond modules provide areas of functionality to trytond. You can generate a list of all available modules using pip.

(default) [root@casper /home/tryton/tryton]# pip search tryton

Install the trytond_sale module to provide a basic set of functionality.

(default) [root@casper /home/tryton/tryton]# pip install trytond_company

Modules often have dependencies. To see all the trytond modules which were installed, you can use pip to list installed modules and grep to filter for trydond.

(default) [root@casper /home/tryton/tryton]# pip list | grep trytond
trytond 5.2.6
trytond-account 5.2.3
trytond-account-invoice 5.2.2
trytond-account-invoice-stock 5.2.0
trytond-account-product 5.2.0
trytond-company 5.2.0
trytond-country 5.2.0
trytond-currency 5.2.1
trytond-party 5.2.0
trytond-product 5.2.1
trytond-sale 5.2.0
trytond-stock 5.2.1
(default) [root@casper /home/tryton/tryton]#

Create log directory for trytond

dale@casper:~ % sudo mkdir /var/log/trytond
dale@casper:~ % sudo chown -R tryton:tryton /var/log/trytond

Create json-rpc data directory for trytond

dale@casper:~ % sudo mkdir /var/run/trytond
dale@casper:~ % sudo chown -R tryton:tryton /var/log/trytond

Create trytond.conf

The Tryton configuration file trytond.conf is read by the Tryton server daemon trytond when it starts, and includes such site-specific data as:

  • computer addresses to respond to (jsonrpc).
  • username and password for the PostgreSQL “tryton” super-user.
  • Tryton “administrator” password (required to create, drop, backup or restore a database).
  • specify FreeBSD-specific directory paths

Unfortunately, the pip install for trytond currently does not copy the default trytond.conf file in the package to a suitable location (or rather, to any location). Download the trytond server distribution from PyPi, extract and copy trytond/etc/trytond.conf to /usr/local/etc/trytond.conf.

Edit parameters in /usr/local/etc/trytond.conf using the following as reference:

jsonrpc = *:8000,0.0.0.0:8000
jsondata_path = /var/run/trytond

db_type = postgresql
db_host = localhost
db_port = 5432
db_user = tryton
db_password = appleton

admin_passwd = appleton

pidfile = /var/run/trytond/trytond.pid
logfile = /var/log/trytond/trytond.log

data_path = /home/tryton

Create tryton rc script

An rc.d script will be created to manage starting and stopping trytond, and to start trytond after booting. I’m using a basic rc.d startup script created by Christoph Larsen for the GNU Health project, and added support for status reporting. Copy the following code to /usr/local/etc/rc.d/trytond

#!/bin/sh

#
# PROVIDE: trytond
# REQUIRE: DAEMON
# BEFORE:  LOGIN
#
# Originally created by: Christoph H. Larsen
# http://lists.gnu.org/archive/html/health-dev/2011-11/msg00008.html
#

. /etc/rc.subr

name=trytond
rcvar=`set_rcvar`

load_rc_config $name

: ${trytond_enable="NO"}
: ${trytond_user="tryton"}
: ${trytond_group="tryton"}

start_cmd=${name}_start
stop_cmd=${name}_stop
restart_cmd=${name}_restart
status_cmd=${name}_status

command="/usr/local/bin/trytond"
required_files="/usr/local/etc/trytond.conf"

trytond_start() {
  su tryton -c "$command --config=/usr/local/etc/trytond.conf" &
}

trytond_stop() {
if [ -f /var/run/${name}/${name}.pid ]; then
  kill `cat /var/run/${name}/${name}.pid`
  fi
}

trytond_restart() {
  if [ -f /var/run/${name}/${name}.pid ]; then
  kill `cat /var/run/${name}/${name}.pid`
  sleep 1
  fi
  su tryton -c "$command --config=/usr/local/etc/trytond.conf" &
}

run_rc_command "$1"

Make /usr/local/etc/rc.d/trytond executable

# chmod u+x /usr/local/etc/rc.d/trytond

Add trytond_enable to /etc/rc.conf

# echo "trytond_enable=YES" >> /etc/rc.conf

Start trytond

Start trytond using the rc script:

# /usr/local/etc/rc.d/trytond start

Once started, you can check if trytond is running with the status option:

# /usr/local/etc/rc.d/trytond status

or stop the server if needed:

# /usr/local/etc/rc.d/trytond stop

Create and configure a new Tryton database

Download and install the Tryton desktop client for your system. Launch the Tryton client and access menu: File > Databases > New database.

Enter the Tryton server admin password (“admin_passwd” in trytond.conf) in the password field, then click Change beside the IP address and change the address to that of your server.

You must enter the password first, before changing the server address, because the Tryton client will attempt to connect to the server immediately after the server address is changed, and will report “Unable to connect” if the admin password was not already entered.

Enter the name of the database to create (e.g. “scc”) and the admin password for the database, then click Create.

Login to the new database as user “admin” and the password you entered to create the database. The Module Configuration Wizard will run automatically after login to configure the new database.

  • Add user (e.g. “Dale Scott”, login “dale”), optionally add permissions (you may need to update user permissions after installing modules, so this is optional at this point),
    • add Permissions: “Administration” (which will be the only permission group available)
    • add Rule: Read, Write, Create, Delete, Model: View Search (which will be the only rule available available)

Install Tryton modules into the database

Mark modules for install

The Tryton modules previously installed to the server will not be installed in a Tryton database.

In the Tryton client, access the menu: Administration > Modules > Modules. Mark the following modules for install (double-click in the Mark for Install column):

  • dashboard
  • product
  • product-attribute
  • production
  • project
  • project-plan
  • purchase
  • sale
  • stock
  • stock-lot
  • stock-split

Install marked modules

There are two ways to install the marked modules, you can either:

  • Select Launch Action icon in the Modules menu bar and then Perform Pending Installation/Upgrade, or
  • Execute the Perform Pending Installation/Upgrade Wizard from the main Tryton menu.

After the install/upgrade completes, the Module Configuration wizard runs and will query you to configure the installed modules.

Create a Company

A company is a type of ‘party’. To identify a party as a company in a new database you must first create a new party, then select it as the new company.

  • Name
    • Swift Construction Company
  • Addresses
    • Name: Default
    • Street: 1 Swift Way
    • Zip: 13054
    • City: Shopton
    • Country: United States
    • Subdivision: New York
  • Language
    • English

Configure Company

  • Enter Company > Currency
    • US Dollar
  • On the Company > Employees > Party view
    • select the new company (e.g. Swift Construction Company)
    • select Add

Create Chart of Accounts

  • Company: Swift Construction Company
  • Account Template: Minimal Account Chart
  • Create Default Properties
    • Default Receivable Account: Main Receivable
    • Default Payable Account: Main Payable

You will need to reload the menu in the Tryton client if it isn’t now displaying menu choices for the new modules (i.e. access menu: User > Menu Reload (Ctrl-T).

The Tryton server has been installed and you can connect to it from a Tryton client. You have also created a new Tryton database with the modules necessary to implement Maestro workflows.

Miscellaneous

Update FreeBSD periodic databases

I don’t know if installing packages triggers the periodic databases to update, but since I often don’t run a virtual machine long enough to cross day, week or month boundaries (when they update automatically), I typically manually update them after major system changes.

# periodic daily
# periodic weekly
# periodic monthly

References

Load Testing a Home Internet Server

The “new” basement server hosting dalescott.net has been rock solid now for a couple days, so it was time for some load testing.

The server is an HP M7690Y media center with Intel Core2 2.40GHz CPU, 3G of RAM, and connected to the internet through a residential “internet-over-cable” service. I’m using the Apache pre-fork MPM with default configuration (no need to tune for reduced RAM with 3GB).

LoadImpact

I ran LoadImpact’s free account-required 50 user / 12 minute test, and monitored server resources while the test was running.

top/htop while while running LoadImpact test

CPU utilization spiked to maximum, but never ran out of RAM, let alone getting into the cache. Increased CPU performance means that http requests aren’t getting queued, resulting in less demand on RAM compared to a single-core CPU with 512MB RAM.

Here is the test summary. The number of VUs, or virtual users, is on the left Y-axis, the VU Page Load Time is on the right Y-axis, and time is on the X-axis.

LoadImpact results

WebPageTest

Next, I checked to see if WebPageTest liked the new server any better than the old one.

WegPageTest results

 

Compared to previous testing on the 1 CPU 512MB vps, the First Byte Time has gone from an F to a D. However, it’s not clear why Compress Images has gone from a B to a D, the servers should have identical WordPress, Apache and PHP configurations.

ISP Speed Test

Finally, I ran my ISP’s Speed Test.

ISP Speed Test

I ran the test from my laptop on the LAN side of a Hitron DOCSIS (“internet over cable”) interface adapter, but the results should apply equally to the server. The server is also connected to the Hitron, but configured on a pass-through to get its own external IP address via DHCP from my ISP.

Conclusion

Performance from the new server far exceeds that of the previous minimal vps droplet, but that is to be expected given the hardware performance. However, it seems performance on a residential ISP service is much more variable than the vps was. I ran the LoadImpact test several times from mid-morning to mid-afternoon, with worst-case VU load times in tens of seconds occurring after lunch with 40+ VUs. Obviously there will need to be changes again when the site starts drawing significant traffic.

dalescott.net is back down from the cloud!

Hosting dalescott.net on a low-cost  cloud server didn’t go so well and I had to move my site back to a bare metal server in the basement.

Step 1

It all started when I created a $5/month FreeBSD 10.1 vps using a DigitalOcean droplet (1 CPU, 512MB RAM) to host a demo for my Maestro PLM/ERP project. The site also included OpenLDAP/phpLDAPadmin and Postfix/dovecot/procmail/mutt/SquirrelMail for Swift Construction Company demo user authentication and email. The vps was rock solid, and I was very pleased with performance and cost (although getting negligible traffic).

Step 2

A year later, I tried to simplify my life by migrating my WordPress blog from a bare metal server in the basement also to the DigitalOcean vps droplet. The blog went live on the vps once I updated the IP address for my dalescott.net domain using No-IP’s DDNS service, and a day later the system was non-responsive with kernel out-of-swap errors in /var/log/messages. My immediate response was to dedicate 2G of the available 20GB SSD file space to swap (3GB total swap), but this only delayed the system becoming non-responsive to ~3 days.

I next learned how to tune the apache prefork mpm to not use more than ~300MB memory. At first, everything seemed OK and I breathed a sigh of relief, not too responsive but at least not running out of RAM and thrashing.  Then I upgraded some ports and upgraded from FreeBSD 10.1 to 10.3 (or maybe from 10.2 to 10.3, I regret not keeping better notes), but the result was that the server couldn’t maintain an ssh connection for more than 30 seconds with Apache running.

Rebooting and watching the system console, I noticed a ZFS notice I hadn’t noticed before – warning of expected unstable behaviour!

ZFS NOTICE: Prefetch is disabled by default if less than 4GB of RAM is present; to enable......
ZFS WARNING: Recommended minimal kmem_size is 512MB; expect unstable behavior....

I also noticed errors in /var/log/messages that I didn’t recall seeing before.

dale@whizzer:~ % tail /var/log/messages
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $growfs_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $ is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $rsyncd_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $php_fpm_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $htcacheclean_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $git_daemon_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $dbus_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $avahi_daemon_enable is not set properly - see rc.conf(5).
Aug 25 16:05:33 whizzer dale: /usr/sbin/service: WARNING: $avahi_dnsconfd_enable is not set properly - see rc.conf(5).
dale@whizzer:~ %

DigitalOcean now has both FreeBSD “10.3” and “10.3 zfs” droplet templates, and I had recently upgraded the system to 10.3 using “pkg upgrade”. Could there be some unexpected interaction between my manually updated system and DigitalOcean’s droplet management scaffolding?

DigitalOcean tech support was supportive and tried to help, but in the end recommended starting over.

…it’s always going to result in some issues if you upgrade a Unix system’s distribution release in-place. We see it a lot in the Linux images where a release upgrade causes some random issues down the road, and upgrades tend to not work as well as anticipated. We would recommend setting up a newly built Droplet running the release you require and then to plan your migration of applications or data onto that new system.

I was disappointed with the recommendation to start over, especially as FreeBSD is well known for being able to update in-place. Not being able to update the OS might be OK for short-lived dev servers, and maybe for production servers with a team of people to do the work when upgrading is necessary, but it was not what I was expecting.

Resolution

In the end, the decision to re-host back to my own server came down to performance, anticipated future maintenance effort, and cost. Page loading was never really as good as I wanted, especially after restricting Apache to available RAM (although at least it stayed somewhat responsive). I also didn’t look forward to having to repeat the server migration when I was ready to upgrade to FreeBSD 11.0.

Already having a suitable server on hand (a de-branded HP media tower with an Intel 2×2.3 GHz CPU, 3 GB RAM, two 400GB drives), I installed FreeBSD 10.3 and started the migration. I’ll keep the droplet for experimenting, but for now it’s back to the basement for dalescott.net.

Dale

Transparency with Trust

FreeBSD and Apache on a $5/month DigitalOcean Droplet VPS

I recently merged dalescott.net and swiftconstructioncompany.net onto a $5/month DigitalOcean droplet (512MB Memory, 1 Core Processor, 20GB SSD Disk, and
1TB Transfer). Afterwards, I wanted to get a measure of server performance. A quick web search came up with some candidates:

  1. Load Impact, claiming “The leading on-demand load and performance testing software-as-a-service.”
  2. Neustar, who claims “We started it all. And we continue to shape the industry.”
  3. WebPageTest, created by AOL for internal use before being open-sourced and now primarily developed and supported by Google.

There are more, but these will be enough to get started with. I had wanted to include Blitz.io, which was referenced in a blog post by Ryan Frankell on using Apache on a small DigitalOcean droplet . However, I couldn’t find any free evaluation capability, and Blitz’s demo is hard-coded to use a Blitz demo site, which eliminated Blitz from consideration.

Tuning Apache

The first step was to tune Apache. 512MB of RAM is low by server standards and also Apache’s default configuration. Some tuning is needed to keep Apache operating in the available RAM, otherwise Apache will gradually consume everything, including swap, and eventually the kernel will start thrashing.

KeepAlive

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

The FreeBSD apache24 port already sets these as defaults in /usr/local/etc/apache24/extra/httpd-default.conf  (the default MaxKeepAliveRequests is even lower than the recommended 200).

References

MPM-Prefork

Although Event is reportedly the default MPM in Apache 2.4, Prefork is still the default on FreeBSD 10.x for compatibility with non-thread-safe php/perl/python modules.

MaxRequestWorkers and MaxConnectionsPerChild must be lowered in /usr/local/etc/apache24/extra/httpd-mpm.conf, and the Include line for httpd-mpm.conf in usr/local/etc/apache24/httpd.conf must be un-commented (and Apache restarted).

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: min number of server processes which are kept spare
# MaxSpareServers: max number of server processes which are kept spare
# MaxRequestWorkers: max number of server processes allowed to start
# MaxConnectionsPerChild: max num of connections a server process serves
# before terminating
#
#<IfModule mpm_prefork_module>
#    StartServers 5
#    MinSpareServers 5
#    MaxSpareServers 10
#    MaxRequestWorkers 250
#    MaxConnectionsPerChild 0
#</IfModule>

<IfModule mpm_prefork_module>
 StartServers 5
 MinSpareServers 5
 MaxSpareServers 10
# reduce max number of server processes to not exceed physical memory
# called "MaxClients" prior to v2.3.13 (MaxClients is still supported)
# - uses cache under load when 25
# - appears to not use cache under load when 12
 MaxRequestWorkers 12
# reduce max connections per child to avoid idle processes from holding onto memory
# - memory use seems stable when 200 but could be lower than optimal
# MaxConnectionsPerChild 350
 MaxConnectionsPerChild 200
</IfModule>

References

Load Impact

I first used the free no-login-required test, which loads 25 Virtual Users in 5 minutes, but by creating a free login profile you are allowed 5 (QTY)-five minute tests (executions) up to 100 VUs per month. Here are the results of the Load Impact test with Apache tuned, showing load times in the low seconds for up to 15 users. This can likely be further improved, but the server is stable and adequate for the expected amount of traffic.

2016-08-12 LoadImpact test results

 

Neustar

Neustar queued three servers for testing, but the Washington server never ran. Here are the results when I gave up waiting.

image

WebPageTest

WebPageTest concentrates on measuring how fast it takes a page to load, and gives lots of information for digging into the load times for each aspect of the page. I was looking for more of a general load or stress test to see if my server will fail under load, but the information can be valuable none the less.

image

Server Performance

Here are the result of top while the Load Impact no-login (20 VU) test is running. Although the server can by no means be considered fast, it also is not exhausting swap and stalling. I’m pleased for now, and will be back to review when time permits.

top-load-test-during