Skip to content

Fittrackee Installation - Meine Schritte

I like walking and running and would like to share my routes with others and record them for myself. I want to manage my data independently. I sometimes use the well-known online fitness trackers. I like the fact that I can share my activities with others. I don’t like the fact that the data is not in my hands. What’s more, with most providers I can specify who is allowed to see which things. However, I’m not entirely happy with this because I don’t have access to the source code of the systems myself.

An open source application that

  • I can install myself
  • that offers the possibility of shared use and
  • ideally supports the ActivityPub protocol has long seemed to me to be the ideal solution.

I was pretty happy when I found Fittrackee. The local installation worked smoothly. If you just want to track your data in a nice format, it may be enough to manage your GPX files in a local installation. Support for the ActivityPub protocol has not yet been implemented, but is being planned.

I have been looking for a hosting provider where I can install all the tools I need to run Fittrackee. I found one with Uberspace.

I would like to share the steps I took during the test installation here.

Set up an account with Uberspace

Create account

The first thing I did was create an account with Uberspace. The host offers the possibility to test everything for a month before you have to pay for the offer. This way you can find out for yourself whether everything works and whether you are satisfied with Uberspace’s offer and support. When setting up, all you need to do is enter an e-mail address.

Set up access

To log in to the Uberspace server via Secure Shell SSH, it is necessary to set a password. The easiest way to do this is after logging in to the customer area via the Zugänge tab in the SSH-Zugang zum Uberspace area.

Zugang

I used a simple password for testing.

Via SSH anmelden

The login to the Uberspace server is done via the command line. All necessary data can be found in the Uberspace customer area - specifically in the tabulator Datenblatt.

The Uberspace assigned to the user ub is located on the server lupus.uberspace.de.

Web

I have access to the area assigned to me via ub.uber.space.

SSH

Concretely, this looks as follows on the command line:

Terminal window
$ ssh ub@ub.uber.space
(ub@ub.uber.space) Password:
Last failed login: Tue Oct 10 12:21:20 CEST 2023 from 45.150.13.187 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Tue Oct 10 12:19:42 2023 from 45.150.13.187
Welcome to Uberspace 7!
Current version: 7.15.9
Manual: https://manual.uberspace.de
Lab - guides and inspirations for apps: https://lab.uberspace.de
Watch out for changes at: https://manual.uberspace.de/changelog
Follow us on Twitter or Mastodon for updates:
- https://twitter.com/ubernauten
- https://uberspace.social/@ubernauten
Is something unclear or does not work as expected?
=> check the server status: https://is.uberspace.online
=> reach out to our team by mail: hallo@uberspace.de
=> Contact support on Twitter: https://twitter.com/hallouberspace
=> Contact support on Mastodon: https://uberspace.social/@hallo
[ub@lupus ~]$

Here [ub@lupus ~]$ is the command line of the server at Uberspace.

Orientation

I would like to get an overview at the beginning. First, I look at the root directory for the web space in the html folder.

[ub@lupus ~]$ ls
bin etc html logs Maildir tmp users
[ub@lupus ~]$ cd html
[ub@lupus html]$ ls
nocontent.html

The html directory contains a file called nocontent.html. I checked the code of the file via cat nocontent.html:

Terminal window
[ub@lupus html]$ cat nocontent.html
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<h2>Dieser Uberspace hat noch keinen Inhalt.</h2>
<h2>This Uberspace does not have any content yet.</h2>
<h3>
Sollte er dir gehören, kannst du, wie
<a
href="https://manual.uberspace.de/web-documentroot.html"
target="_blank"
>im Manual</a
>
beschrieben, Inhalte in /var/www/virtual/ub/html
hochladen.
</h3>
<h3>
In case it is yours, take a look at
<a
href="https://manual.uberspace.de/web-documentroot.html"
target="_blank"
>the manual</a
>
to learn how to upload your content to /var/www/virtual/ub/html.
</h3>
</body>
</html>
[ub@lupus html]$

If I type https://[MyUser].uber.space/ in the address bar of my browser and open the page, exactly this HTML file is displayed.

Orientation

Fittrackee

The developer of Fittrackee has described the installation in the Documentation.

Create directories for Fittrackee

To keep everything clearly organized, I create a fittrackee directory in /home/ub/

  • a directory fittrackee, in which I store all Fittracke data together and
  • a separate directory for the uploads of the GPX files fittrackee\upldad.

At the end I change to the directory /home/ub/fittrackee.

Terminal window
[ub@lupus ~]$ mkdir /home/ub/fittrackee
[ub@lupus ~]$ mkdir /home/ub/fittrackee/upload
[ub@lupus ~]$ cd /home/ub/fittrackee/
[ub@lupus fittrackee]$

Install Fittrackee and set up a virtual environment for Python

Fittrackee is a Python application and it makes sense to install it in a virtual environment. Minimum requirement is Python version 3.8.

Information on how Python is pre-installed in Uberspace can be found in the Manual.

An overview of the different versions of Python can be found at python.org.

In the following I will show you my steps during the installation.

