From 0c1dcb3fcf8c68c4c7412a6cca02f3bef1350e32 Mon Sep 17 00:00:00 2001 From: hygienic-books Date: Sun, 25 Jun 2023 00:33:01 +0200 Subject: [PATCH] feat(traccar): Initial commit --- README.md | 127 +++++++++++++++++- build-context/mysql/Dockerfile | 4 + build-context/mysql/docker-data/.gitkeep | 0 .../mysql/docker-data/config/db/my.cnf | 6 + .../docker-entrypoint-initdb.d/.gitkeep | 0 .../mysql/docker-data/data/datadir/.gitkeep | 0 .../mysql/docker-data/data/tmpdir/.gitkeep | 0 build-context/mysql/extras/.gitkeep | 0 build-context/traccar/Dockerfile | 14 ++ build-context/traccar/docker-data/.gitkeep | 0 .../traccar/docker-data/config/traccar.xml | 26 ++++ .../traccar/docker-data/data/.gitkeep | 0 build-context/traccar/extras/.gitkeep | 0 common-settings.yml | 11 ++ docker-compose.override.yml | 17 +++ docker-compose.yml | 61 +++++++++ env/fqdn_context.env.example | 18 +++ 17 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 build-context/mysql/Dockerfile create mode 100644 build-context/mysql/docker-data/.gitkeep create mode 100644 build-context/mysql/docker-data/config/db/my.cnf create mode 100644 build-context/mysql/docker-data/config/docker-entrypoint-initdb.d/.gitkeep create mode 100644 build-context/mysql/docker-data/data/datadir/.gitkeep create mode 100644 build-context/mysql/docker-data/data/tmpdir/.gitkeep create mode 100644 build-context/mysql/extras/.gitkeep create mode 100644 build-context/traccar/Dockerfile create mode 100644 build-context/traccar/docker-data/.gitkeep create mode 100644 build-context/traccar/docker-data/config/traccar.xml create mode 100644 build-context/traccar/docker-data/data/.gitkeep create mode 100644 build-context/traccar/extras/.gitkeep create mode 100644 common-settings.yml create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml create mode 100644 env/fqdn_context.env.example diff --git a/README.md b/README.md index 6885564..67be2df 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,126 @@ -# traccar +# Traccar Docker Compose files -Docker Compose files to spin up an instance of Traccar \ No newline at end of file +Docker Compose files to spin up an instance of Traccar. + +# How to run + +Add a `COMPOSE_ENV` file and save its location as a shell variable along with the location where this repo lives, here for example `/opt/containers/traccar` plus all other variables. At [env/fqdn_context.env.example](env/fqdn_context.env.example) you'll find an example environment file. + +When everything's ready start Traccar with Docker Compose, otherwise head down to [Initial setup](#initial-setup) first. + +## Environment +``` +export COMPOSE_DIR='/opt/containers/traccar' +export COMPOSE_CTX='ux_vilnius' +export COMPOSE_PROJECT='traccar-'"${COMPOSE_CTX}" +export COMPOSE_FILE="${COMPOSE_DIR}"'/docker-compose.yml' +export COMPOSE_OVERRIDE="${COMPOSE_DIR%/}"'/docker-compose.override.yml' +export COMPOSE_ENV= +``` + +## Context + +On your deployment machine create the necessary Docker context to connect to and control the Docker daemon on whatever target host you'll be using, for example: +``` +docker context create fully.qualified.domain.name --docker 'host=ssh://root@fully.qualified.domain.name' +``` + +## Build + +We build only MySQL. Our local adjustment to the official image is simply adding `/tmp/mysql` to it. See [build-context/mysql/Dockerfile](build-context/mysql/Dockerfile). We use `/tmp/mysql` to bind-mount a dedicated ZFS dataset for MySQL `tmpdir` location. + +``` +docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE}" --env-file "${COMPOSE_ENV}" --profile 'build-mysql' build +``` + +## Pull + +The Traccar image is just pulled from Docker Hub verbatim. + +``` +docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'traccar' pull +``` + +## Copy to target + +Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub. Copying in its simplest form involves a local `docker save` and a remote `docker load`. Consider the helper mini-project [quico.space/Quico/copy-docker](https://quico.space/Quico/copy-docker) where [copy-docker.sh](https://quico.space/Quico/copy-docker/src/branch/main/copy-docker.sh) allows the following workflow: + +``` +source "${COMPOSE_ENV}" +for image in 'mysql:'"${MYSQL_VERSION}" 'traccar/traccar:'"${TRACCAR_VERSION}"; do + copy-docker.sh "${image}" fully.qualified.domain.name +done +``` + +## Start + +``` +docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach +``` + +# Initial setup + +We're assuming you run Docker Compose workloads with ZFS-based bind mounts. ZFS management, creating a zpool and setting adequate properties for its datasets is out of scope of this document. + +## Datasets + +Create ZFS datasets and set permissions as needed. + +* Parent dateset + ``` + zfs create -o mountpoint=/opt/docker-data 'zpool/docker-data' + ``` + +* Container-specific datasets + ``` + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/traccar/data/data' + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/traccar/data/logs' + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/traccar/config' + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/mysql/data/datadir' + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/mysql/data/tmpdir' + zfs create -p 'zpool/docker-data/traccar-'"${COMPOSE_CTX}"'/mysql/config' + ``` + +* Create subdirs + ``` + mkdir -p '/opt/docker-data/traccar-'"${COMPOSE_CTX}"'/mysql/config/'{'docker-entrypoint-initdb.d','db'} + ``` + +* Change ownership for MySQL daemon + ``` + chown -R 999:999 '/opt/docker-data/traccar-'"${COMPOSE_CTX}"'/mysql/'{*,.*} + ``` + +## Additional files + +Place the following files on target server. Use the directory structure at [build-context](build-context) as a guide, specifically at `docker-data`. + +``` +build-context/ +├── mysql +│   ├── docker-data +│   │   ├── config +│   │   │   ├── db +│   │   │   │   └── my.cnf +│   │   │   └── docker-entrypoint-initdb.d +│   │   └── data +│   │   ├── datadir +│   │   └── tmpdir +│   ├── ... +│   └── ... +└── traccar + ├── docker-data + │   ├── config + │   │   └── traccar.xml + │   └── data + ├── ... + └── ... +``` + +The [example my.cnf](build-context/mysql/docker-data/config/db/my.cnf) config file for MySQL follows [Traccar's recommendation for MySQL](https://www.traccar.org/mysql-optimization/) but uses 512 MiB of RAM instead of Traccar's 3 GiB example. We also add a `tmpdir` whose location gets created in our custom MySQL image up top during [Build](#build). Lastly since we live in a world with MySQL 8.0.30+ we're using `innodb_redo_log_capacity` over Traccar's recommendation (as of Thursday, June 22, 2023) of `innodb_log_file_size`. See also [MySQL 8.0 docs section "Configuring Redo Log Capacity (MySQL 8.0.30 or Higher)"](https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html#innodb-modifying-redo-log-capacity). + +In `docker-entrypoint-initdb.d` you can store database initialization scripts that are run when you start MySQL without any data. See also [MySQL 8.0 docs section "Running Additional Initialization Scripts"](https://dev.mysql.com/doc/refman/8.0/en/docker-mysql-more-topics.html#docker-additional-init). + +Config `traccar.xml` is a minimal working example file taken from the Traccar Docker image. See [Docker Hub traccar/traccar overview](https://hub.docker.com/r/traccar/traccar) section "Get default traccar.xml". In [our example traccar.xml](build-context/traccar/docker-data/config/traccar.xml) file the default H2 database is replaced with MySQL to match this repo. + +When done head back up to [How to run](#how-to-run). diff --git a/build-context/mysql/Dockerfile b/build-context/mysql/Dockerfile new file mode 100644 index 0000000..749761f --- /dev/null +++ b/build-context/mysql/Dockerfile @@ -0,0 +1,4 @@ +ARG MYSQL_VERSION + +FROM "mysql:${MYSQL_VERSION}" +RUN mkdir -p /tmp/mysql diff --git a/build-context/mysql/docker-data/.gitkeep b/build-context/mysql/docker-data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/mysql/docker-data/config/db/my.cnf b/build-context/mysql/docker-data/config/db/my.cnf new file mode 100644 index 0000000..1c4478d --- /dev/null +++ b/build-context/mysql/docker-data/config/db/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +innodb_buffer_pool_size = 512M +innodb_redo_log_capacity = 512M +innodb_flush_method = O_DIRECT +innodb_flush_log_at_trx_commit = 0 +tmpdir = /tmp/mysql diff --git a/build-context/mysql/docker-data/config/docker-entrypoint-initdb.d/.gitkeep b/build-context/mysql/docker-data/config/docker-entrypoint-initdb.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/mysql/docker-data/data/datadir/.gitkeep b/build-context/mysql/docker-data/data/datadir/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/mysql/docker-data/data/tmpdir/.gitkeep b/build-context/mysql/docker-data/data/tmpdir/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/mysql/extras/.gitkeep b/build-context/mysql/extras/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/traccar/Dockerfile b/build-context/traccar/Dockerfile new file mode 100644 index 0000000..042ad99 --- /dev/null +++ b/build-context/traccar/Dockerfile @@ -0,0 +1,14 @@ +# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be +# available with a value of 'must_be_available_in_dockerfile', check out the env +# file at 'env/fully.qualified.domain.name.example' for reference. +# ARG EXAMPLE_ARG_FOR_DOCKERFILE + +# Another env var, this one's needed in the example build step below: +# ARG TRACCAR_VERSION + +# Example +# FROM "traccar:${TRACCAR_VERSION}" +# RUN apt-get update && \ +# apt-get -y install \ +# somepackage-6.q16-6-extra && \ +# rm -rf /var/lib/apt/lists/* diff --git a/build-context/traccar/docker-data/.gitkeep b/build-context/traccar/docker-data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/traccar/docker-data/config/traccar.xml b/build-context/traccar/docker-data/config/traccar.xml new file mode 100644 index 0000000..331f1b1 --- /dev/null +++ b/build-context/traccar/docker-data/config/traccar.xml @@ -0,0 +1,26 @@ + + + + + + + ./conf/default.xml + + + + com.mysql.cj.jdbc.Driver + jdbc:mysql://mysql/traccar?zeroDateTimeBehavior=round&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&sessionVariables=sql_mode='' + traccar + t0psecret + + diff --git a/build-context/traccar/docker-data/data/.gitkeep b/build-context/traccar/docker-data/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/build-context/traccar/extras/.gitkeep b/build-context/traccar/extras/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/common-settings.yml b/common-settings.yml new file mode 100644 index 0000000..9fd26d7 --- /dev/null +++ b/common-settings.yml @@ -0,0 +1,11 @@ +services: + common-settings: + environment: + TZ: "${TIMEZONE:-Etc/UTC}" + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "10" + compress: "true" + restart: "${RESTARTPOLICY:-unless-stopped}" diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..8ea48d3 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,17 @@ +services: + traccar-build: + image: "traccar/traccar:${TRACCAR_VERSION}" + profiles: ["build", "build-traccar"] + build: + context: "build-context/traccar" + dockerfile: Dockerfile + args: + TRACCAR_VERSION: "${TRACCAR_VERSION}" + mysql-build: + image: "mysql:${MYSQL_VERSION}" + profiles: ["build", "build-mysql"] + build: + context: "build-context/mysql" + dockerfile: Dockerfile + args: + MYSQL_VERSION: "${MYSQL_VERSION}" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..190d0fa --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,61 @@ +services: + traccar: + image: "traccar/traccar:${TRACCAR_VERSION}" + container_name: "traccar-traccar-${CONTEXT}" + networks: + traccar-default: + profiles: ["full", "traccar"] + ulimits: + nproc: ${ULIMIT_NPROC-65535} + nofile: + soft: ${ULIMIT_NPROC-65535} + hard: ${ULIMIT_NPROC-65535} + extends: + file: common-settings.yml + service: common-settings + ports: + - "${TRACCAR_WEBUI_PORT}:8082" + - "${TRACCAR_GPS_PORT_EXTERNAL}:${TRACCAR_GPS_PORT_INTERNAL}" + volumes: + - /opt/docker-data/traccar-${CONTEXT}/traccar/config/traccar.xml:/opt/traccar/conf/traccar.xml:ro + - /opt/docker-data/traccar-${CONTEXT}/traccar/data/data:/opt/traccar/data:rw + - /opt/docker-data/traccar-${CONTEXT}/traccar/data/logs:/opt/traccar/logs:rw + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + mysql: + image: "mysql:${MYSQL_VERSION}" + container_name: "traccar-mysql-${CONTEXT}" + networks: + traccar-default: + profiles: ["full", "mysql"] + ulimits: + nproc: ${ULIMIT_NPROC-65535} + nofile: + soft: ${ULIMIT_NPROC-65535} + hard: ${ULIMIT_NPROC-65535} + extends: + file: common-settings.yml + service: common-settings + ports: + - "${MYSQL_PORT}:3306" + volumes: + - /opt/docker-data/traccar-${CONTEXT}/mysql/config/db:/etc/mysql/conf.d + - /opt/docker-data/traccar-${CONTEXT}/mysql/config/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - /opt/docker-data/traccar-${CONTEXT}/mysql/data/datadir:/var/lib/mysql + - /opt/docker-data/traccar-${CONTEXT}/mysql/data/tmpdir:/tmp/mysql + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST} +networks: + traccar-default: + name: traccar-${CONTEXT} + driver: bridge + driver_opts: + com.docker.network.enable_ipv6: "false" + ipam: + driver: default + config: + - subnet: ${SUBNET} diff --git a/env/fqdn_context.env.example b/env/fqdn_context.env.example new file mode 100644 index 0000000..e017524 --- /dev/null +++ b/env/fqdn_context.env.example @@ -0,0 +1,18 @@ +CONTEXT=ux_vilnius +MYSQL_DATABASE=traccar +MYSQL_PASSWORD=t0psecr3t +MYSQL_PORT=33006 +MYSQL_ROOT_HOST=172.16.0.0/12 +MYSQL_ROOT_PASSWORD=Alsot0psecr3t +MYSQL_USER=traccar +MYSQL_VERSION=latest +SUBNET=172.24.10.0/24 +TRACCAR_GPS_PORT_EXTERNAL=61000 +TRACCAR_GPS_PORT_INTERNAL=5008 +TRACCAR_VERSION=latest +TRACCAR_WEBUI_PORT=8080 +ULIMIT_NPROC=65535 + +# Other available defaults +# RESTARTPOLICY=unless-stopped +# TIMEZONE=Etc/UTC