Skip to content

Commit

Permalink
Add ability to run Mycodo in Docker containers (#637)
Browse files Browse the repository at this point in the history
  • Loading branch information
kizniche committed Nov 30, 2019
1 parent 792e03c commit 3564533
Show file tree
Hide file tree
Showing 35 changed files with 2,708 additions and 118 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -15,7 +15,8 @@ before_install:
- influx -database mycodo_db -execute "CREATE USER mycodo WITH PASSWORD 'mmdu77sj3nIoiajjs'"
- export PATH=/usr/bin:$PATH
install:
- sed -i '/picamera/d' install/requirements.txt
- sed -i '/picamera/d' install/requirements-rpi.txt
- pip3 install --upgrade -r install/requirements.txt
- pip3 install --upgrade -r install/requirements-rpi.txt
script:
- cd mycodo && pytest -W ignore::DeprecationWarning -s tests/software_tests
5 changes: 4 additions & 1 deletion CHANGELOG.md
@@ -1,7 +1,10 @@
## 8.1.2 (Unreleased)
## 8.2.0 (Unreleased)

This update brings the ability to run Mycodo/Influxdb in Docker containers, enabling Mycodo to run outside the Raspberry Pi and Raspbian environment. For instance, I currently have Mycodo running on my 64-bit PC in Ubuntu 18.04. This is currently an experimental feature and is not recommended to be used in a production environment. See the [Docker README](https://github.com/kizniche/Mycodo/blob/master/docker/README.md) for more information.

### Features

- Add ability to run Mycodo in Docker containers ([#637](https://github.com/kizniche/mycodo/issues/637))
- Add Dashboard Widget: Spacer ([#717](https://github.com/kizniche/mycodo/issues/717))
- Add ability to hide Widget drag handle, set Widget name font size, and hide Graph Widget buttons ([#717](https://github.com/kizniche/mycodo/issues/717))
- Add ability to set Dashboard grid cell height
Expand Down
18 changes: 18 additions & 0 deletions docker/Dockerfile
@@ -0,0 +1,18 @@
FROM python:3.7-slim-buster

ENV DOCKER_CONTAINER TRUE

RUN useradd -ms /bin/bash pi
RUN useradd -ms /bin/bash mycodo

COPY . /home/mycodo

WORKDIR /home/mycodo/mycodo

RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh create-files-directories
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh update-packages
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh install-docker-ce-cli
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh docker-update-pip
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh docker-update-pip-packages
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh ssl-certs-generate
RUN /home/mycodo/mycodo/scripts/upgrade_commands.sh docker-compile-translations
6 changes: 6 additions & 0 deletions docker/Makefile
@@ -0,0 +1,6 @@
build:
../env/bin/docker-compose up --build -d

clean:
../env/bin/docker-compose down
docker system prune -a
119 changes: 119 additions & 0 deletions docker/README.md
@@ -0,0 +1,119 @@
# Docker

This effort is to get Mycodo running in Docker containers with all features working. many parts of the system work, however there are also many that do not.

***This is currently experimental***

Please do not submit github issues for Docker-related problems.

## Setup

### Notes

This has been tested to work with:

- Raspberry Pi running Raspbian Buster
- 64-bit PC running Ubuntu Linux (18.04, 64-bit)

A Dockerized Mycodo instance cannot run if there is a local install of Mycodo also running. You can stop any local non-Docker Mycodo instances prior to building with the following commands. Note that this will only stop these services until reboot.

```shell script
sudo service mycodo stop
sudo service mycodoflask stop
sudo service nginx stop
```

### Prerequisites

Install prerequisites with the following command.

```shell script
sudo /bin/bash ~/Mycodo/docker/install-dependencies.sh install-dependencies
```

Log out then back in to make the group changes go into effect before attempting to build.

### Build and Start

```shell script
cd ~/Mycodo/docker
make build
```

### Access

#### Mycodo

Mycodo can be accessed at https://127.0.0.1

#### Grafana

Grafana can be accessed at http://127.0.0.1:3000

The default user is admin and the password admin.

## Docker Management

### Stop

```shell script
cd ~/Mycodo/docker
../env/bin/docker-compose down
```

### Clean

```shell script
cd ~/Mycodo/docker
make clean
```

### Disable Grafana and Telegraf

To disable these features (prior to building), just delete or comment out their lines in docker-compose.yml. For example:

```
# telegraf:
# image: telegraf:latest
# container_name: telegraf
# volumes:
# - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
# depends_on:
# - influxdb
# grafana:
# image: grafana/grafana:latest
# container_name: grafana
# ports:
# - "3000:3000"
# env_file:
# - 'grafana/env.grafana'
# volumes:
# - grafana-volume:/var/lib/grafana
# depends_on:
# - influxdb
```

As this part of Mycodo develops, a more elegant solution to disabling these options will form.

## Grafana

For reference, this is the guide used to implement Grafana and Telegraf: https://towardsdatascience.com/get-system-metrics-for-5-min-with-docker-telegraf-influxdb-and-grafana-97cfd957f0ac

### Add Mycodo as a data source

After logging in and changing the admin password, select "Add data source", then "InfluxDB". Enter the following information:

URL: http://influxdb:8086

Database: mycodo_db

User: mycodo

Password: mmdu77sj3nIoiajjs

Click "Save and Test"

### Add Telegraf plugin

Click the plus icon at the top-left, then Import. Enter 914 in the Grafana.com Dashboard field, then click Load. Select any of the InfluxDBs listed for InfluxDB telegraf field, then click Import.
95 changes: 95 additions & 0 deletions docker/docker-compose.yml
@@ -0,0 +1,95 @@
version: "3.7"

services:

influxdb:
container_name: influxdb
build:
context: ../
dockerfile: docker/influxdb/Dockerfile
ports:
- "8083:8083"
- "8086:8086"
- "8090:8090"
env_file:
- 'influxdb/env.influxdb'
volumes:
- influxdb-volume:/var/lib/influxdb
- /etc/localtime:/etc/localtime:ro # Use timezone of the host (read-only)

nginx:
container_name: nginx
restart: always
build:
context: ../
dockerfile: docker/nginx/Dockerfile
volumes:
- home:/home/mycodo
- log:/var/log/mycodo
- /etc/localtime:/etc/localtime:ro # Use timezone of the host (read-only)
ports:
- "80:80"
- "443:443"
depends_on:
- mycodo_flask

mycodo_daemon:
container_name: mycodo_daemon
image: app
restart: always
volumes:
- /dev:/dev
- home:/home/mycodo
- log:/var/log/mycodo
- /etc/localtime:/etc/localtime:ro # Use timezone of the host (read-only)
privileged: true
ports:
- "9090:9090"
command: bash -c "PYTHONPATH=/home/mycodo python mycodo_daemon.py"
depends_on:
- mycodo_flask
- influxdb

mycodo_flask:
container_name: mycodo_flask
image: app
restart: always
build:
context: ../
dockerfile: docker/Dockerfile
volumes:
- /dev:/dev
- home:/home/mycodo
- log:/var/log/mycodo
- /var/run/docker.sock:/var/run/docker.sock:ro # Permits container to restart itself
- /etc/localtime:/etc/localtime:ro # Use timezone of the host (read-only)
privileged: true
command: gunicorn --workers 1 --bind unix:/home/mycodo/mycodoflask.sock start_flask_ui:app
depends_on:
- influxdb

# telegraf:
# image: telegraf:latest
# container_name: telegraf
# volumes:
# - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
# depends_on:
# - influxdb
#
# grafana:
# image: grafana/grafana:latest
# container_name: grafana
# ports:
# - "3000:3000"
# env_file:
# - 'grafana/env.grafana'
# volumes:
# - grafana-volume:/var/lib/grafana
# depends_on:
# - influxdb

volumes:
home:
log:
influxdb-volume:
grafana-volume:
1 change: 1 addition & 0 deletions docker/grafana/env.grafana
@@ -0,0 +1 @@
GF_INSTALL_PLUGINS=grafana-clock-panel,briangann-gauge-panel,natel-plotly-panel,grafana-simple-json-datasource
14 changes: 14 additions & 0 deletions docker/influxdb/Dockerfile
@@ -0,0 +1,14 @@
FROM influxdb:latest

RUN mkdir -pv /var/influxdb/data

ADD docker/influxdb/run.sh /run.sh
RUN chmod +x /*.sh

ENV PRE_CREATE_DB mycodo_db
ENV ADMIN_USER mycodo
ENV PASS mmdu77sj3nIoiajjs

EXPOSE 8086

CMD /run.sh
1 change: 1 addition & 0 deletions docker/influxdb/env.influxdb
@@ -0,0 +1 @@
INFLUXDB_REPORTING_DISABLED=true
55 changes: 55 additions & 0 deletions docker/influxdb/run.sh
@@ -0,0 +1,55 @@
#!/bin/bash

set -m
INFLUX_HOST="influxdb"
INFLUX_API_PORT="8086"
API_URL="http://${INFLUX_HOST}:${INFLUX_API_PORT}"

echo "=> Starting InfluxDB ..."
exec influxd &


# Pre create database on the initiation of the container
if [ -n "${PRE_CREATE_DB}" ]; then
echo "=> About to create the following database: ${PRE_CREATE_DB}"
if [ -f "/var/lib/influxdb/.pre_db_created" ]; then
echo "=> Database had been created before, skipping ..."
else
arr=$(echo ${PRE_CREATE_DB} | tr ";" "\n")

#wait for the startup of influxdb
RET=1
while [[ RET -ne 0 ]]; do
echo "=> Waiting for confirmation of InfluxDB service startup ..."
sleep 3
curl -k ${API_URL}/ping 2> /dev/null
RET=$?
done
echo ""

PASS=${INFLUXDB_INIT_PWD:-root}
if [ -n "${ADMIN_USER}" ]; then
echo "=> Creating admin user"
influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -execute="CREATE USER ${ADMIN_USER} WITH PASSWORD '${PASS}' WITH ALL PRIVILEGES"
for x in $arr
do
echo "=> Creating database: ${x}"
influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -username=${ADMIN_USER} -password="${PASS}" -execute="create database ${x}"
influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -username=${ADMIN_USER} -password="${PASS}" -execute="grant all PRIVILEGES on ${x} to ${ADMIN_USER}"
done
echo ""
else
for x in $arr
do
echo "=> Creating database: ${x}"
influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -execute="create database \"${x}\""
done
fi

touch "/var/lib/influxdb/.pre_db_created"
fi
else
echo "=> No database need to be pre-created"
fi

fg

0 comments on commit 3564533

Please sign in to comment.