Terminal window
[ub@lupus fittrackee]$ python3.9 -m venv fittrackee_venv
[ub@lupus fittrackee]$ ls
fittrackee_venv upload
[ub@lupus fittrackee]$ source fittrackee_venv/bin/activate
(fittrackee_venv) [ub@lupus fittrackee]$

In the virtual environment, I install the Fittrackee application using the install fittrackee command.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ pip3.9 install fittrackee
Collecting fittrackee
...
[notice] A new release of pip is available: 23.0.1 -> 23.2.1
[notice] To update, run: pip install --upgrade pip

I update the package installer for Python pip via pip3.9 install --upgrade pip.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ pip3.9 install --upgrade pip
Requirement already satisfied: pip in ./fittrackee_venv/lib/python3.9/site-packages (23.0.1)
Collecting pip
Downloading pip-23.2.1-py3-none-any.whl (2.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 16.4 MB/s eta 0:00:00
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 23.0.1
Uninstalling pip-23.0.1:
Successfully uninstalled pip-23.0.1
Successfully installed pip-23.2.1
(fittrackee_venv) [ub@lupus fittrackee]$

I then explicitly install version 1.26.6 of urllib3, because I know from experience that otherwise I will get an error message about the version later when setting up the database. So I run pip3.9 install urllib3==1.26.6.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ pip3.9 install urllib3==1.26.6
Collecting urllib3==1.26.6
Downloading urllib3-1.26.6-py2.py3-none-any.whl (138 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 138.5/138.5 kB 7.3 MB/s eta 0:00:00
Installing collected packages: urllib3
Attempting uninstall: urllib3
Found existing installation: urllib3 2.0.6
Uninstalling urllib3-2.0.6:
Successfully uninstalled urllib3-2.0.6
Successfully installed urllib3-1.26.6
(fittrackee_venv) [ub@lupus fittrackee]$

Otherwise, in other words without the previous step, setting up the database would be aborted later with the following error message.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ ftcli db upgrade
Traceback (most recent call last):
File "/home/ub/fittrackee/fittrackee_venv/bin/ftcli", line 5, in <module>
from fittrackee.cli import cli
File "/home/ub/fittrackee/fittrackee_venv/lib64/python3.9/site-packages/fittrackee/__init__.py", line 25, in <module>
from fittrackee.emails.email import EmailService
File "/home/ub/fittrackee/fittrackee_venv/lib64/python3.9/site-packages/fittrackee/emails/email.py", line 11, in <module>
from urllib3.util import parse_url
File "/home/ub/fittrackee/fittrackee_venv/lib64/python3.9/site-packages/urllib3/__init__.py", line 41, in <module>
raise ImportError(
ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168
(fittrackee_venv) [ub@lupus fittrackee]$ pip install --upgrade pip
Requirement already satisfied: pip in ./fittrackee_venv/lib/python3.9/site-packages (23.2.1)

Mit deactivate verlasse ich die virtuelle Umgebung um mit der Konfiguration der Datenbank fortzufahren.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ deactivate
[ub@lupus fittrackee]$

Database

Fittrackee uses a PostgreSQL database. Minimum requirement is PostgreSQL version 11. Information about PostgreSQL at Uberspace can be found in the documentation.

You can find out which PostgreSQL version on the Uberspace server is active via uberspace tools version show postgresql.

Terminal window
[ub@lupus fittrackee]$ uberspace tools version show postgresql
Using 'Postgresql' version: '15'

Initialisierung

Umgebungsvariablen

Via editor add the following line to the file ~/.bash_profile.

# PostgreSQL Environment
export PGPASSFILE=$HOME/.pgpass

I use Nano as editor. If you prefer to work with the Vi editor, you can also do this at Uberspace.

I open the file ~/.bash_profile via nano ~/.bash_profile and edit it.

Terminal window
[ub@lupus ~]$ nano ~/.bash_profile

I then check via cat whether everything has been saved correctly and whether the newly inserted line is included at the end of the file.

.bash_profile
[ub@lupus ~]$ cat ~/.bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$HOME/.local/bin:$HOME/bin:$PATH
export PATH
# PostgreSQL Environment
export PGPASSFILE=$HOME/.pgpass

Then I call the file .bash_profile via source ~/.bash_profile so that my new environment variable is loaded:

Terminal window
[ub@lupus ~]$ source ~/.bash_profile
[ub@lupus ~]$

At the end I make sure that the variable $PGPASSFILE is set correctly.

Terminal window
[ub@lupus ~]$ echo $PGPASSFILE
/home/ub/.pgpass

The database cluster

I created the database cluster as described in the documentation.

First I generated a random number via openssl rand and saved it in the temporary file ~/pgpass.temp and then copied it to a hidden file ~/.pgpass.

Terminal window
[ub@lupus ~]$ openssl rand -hex 32 > ~/pgpass.temp
[ub@lupus ~]$ cp ~/pgpass.temp ~/.pgpass
[ub@lupus ~]$

Die Datei enthält bisher lediglich die Zufallszahl.

Terminal window
[ub@lupus ~]$ cat ~/.pgpass
6example0fa5b0c8b34be04b582fb44f63c3198b1daa84b92b0fc49bda1955b

According to PostgreSQL documentation, ~/.pgpass should contain lines in the following format:

Terminal window
hostname:port:database:username:password

Depending on my environment, I edit the file as shown in the next code block. The character * is a wildcard, a placeholder for any number of characters. ub is the user and the random number is the password.

Terminal window
[ub@lupus ~]$ nano ~/.pgpass
[ub@lupus ~]$ cat ~/.pgpass
*:*:*:ub:6example0fa5b0c8b34be04b582fb44f63c3198b1daa84b92b0fc49bda1955b

For everything to work, the authorizations for the file ~/.pgpass must be configured.

Terminal window
[ub@lupus ~]$ chmod 0600 ~/.pgpass

At the end I call initdb --pwfile ~/pgpass.temp --auth=scram-sha-256 -E UTF8 -D ~/opt/postgresql/data/.

Terminal window
[ub@lupus ~]$ initdb --pwfile ~/pgpass.temp --auth=scram-sha-256 -E UTF8 -D ~/opt/postgresql/data/
Die Dateien, die zu diesem Datenbanksystem gehören, werden dem Benutzer
»ub« gehören. Diesem Benutzer muss auch der Serverprozess gehören.
Der Datenbankcluster wird mit der Locale »de_DE.UTF-8« initialisiert werden.
Die Standardtextsuchekonfiguration wird auf »german« gesetzt.
Datenseitenprüfsummen sind ausgeschaltet.
erzeuge Verzeichnis /home/ub/opt/postgresql/data ... ok
erzeuge Unterverzeichnisse ... ok
wähle Implementierung von dynamischem Shared Memory ... posix
wähle Vorgabewert für max_connections ... 100
wähle Vorgabewert für shared_buffers ... 128MB
wähle Vorgabewert für Zeitzone ... Europe/Berlin
erzeuge Konfigurationsdateien ... ok
führe Bootstrap-Skript aus ... ok
führe Post-Bootstrap-Initialisierung durch ... ok
synchronisiere Daten auf Festplatte ... ok
Erfolg. Sie können den Datenbankserver jetzt mit
/usr/pgsql-15/bin/pg_ctl -D /home/ub/opt/postgresql/data/ -l logdatei start
starten.

Finally, I delete the temporary file ~/pgpass.temp.

Terminal window
[ub@lupus ~]$ rm ~/pgpass.temp
[ub@lupus ~]$

Configuration

Unix Socket

Now I look at the file ~/.bashrc.

.bashrc
[ub@lupus ~]$ cat ~/.bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions

Here I insert the user-specific aliases and functions below User specific aliases and functions. Specifically, these are the lines export PGHOST=localhost and export PGPORT=5432.

.bashrc
[ub@lupus ~]$ nano ~/.bashrc
[ub@lupus ~]$ cat ~/.bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
export PGHOST=localhost
export PGPORT=5432
[ub@lupus ~]$

Now I call the file via source so that my new variables are created.

Terminal window
[ub@lupus ~]$ source ~/.bashrc
[ub@lupus ~]$
PostgreSQL Configuration

Next, I open the file ~/opt/postgresql/data/postgresql.conf for editing.

Terminal window
[ub@lupus ~]$ nano ~/opt/postgresql/data/postgresql.conf

The file is very big. I am searching for the following text in the file: #unix_socket_directories = '/var/run/postgresql, /tmp' # comma-separated list of directories

After finding I delet this line and insert the line unix_socket_directories = '/home/[MyUserName]/tmp' instead. In my case this is concrete:

Terminal window
...
unix_socket_directories = '/home/ub/tmp'
...
Daemon

Now I am setting up everything necessary for the PostgreSQL service. The file ~/etc/services.d/postgresql.ini does not yet exist.

Terminal window
[ub@lupus ~]$ cat ~/etc/services.d/postgresql.ini
cat: /home/ub/etc/services.d/postgresql.ini: Datei oder Verzeichnis nicht gefunden

I create the file ~/etc/services.d/postgresql.ini and insert the required text for the PostgreSQL service.

Terminal window
[ub@lupus ~]$ nano ~/etc/services.d/postgresql.ini
[ub@lupus ~]$ cat ~/etc/services.d/postgresql.ini
[program:postgresql]
command=postgres -D %(ENV_HOME)s/opt/postgresql/data/
autostart=yes
autorestart=yes
startsecs=15
[ub@lupus ~]$

Now I test whether the PostgreSQL service is working properly by stopping and starting it and looking at the output in the command line. Sometimes I have to be patient because it takes a while for the service to change the status from STARTING to RUNNING.

Terminal window
[ub@lupus ~]$ supervisorctl status
[ub@lupus ~]$ supervisorctl reread
postgresql: available
[ub@lupus ~]$ supervisorctl update
postgresql: added process group
[ub@lupus ~]$ supervisorctl status
postgresql STARTING
[ub@lupus ~]$ supervisorctl status
postgresql STARTING
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 21503, uptime 0:00:23
[ub@lupus ~]$

How I manage services at Uberspace is described in Manuel.

Terminal window
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 21503, uptime 0:00:23
[ub@lupus ~]$ supervisorctl stop postgresql
postgresql: stopped
[ub@lupus ~]$ supervisorctl status
postgresql STOPPED Sep 20 04:27 PM
[ub@lupus ~]$ supervisorctl start postgresql
postgresql: started
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 23200, uptime 0:00:20
[ub@lupus ~]$

If something is not working properly, I look for hints in the log file ~/opt/postgresql/data/log/.

Create database, database user and schema

If everything runs smoothly, I can create

  • the database user required for Fittrackee,
  • the database and
  • the schema required for Fittrackee.

As recommended in the Uberspace documentation, I create the database user.

Terminal window
[ub@lupus ~]$
[ub@lupus ~]$ createuser fittrackee -P
Enter password for new role:
Enter it again:

As also recommended in the Uberspace documentation, I create the database.

Terminal window
[ub@lupus ~]$ createdb --encoding=UTF8 --owner=fittrackee --template=template0 fittrackee

Via psql I create the scheme required in the Fittrackee documentation.

Terminal window
[ub@lupus ~]$ psql fittrackee
psql (15.4)
Type "help" for help.
fittrackee=# CREATE SCHEMA fittrackee AUTHORIZATION fittrackee;
CREATE SCHEMA
fittrackee=# exit
[ub@lupus ~]$

Everything important for the database is now set.

Redis

Information about Redis at Uberspace can be found in Manuel and about Redis in general I looked at the Redis Doku.

According to Manuel, Redis does not run on a port at Uberspace by default, but offers a Unix socket under /home/$USER/.redis/sock. You either have to adjust the configuration of the Fittrackee application or change the Redis configuration from port 0 to port 6379. I decided to take the latter option.

Configuration

When customizing the configuration, I did not set the port to 0, as described in Manuel, but to 6379, so it is not necessary to change anything in the Fittrackee application itself.

Terminal window
[ub@lupus ~]$ mkdir ~/.redis/
[ub@lupus ~]$ nano ~/.redis/conf
[ub@lupus ~]$ cat ~/.redis/conf
unixsocket /home/ub/.redis/sock
daemonize no
port 6379
save ""
[ub@lupus ~]$

Daemon

To start the Redis service, I create the file ~/etc/services.d/redis.ini. The next steps are similar to the descriptions in Manuel.

Terminal window
[ub@lupus ~]$ cat ~/etc/services.d/redis.ini
cat: /home/ub/etc/services.d/redis.ini: Datei oder Verzeichnis nicht gefunden
[ub@lupus ~]$ nano ~/etc/services.d/redis.ini
[ub@lupus ~]$ cat ~/etc/services.d/redis.ini
[program:redis]
command=redis-server %(ENV_HOME)s/.redis/conf
directory=%(ENV_HOME)s/.redis
autostart=yes
autorestart=yes
[ub@lupus ~]$
Terminal window
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 23200, uptime 0:41:38
[ub@lupus ~]$ supervisorctl reread
redis: available
[ub@lupus ~]$ supervisorctl update
redis: added process group
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 23200, uptime 0:41:57
redis RUNNING pid 19237, uptime 0:00:06
[ub@lupus ~]$
Stop and start
Terminal window
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 31985, uptime 1 day, 15:12:57
redis RUNNING pid 5306, uptime 1 day, 15:03:18
[ub@lupus ~]$ supervisorctl stop redis
redis: stopped
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 31985, uptime 1 day, 15:13:06
redis STOPPED Sep 22 10:40 AM
[ub@lupus ~]$ supervisorctl start redis
redis: started
[ub@lupus ~]$ supervisorctl status
postgresql RUNNING pid 31985, uptime 1 day, 15:13:47
redis RUNNING pid 4129, uptime 0:00:35
[ub@lupus ~]$

Test access

In the Uberspace manual, the call redis-cli -s ~/.redis/soc is suggested for testing. This does not work with the installation variant suggested here because we have changed the port.

Terminal window
[ub@lupus ~]$ redis-cli -s ~/.redis/soc
Could not connect to Redis at /home/ub/.redis/soc: No such file or directory
not connected> exit

So I try a different approach. I open the redis-cli.

Terminal window
[ub@lupus ~]$ redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> Set mykey "Test"
OK
127.0.0.1:6379> Get mykey
"Test"
127.0.0.1:6379> exit

That looks fine for me.

Optional: email

To be able to send e-mails from Fittrackee, you need an e-mail account, which you specify later in the .env file. Any account can be used for this purpose. If you like, you can create the account directly at Uberspace.

In the Uberspace manual you will find information about the e-mail accounts.

E-Mail

Environment variables for Fittrackee

I create a file in which I insert all the environment variables required for Fittrackee. Further information on the environment variables can be found in the Fittrackee documentation.

Standard file for configuring the environment variables

I use the file sample file from Github as a basis.

Terminal window
# Custom variables initialisation
# (can overwrite variables present in Makefile.config)
# Application
# export FLASK_APP=fittrackee
export FLASK_SKIP_DOTENV=1
# export HOST=
# export PORT=
# export APP_SETTINGS=fittrackee.config.ProductionConfig
export APP_SECRET_KEY='please change me'
# export APP_WORKERS=
export APP_LOG=fittrackee.log
export UPLOAD_FOLDER=
# PostgreSQL
# export DATABASE_URL=postgresql://fittrackeeuser:fittrackeepwd@${HOST}:5432/fittrackee
# export DATABASE_DISABLE_POOLING=
# Redis (required for API rate limits and email sending)
# export REDIS_URL=
# API rate limits
# export API_RATE_LIMITS="300 per 5 minutes"
# Emails
export UI_URL=
export EMAIL_URL=
export SENDER_EMAIL=
# export WORKERS_PROCESSES=
# Workouts
# export TILE_SERVER_URL=
# export STATICMAP_SUBDOMAINS=
# export MAP_ATTRIBUTION=
# export DEFAULT_STATICMAP=False
# Weather
# available weather API providers: visualcrossing
# export WEATHER_API_PROVIDER=
# export WEATHER_API_KEY=

Example of customizing the environment variables

I create the file in which I configure my customized environment variables.

Terminal window
[ub@lupus ~]$ nano /home/ub/fittrackee/.env

My file looks like the following:

Terminal window
export FLASK_APP=fittrackee
export FLASK_SKIP_DOTENV=1
export HOST=0.0.0.0
export PORT=5000
export APP_SETTINGS=fittrackee.config.ProductionConfig
export APP_SECRET_KEY='please change me now'
export APP_WORKERS=1
export APP_LOG=fittrackee.log
export UPLOAD_FOLDER=/home/ub/fittrackee/upload
# PostgreSQL
export DATABASE_URL=postgresql://fittrackee:fittrackee@localhost:5432/fittrackee
# Redis
export REDIS_URL=redis://
# API rate limits
export API_RATE_LIMITS="300 per 5 minutes"
# Emails and URLs
export UI_URL=ub.uber.space
export EMAIL_URL=smtp://fittrackee@ub.uber.space:fittrackeeemailpasswort@smtp.ub.uberspace.de:587/?tls=True
export SENDER_EMAIL=fittrackee@ub.uber.space
export WORKERS_PROCESSES=2
# Workouts
export TILE_SERVER_URL=https://tile.openstreetmap.org/{z}/{x}/{y}.png
export MAP_ATTRIBUTION='OpenStreetMap contributors'
# Weather
export WEATHER_API_PROVIDER=visualcrossing
export WEATHER_API_KEY=MEINKEYNICHTDEINKEY

Was habe ich geändert? Das meiste ist im Abdruck der Datei ersichtlich. Zu beachten sind insbesondere die Zeilen export HOST=0.0.0.0 und export DATABASE_URL=postgresql://fittrackee:fittrackee@localhost:5432/fittrackee.

Setting up and activating Fittrackee

I choose the Installation via PyPI (The Python Package Index).

Activating the virtual environment

At the beginning I activate the virtual environment for Python via source fittrackee_venv/bin/activate.

Terminal window
[ub@lupus fittrackee]$ cd /home/ub/fittrackee/
[ub@lupus fittrackee]$ ls
fittrackee_venv upload
[ub@lupus fittrackee]$ source fittrackee_venv/bin/activate
(fittrackee_venv) [ub@lupus fittrackee]$

Load environment variables for Fittrackee

I then load the environment variables previously configured in the file /home/ub/fittrackee/.env. As the name of the .env file begins with a dot, it is hidden in the operating system by default. Using the a parameter in the ls command, I can see the hidden files. This is how I ensure that the file exists.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ ls -a
. .. .env fittrackee_venv upload
(fittrackee_venv) [ub@lupus fittrackee]$

Then I call the file .env via source to load all environment variables into the system.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ source .env

Initialize database schema

(fittrackee_venv) [ub@lupus fittrackee]$ ftcli db upgrade
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 9741fc7834da, create User table
INFO [alembic.runtime.migration] Running upgrade 9741fc7834da -> b7cfe0c17708, create Activity & Sport tables
INFO [alembic.runtime.migration] Running upgrade b7cfe0c17708 -> caf0e0dc621a, create Record table
INFO [alembic.runtime.migration] Running upgrade caf0e0dc621a -> dd73d23a7a3d, create Activities Segments table
INFO [alembic.runtime.migration] Running upgrade dd73d23a7a3d -> 92adde6ac0d0, add 'bounds' column to 'Activity' table
INFO [alembic.runtime.migration] Running upgrade 92adde6ac0d0 -> 5a42db64e872, add static map url to 'Activity' table
INFO [alembic.runtime.migration] Running upgrade 5a42db64e872 -> 9f8c9c37da44, add static map id to 'Activity' table
INFO [alembic.runtime.migration] Running upgrade 9f8c9c37da44 -> e82e5e9447de, add 'timezone' to 'User' table
INFO [alembic.runtime.migration] Running upgrade e82e5e9447de -> 71093ac9ca44, add weather infos in 'Activity' table
INFO [alembic.runtime.migration] Running upgrade 71093ac9ca44 -> 096dd0b43beb, Add 'notes' column to 'Activity' table
INFO [alembic.runtime.migration] Running upgrade 096dd0b43beb -> 27425324c9e3, add 'weekm' in 'User' table
INFO [alembic.runtime.migration] Running upgrade 27425324c9e3 -> f69f1e413bde, add 'language' to 'User' table
INFO [alembic.runtime.migration] Running upgrade f69f1e413bde -> 1345afe3b11d, replace 'is_default' with 'is_active' in 'Sports' table
INFO [alembic.runtime.migration] Running upgrade 1345afe3b11d -> 8a0aad4c838c, add application config in database
INFO [alembic.runtime.migration] Running upgrade 8a0aad4c838c -> 3243cd25eca7, add uuid to activities
INFO [alembic.runtime.migration] Running upgrade 3243cd25eca7 -> 4e8597c50064, rename 'activity' with 'workout'
INFO [alembic.runtime.migration] Running upgrade 4e8597c50064 -> cee0830497f8, Add new sports
INFO [alembic.runtime.migration] Running upgrade cee0830497f8 -> 9842464bb885, add stopped speed threshold to sports
INFO [alembic.runtime.migration] Running upgrade 9842464bb885 -> 080acc8ee956, add sport preferences
INFO [alembic.runtime.migration] Running upgrade 080acc8ee956 -> 07188ca7620a, add imperial units preferences
INFO [alembic.runtime.migration] Running upgrade 07188ca7620a -> ed409fd9db9d, add snowshoes sport
INFO [alembic.runtime.migration] Running upgrade ed409fd9db9d -> e30007d681cb, add missing indexes on Workout table
INFO [alembic.runtime.migration] Running upgrade e30007d681cb -> 5e3a3a31c432, update User and AppConfig tables
INFO [alembic.runtime.migration] Running upgrade 5e3a3a31c432 -> cd0e6cf83207, add ascent record
INFO [alembic.runtime.migration] Running upgrade cd0e6cf83207 -> 84d840ce853b, add OAuth 2.0 and blacklisted tokens
INFO [alembic.runtime.migration] Running upgrade 84d840ce853b -> 5b936821326d, add virtual cycling as sport type
INFO [alembic.runtime.migration] Running upgrade 5b936821326d -> bf13b8f5589d, Add date_format for date display to user preferences in DB
INFO [alembic.runtime.migration] Running upgrade bf13b8f5589d -> a8cc0adfe1d3, add Mountaineering
INFO [alembic.runtime.migration] Running upgrade a8cc0adfe1d3 -> 0f375c44e659, update elevation precision
INFO [alembic.runtime.migration] Running upgrade 0f375c44e659 -> 374a670efe23, add privacy policy
INFO [alembic.runtime.migration] Running upgrade 374a670efe23 -> db58d195c5bf, add user preference to start elevation plots at zero
INFO [alembic.runtime.migration] Running upgrade db58d195c5bf -> eff1c16c43eb, Add user preference for gpx speed calculation
INFO [alembic.runtime.migration] Running upgrade eff1c16c43eb -> d22670a89a54, add paragliding sport
INFO [alembic.runtime.migration] Running upgrade d22670a89a54 -> 24eb097614e4, add open water swimming
(fittrackee_venv) [ub@lupus fittrackee]$

Der Befehl netstat -tupen zeigt jetzt folgende Liste:

(fittrackee_venv) [ub@lupus fittrackee]$ netstat -tulpen
Aktive Internetverbindungen (Nur Server)
Proto Recv-Q Send-Q Local Address Foreign Address State Benutzer Inode PID/Program name
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1215 269297806 11983/postgres
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 1215 269390811 26038/redis-server
tcp6 0 0 ::1:5432 :::* LISTEN 1215 269297805 11983/postgres
tcp6 0 0 :::25 :::* LISTEN 0 268899212 -
tcp6 0 0 :::443 :::* LISTEN 0 268899211 -
tcp6 0 0 :::993 :::* LISTEN 0 268899209 -
tcp6 0 0 :::995 :::* LISTEN 0 268899210 -
tcp6 0 0 :::3306 :::* LISTEN 0 268899206 -
tcp6 0 0 :::6379 :::* LISTEN 1215 269390812 26038/redis-server
tcp6 0 0 :::587 :::* LISTEN 0 268899213 -
tcp6 0 0 :::110 :::* LISTEN 0 268899207 -
tcp6 0 0 :::143 :::* LISTEN 0 268899208 -
tcp6 0 0 :::80 :::* LISTEN 0 268899214 -
tcp6 0 0 :::22 :::* LISTEN 0 268899205 -

Start Fittrackee

We could now start Fittrackee via fittrackee. For the sake of completeness, I describe this in this chapter. However, since we will activate fittrackee later via a service, I skip these steps in the real installation.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ fittrackee
[2023-10-10 18:22:17 +0200] [7535] [INFO] Starting gunicorn 21.2.0
[2023-10-10 18:22:17 +0200] [7535] [INFO] Listening at: http://0.0.0.0:5000 (7535)
[2023-10-10 18:22:17 +0200] [7535] [INFO] Using worker: sync
[2023-10-10 18:22:17 +0200] [7544] [INFO] Booting worker with pid: 7544

The command netstat -tulpen can be opened in another command line. The command now shows the following list. The second line has been added.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ netstat -tulpen
Aktive Internetverbindungen (Nur Server)
Proto Recv-Q Send-Q Local Address Foreign Address State Benutzer Inode PID/Program name
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1215 269297806 11983/postgres
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 1215 269688055 7535/python3.9
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 1215 269390811 26038/redis-server
tcp6 0 0 ::1:5432 :::* LISTEN 1215 269297805 11983/postgres
tcp6 0 0 :::25 :::* LISTEN 0 268899212 -
tcp6 0 0 :::443 :::* LISTEN 0 268899211 -
tcp6 0 0 :::993 :::* LISTEN 0 268899209 -
tcp6 0 0 :::995 :::* LISTEN 0 268899210 -
tcp6 0 0 :::3306 :::* LISTEN 0 268899206 -
tcp6 0 0 :::6379 :::* LISTEN 1215 269390812 26038/redis-server
tcp6 0 0 :::587 :::* LISTEN 0 268899213 -
tcp6 0 0 :::110 :::* LISTEN 0 268899207 -
tcp6 0 0 :::143 :::* LISTEN 0 268899208 -
tcp6 0 0 :::80 :::* LISTEN 0 268899214 -
tcp6 0 0 :::22 :::* LISTEN 0 268899205 -
[ub@lupus fittrackee]$

Worker für E-Mail Versendung via Flask starten:

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ flask worker --processes 2
(fittrackee_venv) [ub@lupus fittrackee]$

Redirect port 5000 to the documentation root

Since it is not possible to access all ports of the Uberspace server from outside and we also want to provide a call without port specification on the Internet, we configure web backends. Further information can be found in Manuel.

What does the output of the Web Backend List look like by default? This is shown by the command uberspace web backend list.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ uberspace web backend list
/ apache (default)

You can redirect the output of port 5000 to the document root / via uberspace web backend set / --http --port 5000.

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ uberspace web backend set / --http --port 5000
Set backend for / to port 5000; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".

The updated list now looks like this, if Fittrackee is started:

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ uberspace web backend list
/ http:5000 => OK, listening: PID 7544, /home/ub/fittrackee/fittrackee_venv/bin/python3.9 /home/ub/fittrackee/fittrackee_venv/bin/fittrackee

If the service has not yet been started because we will start it as a service later, the message / http:5000 => NOT OK, no service is displayed.

Daemon/Systemd

Application: fittrackee.service

Terminal window
[ub@lupus ~]$ nano ~/etc/services.d/fittrackee.ini
[ub@lupus ~]$ cat ~/etc/services.d/fittrackee.ini
[program:fittrackee]
command=bash -c 'source %(ENV_HOME)s/fittrackee/.env && %(ENV_HOME)s/fittrackee/fittrackee_venv/bin/gunicorn -b 0.0.0.0:5000 "fittrackee:create_app()" --error-logfile %(ENV_HOME)s/fittrackee/gunicorn.log'
autostart=yes
autorestart=yes
startsecs=30

task queue workers: fittrackee_workers.service

Terminal window
[ub@lupus ~]$ nano ~/etc/services.d/fittrackee_workers.ini
[ub@lupus ~]$ cat ~/etc/services.d/fittrackee_workers.ini
[program:fittrackee_worker]
command=bash -c 'source %(ENV_HOME)s/fittrackee/.env && %(ENV_HOME)s/fittrackee/fittrackee_venv/bin/flask worker --processes 2'
autostart=yes
autorestart=yes
startsecs=30

Start Services

Terminal window
[ub@lupus ~]$ supervisorctl status
[ub@lupus ~]$ supervisorctl reread
fittrackee: available
fittrackee_worker: available
[ub@lupus ~]$ supervisorctl update
[ub@lupus ~]$

The services are now active and the application can be accessed via the Internet.

Opening the application on the web

The application can now be opened via the Internet browser at https://ub.uber.space/, where ub stands for the specific user.

E-Mail

Register user

It is now possible to create a user.

E-Mail

After submitting the registration form, a message should appear. If an error occurs, it is very likely that something is wrong with the e-mail configuration.

E-Mail

Assign Admin status to a user

Terminal window
(fittrackee_venv) [ub@lupus fittrackee]$ ftcli users update astrid --set-admin true
User 'astrid' updated.
(fittrackee_venv) [ub@lupus fittrackee]$

Optional

Set up web backends for external domain

Do you want your Fittrackee application to be accessible under your domain such as example.org or a subdomain such as subdomain.example.org? It should not just be a simple forwarding, but a DNS addressing. In this case, Uberspace Web Backends come into play! You can find more information about web backends at Uberspace in Manuel.

In the first step, I add the domain ub.dimna.de to the Uberspace configuration.

Terminal window
[ub@lupus ~]$ uberspace web domain add ub.dimna.de
The webserver s configuration has been adapted.
Now you can use the following records for your DNS:
A -> 123.456.789.176
AAAA -> xxxx:1a50:xx:0:80ce:69ff:fe92:c1d3
[ub@lupus ~]$

Die Werte, die mir hinter A und AAAA ausgegeben werden, muss ich im zweiten Schritt bei dem Anbieter konfigurieren, bei dem ich die ub.dimna.de registriert habe.

Im dritten Schritt richte ich das Web Backend für die Domain ub.dimna.de ein.

Terminal window
[ub@lupus ~]$ uberspace web backend set ub.dimna.de --http --port 5000
Set backend for ub.dimna.de/ to port 5000; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[ub@lupus ~]$

Fittrackee ist noch nicht auf Port 5000 aktiviert. Dies muss ich nachholen.

Terminal window
[ub@lupus ~]$ uberspace web backend list
ub.dimna.de/ http:5000 => NOT OK, no service
/ apache (default)

Problems

It should look like this

[ub@lupus ~]$ netstat -tulpen
Aktive Internetverbindungen (Nur Server)
Proto Recv-Q Send-Q Local Address Foreign Address State Benutzer Inode PID/Program name
tcp 0 0 0.0.0.0:9191 0.0.0.0:* LISTEN 1213 3962665678 27760/python3.9
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 1213 3962660307 25867/python3.9
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 1213 3962650056 24910/redis-server
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1213 3962618249 24676/postgres
tcp6 0 0 :::3306 :::* LISTEN 0 3927957775 -
tcp6 0 0 :::6379 :::* LISTEN 1213 3962650057 24910/redis-server
tcp6 0 0 :::587 :::* LISTEN 0 3927957781 -
tcp6 0 0 :::110 :::* LISTEN 0 3927957780 -
tcp6 0 0 :::143 :::* LISTEN 0 3927957777 -
tcp6 0 0 :::80 :::* LISTEN 0 3927957782 -
tcp6 0 0 :::22 :::* LISTEN 0 3927957774 -
tcp6 0 0 ::1:5432 :::* LISTEN 1213 3962618248 24676/postgres
tcp6 0 0 :::25 :::* LISTEN 0 3927957776 -
tcp6 0 0 :::443 :::* LISTEN 0 3927957773 -
tcp6 0 0 :::993 :::* LISTEN 0 3927957778 -
tcp6 0 0 :::995 :::* LISTEN 0 3927957779 -

Kill process

You can also kill a process that you (i.e. your Linux user) have started. If it is not clear which one it is, tools such as ps, top, htop or, in this case, netstat can help:

[ub@lupus ~]$ netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN 1211 3907722271 3801/python3.9
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1211 3890130994 30917/postgres
tcp6 0 0 :::3306 :::* LISTEN 0 3871556965 -
tcp6 0 0 :::587 :::* LISTEN 0 3871556959 -
tcp6 0 0 :::110 :::* LISTEN 0 3871556966 -
tcp6 0 0 :::143 :::* LISTEN 0 3871556967 -
tcp6 0 0 :::80 :::* LISTEN 0 3871556964 -
tcp6 0 0 :::22 :::* LISTEN 0 3871556960 -
tcp6 0 0 ::1:5432 :::* LISTEN 1211 3890130993 30917/postgres
tcp6 0 0 :::25 :::* LISTEN 0 3871556961 -
tcp6 0 0 :::443 :::* LISTEN 0 3871556963 -
tcp6 0 0 :::993 :::* LISTEN 0 3871556962 -
tcp6 0 0 :::995 :::* LISTEN 0 3871556958 -
[ub@lupus ~]$

As you can see here, port 5000 is blocked by a Python process with the process ID (PID) 3801. You can also terminate the process with this numerical ID. That would be:

Terminal window
$ kill 3801

By default, however, kill does not send the KILL signal but TERM. The latter can be understood as a polite request to the process to please terminate. If a KILL is really required because the process no longer responds to TERM, this is also possible:

Terminal window
$ kill -s KILL 3801

or shorter:

Terminal window
$ kill -s 9 3801

Conclusion

The aim of this post is to record my steps in installing Fittrackee at Uberspace. I am posting the text online to share my experiences.

Imprint

Astrid Günther
Sonnenhang 23
56729 Kehrig
Germany
E-Mail: info At astrid-guenther.de

I am looking forward to your requests on the topics I describe here and will answer them as soon as possible!

Privacy

I do not collect or store any personal data via this website. In order to make it possible to call up this site, the internet provider stores some data in server log files which a browser automatically forwards: Browser type and browser version, operating system used, referrer URL, host name of the accessing computer, time of the server request, IP address. The basis for the data processing is Art. 6 (1) DSGVO, which allows the processing of data for the fulfilment of a contract or pre-contractual measures.