TimeTagger logo Pricing Support Log in Sign up
by Almar Klein | published 21-06-2022 | last edited 22-06-2022

← all articles

How to self-host your time tracker with Docker

The focus of this post is running TimeTagger on your own server using the readily available Docker image. For a more in-depth guide on running a modified version of TimeTagger, see this post.

The TimeTagger project

TimeTagger is an open source time tracker that you can run yourself relatively easily. There is also a published Docker image, which makes it very easy to run the app on your server using e.g. Docker Compose.

Docker compose logo

The application

When you have the server up and running, it will serve a simple website and the TimeTagger application. The app's interface is based around an interactive timeline, and is aimed at individuals who want a simple time tracker with powerful features such as easy navigation (also with the keyboard) and solid reporting. You could try the demo to get an idea.

TimeTagger screenshot

Self-host using Docker-compose

Here are the steps to self-host TimeTagger on your own server using Docker-compose.

Step 1: write a docker-compose.yml

You should write a docker-compose file, or include the timetagger service in another compose file. Use the below as a starting point.

version: "3"
services:
  timetagger:
    image: ghcr.io/almarklein/timetagger
    ports:
      - "80:80"
    volumes:
      - ./_timetagger:/root/_timetagger
    environment:
      - TIMETAGGER_BIND=0.0.0.0:80
      - TIMETAGGER_DATADIR=/root/_timetagger
      - TIMETAGGER_LOG_LEVEL=info
      - TIMETAGGER_CREDENTIALS=test:$$2a$$08$$zMsjPEGdXHzsu0N/felcbuWrffsH4.4ocDWY5oijsZ0cbwSiLNA8.  # test:test

The volumes is set so that the databases are saved to persistent storage. The environment shows the possible configuration options. The shown values are the defaults (except for the credentials, which is empty by default).

Step 2: create credentials

You will need to create a string with a BCrypt hash of the password. We provide https://timetagger.app/cred to do this, but you can also use your favourite BCrypt tool. Paste the string to replace the credentials in the docker-compose.yml. These are the credentials that you'll use to log into the TimeTagger app. You can add multiple users this way (separated by commas).

The one gotcha here is that the 3 dollar signs in the hash must be replaced with double-dollar signs ('$$'), otherwise Docker-compose will interpret them as interpolation symbols.

Step 3: deploy

Now you can deploy the service. How this works exactly depends on your personal setup.

Rocket launch

Using a custom startup script

A tip for advanced users. You can use a custom startup script as described here and still use the published Docker image like this:

version: "3"
services:
  timetagger:
    image: ghcr.io/almarklein/timetagger
    volumes:
      - ./_timetagger:/root/_timetagger
      - ./run.py:/root/run.py    # <-- include custom startup script
    command: python run.py       # <-- use that instead of the default entry point
    ...

See e.g. this example.

Self-host using MyPaas

Docker-compose is not the only way to host apps using Docker containers. Alternatives include e.g. Dokku and Swarmpit. As an example, let's have a look what I use to deploy timetagger.app.

MyPaas is a simple tool to create your own PaaS using Traefik and Docker. It allows deploying services using a Dockerfile that contains some additional parameters. A dockerfile to host TimeTagger using the published image would look something like this:

# mypaas.service = timetagger.test1
# mypaas.url = https://test1.timetagger.app
# mypaas.volume = /root/_timetagger:/root/_timetagger
# mypaas.maxmem = 256m
# mypaas.env = TIMETAGGER_CREDENTIALS
FROM ghcr.io/almarklein/timetagger

The credentials can be specified in the Dockerfile, or added as env variables in the MyPaas config file (on the server).

Note on security

When you login, the password is sent unencrypted to the server. It is therefore strongly recommended that your server uses HTTPS, so that it cannot be snooped.