feat(traccar): Initial commit

This commit is contained in:
hygienic-books 2023-06-25 00:33:01 +02:00
parent 41c25a6f60
commit 0c1dcb3fcf
17 changed files with 282 additions and 2 deletions

127
README.md
View File

@ -1,3 +1,126 @@
# traccar # Traccar Docker Compose files
Docker Compose files to spin up an instance of Traccar 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=<add accordingly>
```
## 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).

View File

@ -0,0 +1,4 @@
ARG MYSQL_VERSION
FROM "mysql:${MYSQL_VERSION}"
RUN mkdir -p /tmp/mysql

View File

View File

@ -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

View File

View File

@ -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/*

View File

@ -0,0 +1,26 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'>
<properties>
<entry key='config.default'>./conf/default.xml</entry>
<!--
This is the main configuration file. All your configuration parameters should be placed in this file.
Default configuration parameters are located in the "default.xml" file. You should not modify it to avoid issues
with upgrading to a new version. Parameters in the main config file override values in the default file. Do not
remove "config.default" parameter from this file unless you know what you are doing.
For list of available parameters see following page: https://www.traccar.org/configuration-file/
-->
<entry key='database.driver'>com.mysql.cj.jdbc.Driver</entry>
<entry key='database.url'>jdbc:mysql://mysql/traccar?zeroDateTimeBehavior=round&amp;serverTimezone=UTC&amp;allowPublicKeyRetrieval=true&amp;useSSL=false&amp;allowMultiQueries=true&amp;autoReconnect=true&amp;useUnicode=yes&amp;characterEncoding=UTF-8&amp;sessionVariables=sql_mode=''</entry>
<entry key='database.user'>traccar</entry>
<entry key='database.password'>t0psecret</entry>
</properties>

View File

11
common-settings.yml Normal file
View File

@ -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}"

View File

@ -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}"

61
docker-compose.yml Normal file
View File

@ -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}

18
env/fqdn_context.env.example vendored Normal file
View File

@ -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