Teslamate: docker-compose example for a public setup (SSL, FQDN, pw protected)

Created on 7 Sep 2019  ·  52Comments  ·  Source: adriankumpf/teslamate

Hey everyone,

not sure if we're supposed to post example setups here but in absence of a better place to do so I thought I'd just do it ;)

This is what currently works for me as a publicly reachable setup. Publicly reachable here means it's installed on a VPS that is out in the open. So if you use this setup be aware of that.

What is differentl:

  • everything sits behind a reverse proxy that also acts as an SSL terminator (Traefik)
  • some services are renamed
  • every custom setting in the compose file is put to an env file
  • everything publicly accessible uses an FQDN (Fully qualified domain name) and automatically acquires a Let's Encrypt certificate.

What you need to do before running it:

  • Setup your custom stuff in the .env file and put it in the same directory as the docker-compose.yml
  • create a directory called 'acme' in the same directory. this is where your SSL cert information will be stored
  • create a .htpasswd file in your directory containing user and password for the teslamate settings access. You can do it on the web if you don't have apache tools installed (e.g. http://www.htaccesstools.com/htpasswd-generator/)

What is still to be done:

  • Mosquitto isn't publicly reachable (as I don't need it to be). I don't use it all though so I'm not even sure if it needs to be accessible.

_docker-compose.yml_

version: '3'

networks:
  proxynet:
    driver: bridge
  webgateway:
    external: true

services:
  teslamate:
    image: teslamate/teslamate:latest
    restart: unless-stopped
    depends_on:
      - database
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
      - VIRTUAL_HOST=${FQDN_TM}
      - TZ={$TM_TZ}
    networks:
      - proxynet  
    ports:
      - 4000
    cap_drop:
      - all
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet' # you need to change pd_ to something else if you use a different stack name when starting
      - 'traefik.port=4000'
      - 'traefik.backend=teslamate'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.frontend.rule=Host:${FQDN_TM}' # change this to your hostname. That hostname needs to point to your server
      - 'traefik.domain=${FQDN_TM}' # change this to your hostname. That hostname needs to point to your server
      - 'traefik.frontend.auth.basic.usersFile=/auth/.htpasswd'

  database:
    image: postgres:11
    environment:
      - POSTGRES_USER=${TM_DB_USER}
      - POSTGRES_PASSWORD=${TM_DB_PASS}
      - POSTGRES_DB=${TM_DB_NAME}
    volumes:
      - teslamate-db:/var/lib/postgresql/data
    networks:
      - proxynet
    ports:
      - 5432

  grafana:
    image: teslamate/grafana:latest
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - GRAFANA_PASSWD=${GRAFANA_PW}
      - GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PW}
      - GF_AUTH_BASIC_ENABLED=true
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SERVER_ROOT_URL=https://${FQDN_GRAFANA}
    networks:
      - proxynet
    ports:
      - 3000
    volumes:
      - teslamate-grafana-data:/var/lib/grafana
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet' # you need to change pd_ to something else if you use a different stack name when starting
      - 'traefik.port=3000'
      - 'traefik.backend=grafana'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.frontend.rule=Host:${FQDN_GRAFANA}' # change this to your hostname. That hostname needs to point to your server
      - 'traefik.domain=${FQDN_GRAFANA}' # change this to your hostname. That hostname needs to point to your server

  mosquitto:
    image: eclipse-mosquitto:1.6
    networks:
      - proxynet
    ports:
      - 1883
      - 9001
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

  proxy:
    image: traefik
    restart: always
    command:
      - '--loglevel=WARN'
      - '--api'
      # - "--entrypoints=Name:http Address::80"
      - '--entrypoints=Name:http Address::80 Redirect.EntryPoint:https'
      - '--entrypoints=Name:https Address::443 TLS'
      - '--defaultentrypoints=http,https'
      - '--acme'
      - '--acme.storage=/etc/acme/acme.json'
      - '--acme.entryPoint=https'
      - '--acme.onHostRule=true'
      - '--acme.httpChallenge'
      - '--acme.httpChallenge.entryPoint=http'
      - '--acme.email=${LETSENCRYPT_EMAIL}'
      ## comment out the next line to request a real certificate
      #- "--acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # uncomment this line if you want to test the lets encrypt certificate generation
      - '--docker'
      - '--docker.exposedByDefault=false'
      - '--docker.endpoint=unix:///var/run/docker.sock'
      - '--docker.watch'
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./.htpasswd:/auth/.htpasswd
      - ./acme/:/etc/acme/
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxynet
      - webgateway

volumes:
    teslamate-db:
    teslamate-grafana-data:
    mosquitto-conf:
    mosquitto-data:

_.env file_

COMPOSE_PROJECT_NAME=tm

[email protected]

TM_DB_USER=yourdbuser
TM_DB_PASS=yourdbpass
TM_DB_NAME=yourdbname
TM_TZ=Europe/Berlin

GRAFANA_USER=youruser
GRAFANA_PW=yoursupersecretpw

FQDN_GRAFANA=your.host.for.grafana.com
FQDN_TM=your.host.for.teslamate.com
WIP discussion guide

All 52 comments

just edited the original post and added password protection for tesla mate to not have that exposed publicly.

This is awesome - thank you - something been wanting to do and will try it out and ping back!

Awesome setup! Thank you very much for sharing. If you don't mind, I'd create an entry in the wiki with your _docker-compose.yml_?

Sure, feel free to take and modify or whatever is needed.

@adriankumpf I updated the compose file to allow PUT requests to the API to resume and suspend logging. Again widely untested. I get a 404 now instead of a 401 before but not sure if the 404 is due to the missing car (😥) or if something else isnt' working right but I think it should be the right approach.

Also removed some old stupid comments that I copied over from another file and that are not really needed here.

version: '3'

networks:
  proxynet:
    driver: bridge
  webgateway:
    external: true

services:
  teslamate:
    image: teslamate/teslamate:latest
    restart: unless-stopped
    depends_on:
      - database
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
      - VIRTUAL_HOST=${FQDN_TM}
      - TZ={$TM_TZ}
    networks:
      - proxynet  
    ports:
      - 4000
    cap_drop:
      - all
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet'
      - 'traefik.port=4000'
      - 'traefik.backend=teslamate'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.domain=${FQDN_TM}'
      - 'traefik.frontend.rule=Method:GET,POST,Host:${FQDN_TM}'
      - 'traefik.frontend.auth.basic.usersFile=/auth/.htpasswd'
      - 'traefik.frontendapi.rule=Method:PUT,Host:${FQDN_TM}'

  database:
    image: postgres:11
    environment:
      - POSTGRES_USER=${TM_DB_USER}
      - POSTGRES_PASSWORD=${TM_DB_PASS}
      - POSTGRES_DB=${TM_DB_NAME}
    volumes:
      - teslamate-db:/var/lib/postgresql/data
    networks:
      - proxynet
    ports:
      - 5432

  grafana:
    image: teslamate/grafana:latest
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - GRAFANA_PASSWD=${GRAFANA_PW}
      - GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PW}
      - GF_AUTH_BASIC_ENABLED=true
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SERVER_ROOT_URL=https://${FQDN_GRAFANA}
    networks:
      - proxynet
    ports:
      - 3000
    volumes:
      - teslamate-grafana-data:/var/lib/grafana
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet'
      - 'traefik.port=3000'
      - 'traefik.backend=grafana'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.frontend.rule=Host:${FQDN_GRAFANA}'
      - 'traefik.domain=${FQDN_GRAFANA}'

  mosquitto:
    image: eclipse-mosquitto:1.6
    networks:
      - proxynet
    ports:
      - 1883
      - 9001
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

  proxy:
    image: traefik
    restart: always
    command:
      - '--loglevel=WARN'
      - '--api'
      # - "--entrypoints=Name:http Address::80"
      - '--entrypoints=Name:http Address::80 Redirect.EntryPoint:https'
      - '--entrypoints=Name:https Address::443 TLS'
      - '--defaultentrypoints=http,https'
      - '--acme'
      - '--acme.storage=/etc/acme/acme.json'
      - '--acme.entryPoint=https'
      - '--acme.onHostRule=true'
      - '--acme.httpChallenge'
      - '--acme.httpChallenge.entryPoint=http'
      - '--acme.email=${LETSENCRYPT_EMAIL}'
      ## remove the comment for the following line to only send certificate requests to the sandbox service (for testing)
      #- "--acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # uncomment this line if you want to test the lets encrypt certificate generation
      - '--docker'
      - '--docker.exposedByDefault=false'
      - '--docker.endpoint=unix:///var/run/docker.sock'
      - '--docker.watch'
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./.htpasswd:/auth/.htpasswd
      - ./acme/:/etc/acme/
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxynet
      - webgateway

volumes:
    teslamate-db:
    teslamate-grafana-data:
    mosquitto-conf:
    mosquitto-data:

Thanks, I'll update the wiki accordingly! The 404 indicates that it's indeed working correctly 👍

What is the Tasker command for this Config?

@Sebbo69 you just need to adjust the URL to the (sub)domain name you are using for the logger. Nothing special otherwise.

your.host.for.teslamate.com:4000/api/car/1/logging/resume has no funktion

and with this config i dont have access to grafana.
with this message:

[error] Could not check origin for Phoenix.Socket transport.

Can I use this on a host, where ports 80 and 443 are already in use otherwise?

@Sebbo69 this setup is meant to run with FQDNs and you don't need a port. You need to set your subdomain name in the config and each (grafana and Teslamate) gets its own subdomain.

@DrMichael you can but you nede to modify the config accordingly. By default it's meant to run on 80 for the SSL retrieval and 443 for https.

Yes I have 2 subdomains. One grafana. Xxxx.xx and other teslamate. Xxx. Xx

ok, just remove the port from your URL then - you don't need it anymore. If you followed the instructions you will need to enter the password but if you do a PUT request it won't need a password against the API.

Problem is, with both sub it will come to teslamate setup site. Not to grafana.

@Helmi Ok, we have ports 80, 443, 3000, 4000 then open?
3000 for Grafana
4000 for Teslamate
80/443 for what?

@DrMichael this setup uses SSL for all the web access. no 3000, no 4000. One subdomain for Grafana, one for Teslamate. Everything on 443. Port 80 is used for the (automatic) SSL retrieval process. If you don't want to use 80/443 this is just not the right setup for you - use the default docker-compose file instead. This is more what you're looking for.

@Sebbo69 are you sure your subdomains are configured the right way and you got your .env file right and in place? Be sure to check the log output of the proxy and check for error output on the console when you start it. If you setup your hostnames in the .env file and the subdomains are configured to point to your server it should work.

Yes, at logfile are errors because the wrong Domain for the setup Page. Both sub.domains going in the same IP. I have double checked and complete New setup. I have no idea

If you want send me your files by email and I can have a look at it - apart from that it's hard for me to help.

github(at)helmilectric.com

Okay, in 30 min.

@DrMichael this setup uses SSL for all the web access. no 3000, no 4000. One subdomain for Grafana, one for Teslamate. Everything on 443. Port 80 is used for the (automatic) SSL retrieval process. If you don't want to use 80/443 this is just not the right setup for you - use the default docker-compose file instead. This is more what you're looking for.

Ah, ok...

@adriankumpf the last docker-compose had a bug that would make grafana inaccessible. Thanks to @Sebbo69 I got aware of that and was able to fix it at least for my empty installation (still 8 days to go 🤤).

Here's the latest version. Maybe wait for confirmation from @Sebbo69 later today before you put it on the wiki.

version: '3'

networks:
  proxynet:
    driver: bridge
  webgateway:
    external: true

services:
  teslamate:
    image: teslamate/teslamate:latest
    restart: unless-stopped
    depends_on:
      - database
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
      - VIRTUAL_HOST=${FQDN_TM}
      - TZ={$TM_TZ}
    networks:
      - proxynet  
    ports:
      - 4000
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet'
      - 'traefik.port=4000'
      - 'traefik.backend=teslamate'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.domain=${FQDN_TM}'
      - 'traefik.tm.frontend.rule=Method:GET,POST;Host:${FQDN_TM}'
      - 'traefik.tm.frontend.auth.basic.usersFile=/auth/.htpasswd'
      - 'traefik.tmapi.frontend.rule=Method:PUT;Host:${FQDN_TM}'
  database:
    image: postgres:11
    environment:
      - POSTGRES_USER=${TM_DB_USER}
      - POSTGRES_PASSWORD=${TM_DB_PASS}
      - POSTGRES_DB=${TM_DB_NAME}
    volumes:
      - teslamate-db:/var/lib/postgresql/data
    networks:
      - proxynet
    ports:
      - 5432

  grafana:
    image: teslamate/grafana:latest
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - GRAFANA_PASSWD=${GRAFANA_PW}
      - GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PW}
      - GF_AUTH_BASIC_ENABLED=true
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SERVER_ROOT_URL=https://${FQDN_GRAFANA}
    networks:
      - proxynet
    ports:
      - 3000
    volumes:
      - teslamate-grafana-data:/var/lib/grafana
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=${COMPOSE_PROJECT_NAME}_proxynet'
      - 'traefik.port=3000'
      - 'traefik.backend=grafana'
      - 'traefik.backend.loadbalancer.method=drr'
      - 'traefik.frontend.rule=Host:${FQDN_GRAFANA}'
      - 'traefik.domain=${FQDN_GRAFANA}'

  mosquitto:
    image: eclipse-mosquitto:1.6
    networks:
      - proxynet
    ports:
      - 1883
      - 9001
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

  proxy:
    image: traefik
    restart: always
    command:
      - '--loglevel=WARN'
      - '--entrypoints=Name:http Address::80 Redirect.EntryPoint:https'
      - '--entrypoints=Name:https Address::443 TLS'
      - '--defaultentrypoints=http,https'
      - '--acme'
      - '--acme.storage=/etc/acme/acme.json'
      - '--acme.entryPoint=https'
      - '--acme.onHostRule=true'
      - '--acme.httpChallenge'
      - '--acme.httpChallenge.entryPoint=http'
      - '--acme.email=${LETSENCRYPT_EMAIL}'
      ## remove the comment for the following line to only send certificate requests to the sandbox service (for testing)
      #- "--acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # uncomment this line if you want to test the lets encrypt certificate generation
      - '--docker'
      - '--docker.exposedByDefault=false'
      - '--docker.endpoint=unix:///var/run/docker.sock'
      - '--docker.watch'
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./.htpasswd:/auth/.htpasswd
      - ./acme/:/etc/acme/
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxynet
      - webgateway

volumes:
    teslamate-db:
    teslamate-grafana-data:
    mosquitto-conf:
    mosquitto-data:

Thanks @Helmi!

I tried to set it up myself and noticed that v2 of traefik will be released shortly. It has a lot of breaking changes and configuring e.g. HTTP redirects is more verbose but overall it makes a things easier. That's the config I came up with (based on your previous one):

version: '3'

services:
  teslamate:
    image: teslamate/teslamate:latest
    restart: unless-stopped
    depends_on:
      - database
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
      - VIRTUAL_HOST=${FQDN_TM}
      - TZ={$TM_TZ}
    labels:
      - 'traefik.enable=true'
      - 'traefik.port=4000'
      - "traefik.http.middlewares.redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.auth.basicauth.usersfile=/auth/.htpasswd"
      - "traefik.http.routers.teslamate-insecure.rule=Host(`${FQDN_TM}`)"
      - "traefik.http.routers.teslamate-insecure.middlewares=redirect"
      - "traefik.http.routers.teslamate.rule=Host(`${FQDN_TM}`)"
      - "traefik.http.routers.teslamate.middlewares=auth"
      - "traefik.http.routers.teslamate.entrypoints=websecure"
      - "traefik.http.routers.teslamate.tls.certresolver=tmhttpchallenge"

  database:
    image: postgres:11
    environment:
      - POSTGRES_USER=${TM_DB_USER}
      - POSTGRES_PASSWORD=${TM_DB_PASS}
      - POSTGRES_DB=${TM_DB_NAME}
    volumes:
      - teslamate-db:/var/lib/postgresql/data

  grafana:
    image: teslamate/grafana:latest
    environment:
      - DATABASE_USER=${TM_DB_USER}
      - DATABASE_PASS=${TM_DB_PASS}
      - DATABASE_NAME=${TM_DB_NAME}
      - DATABASE_HOST=database
      - GRAFANA_PASSWD=${GRAFANA_PW}
      - GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PW}
      - GF_AUTH_BASIC_ENABLED=true
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SERVER_ROOT_URL=https://${FQDN_GRAFANA}
    volumes:
      - teslamate-grafana-data:/var/lib/grafana
    labels:
      - 'traefik.enable=true'
      - 'traefik.port=3000'
      - "traefik.http.middlewares.redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.grafana-insecure.rule=Host(`${FQDN_GRAFANA}`)"
      - "traefik.http.routers.grafana-insecure.middlewares=redirect"
      - "traefik.http.routers.grafana.rule=Host(`${FQDN_GRAFANA}`)"
      - "traefik.http.routers.grafana.entrypoints=websecure"
      - "traefik.http.routers.grafana.tls.certresolver=tmhttpchallenge"

  mosquitto:
    image: eclipse-mosquitto:1.6
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

  proxy:
    image: traefik:v2.0
    command:
      - "--global.sendAnonymousUsage=false"
      - "--providers.docker"
      - "--providers.docker.exposedByDefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.tmhttpchallenge.acme.httpchallenge=true"
      - "--certificatesresolvers.tmhttpchallenge.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.tmhttpchallenge.acme.email=${LETSENCRYPT_EMAIL}"
      - "--certificatesresolvers.tmhttpchallenge.acme.storage=/etc/acme/acme.json"
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./.htpasswd:/auth/.htpasswd
      - ./acme/:/etc/acme/
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
    teslamate-db:
    teslamate-grafana-data:
    mosquitto-conf:
    mosquitto-data:

That's interesting, thanks for putting that up. I didn't yet look at V2. Did you also get PUT requests workign without auth in that? Couldn't find anything that hints to it hence the question.

That's not done yet. Another way around this would be to include the username and password in the URL e.g. https://username:[email protected]/ when sending PUT requests.

Probably depends on the client if it still works but most clients don't support this anymore - especially with SSL encrypted connections. But maybe a good challenge to get it done the v2 way.

Ah, okay. Yeah, let's see how this can be done with v2.

Sorry for the newbie question - can I update my 'regular' docker-compose (which is already running) with this one and then would it pick up the existing container, and DB and data, etc? Or does one need to start from scratch?

Thanks.

docker-compose down
docker-compose pull
docker-compose up -d

On Sun, Sep 29, 2019 at 11:25 AM Amit Bahree notifications@github.com
wrote:

Sorry for the newbie question - can I update my 'regular' docker-compose
(which is already running) with this one and then would it pick up the
existing container, and DB and data, etc? Or does one need to start from
scratch?

Thanks.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/adriankumpf/teslamate/issues/153?email_source=notifications&email_token=AALCLTJP4UT53ZZ2IEVYPO3QMDCHTA5CNFSM4IUQCAS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD73XWQQ#issuecomment-536312642,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AALCLTOY3AE5PUBLGP5K5S3QMDCHTANCNFSM4IUQCASQ
.

The latest update to Traefik (v1.7.18) seems to have made Grafana inaccessible using the latest docker-compose. Anyone have any suggestions?

@Helmi @adriankumpf Thanks for this guide. I got the original version up and running with a VPN.
While it works reasonably well - i'd prefer not needing to run a VPN for this service to work. That said I'm not very familiar with networking - so I'm wondering if you can clarify a few steps.

  1. I recently signed up to Dynu.com to get a ddns hostname (eg xyz123.dynu.com which mirrors my local IP of 123.456.789.321)
  2. Teslamate will be run on an Ubuntu VM with LAN Address of 192.168.86.51

This is where I get lost :

  1. What ports do I need to forward on my router to make this all work (80/443 for 192.168.86.51)?
  2. What is the FQDN_GRAFANA, FQDN_TM? @Helmi mentioned creating subdomains - but I'm unclear how to set this. Do I do this through the host file? Or do I set an AIias on Dynu.com? I'm assuming I need to create teslamate.xyz123.dynu.com and grafana.xyz123.dynu.com - however, I'm unclear how it ends up pointing to xyz123.dynu.com:4000 and xyz123.dynu.com:3000.
  3. When I type in terminal : hostname "Ubuntu" is returned.
  4. When I type in terminal : sudu nano /etc/hostname "Ubuntu" is all that shows up in text editor

Thanks in advance

J

Well I'm still not sure if I setup the FQDN piece section properly - but I gave it a go anyways to see where I would land.

In my DDNS settings I have the following configured :

Local IP : 123.456.789.321
Domain : xyz123.dynu.com
Alias Subdomain : teslamate.xyz123.dynu.com
Alias Subdomain : grafana.zyz123.dynu.com

*Domain and Subdomains all have :
Record = A
TTL = 120
IP Address = 123.456.789.321

My Ubuntu VM with Teslamate has LAN IP of : 192.168.86.51
I've run : sudo nano /etc/hosts and updated the following :

127.0.0.1       localhost
192.168.86.51  teslamate.xyz123.dynu.com teslamate
192.168.86.51  grafana.xyz123.dynu.com grafana

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

On my Router I've portforwarded 80 to 80 and 443 to 443 for 192.168.86.51

With the above configuration - I executed the YML file as posted by @adriankumpf in his Wiki but I get the following error :

Starting teslamate_proxy_1 ... 
Starting teslamate_database_1 ... 
Starting teslamate_proxy_1
Recreating teslamate_mosquitto_1 ... 
Recreating teslamate_grafana_1 ... 
Starting teslamate_database_1
Recreating teslamate_mosquitto_1
Starting teslamate_proxy_1 ... error

ERROR: for teslamate_proxy_1  Cannot start service proxy: driver failed programming external connectivity on endpoint teslamate_proxy_1 (832bd3284829abeae3820328aebe): Error starting userland proxy: listeStarting teslamate_database_1 ... done
Recreating teslamate_teslamate_1 ... 
Recreating teslamate_teslamate_1 ... done

ERROR: for proxy  Cannot start service proxy: driver failed programming external connectivity on endpoint teslamate_proxy_1 (832bd3284829abeae3820328aebe): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use
ERROR: Encountered errors while bringing up the project.

Thanks in advance for any assistance

Apparently something is already listening on port 80. Either stop that or choose another port.

Apparently something is already listening on port 80. Either stop that or choose another port.

@DrMichael Thanks! Any idea on how to stop whatever is running on port 80?

netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:5938 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:5940 0.0.0.0:* LISTEN -
tcp6 0 0 ::1:631 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::5938 :::* LISTEN -

Could you do a "sudo netstat -tulpen | grep 80"?

Could you do a "sudo netstat -tulpen | grep 80"?

@DrMichael Genius!
sudo netstat -tulpen | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 39024 793/nginx: master p
tcp6 0 0 :::80 :::* LISTEN 0 39025 793/nginx: master p

I've uninstalled NGINX : sudo apt-get purge nginx nginx-common

NGINX was carried over from my original installation - and I forgot about it when I copied the VM.

Now I've got a bunch of other errors that keep propagating. Progress!

@DrMichael @adriankumpf @Helmi I'm getting a whole bunch of errors. It's complaining about the password authentication, but I have no clue why. This is what I've configured :+1:

user : teslamate
password : ABC123test

which is saved in the .htpasswd file as teslamate:$apr1$tc49zXh5$QabDCDrzH7JK127X2LwgKNPmj

My .env file looks like this :
TM_DB_USER=teslamate
TM_DB_PASS=yourpassword
TM_DB_NAME=teslamate

GRAFANA_USER=teslamate
GRAFANA_PW=yourpassword

FQDN_GRAFANA=grafana.xyz123.dynu.com
FQDN_TM=teslamate.xyz123.dynu.com

TM_TZ=Europe/Berlin

[email protected]

On that note, my ACME folder has just an acme.json file. Are there supposed to be more files? Thanks in advance for your assistance. J

* On my browser I can navigate to both https://teslamate.xyz123.dynu.com and https://grafana.xyz123.dynu.com

Both pages prompt for the login / password - which is teslamate / ABC123test
https://teslamate.xyz123.dynu.com seems to accept the login / password but returns with "Bad Gateway"

https://grafana.xyz123.dynu.com brings me to the grafana login page - but upon logging in it returns "Unexpected error".

My log from Terminal after running Docker-Compose Up is as follows :

teslamate_1 |
teslamate_1 | Crash dump is being written to: erl_crash.dump...done
teslamate_1 | 02:29:55.884 [error] Postgrex.Protocol (#PID<0.206.0>) failed to connect: * (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:29:55.884 [error] Postgrex.Protocol (#PID<0.207.0>) failed to connect: *
(Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:29:57.308 [error] Postgrex.Protocol (#PID<0.207.0>) failed to connect: * (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:29:58.721 [error] Postgrex.Protocol (#PID<0.206.0>) failed to connect: *
(Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:29:58.857 [error] Could not create schema migrations table. This error usually happens due to the following:
teslamate_1 |
teslamate_1 | * The database does not exist
teslamate_1 | * The "schema_migrations" table, which Ecto uses for managing
teslamate_1 | migrations, was defined by another library
teslamate_1 | * There is a deadlock while migrating (such as using concurrent
teslamate_1 | indexes with a migration_lock)
teslamate_1 |
teslamate_1 | To fix the first issue, run "mix ecto.create".
teslamate_1 |
teslamate_1 | To address the second, you can run "mix ecto.drop" followed by
teslamate_1 | "mix ecto.create". Alternatively you may configure Ecto to use
teslamate_1 | another table for managing migrations:
teslamate_1 |
teslamate_1 | config :teslamate, TeslaMate.Repo,
teslamate_1 | migration_source: "some_other_table_for_schema_migrations"
teslamate_1 |
teslamate_1 | The full error report is shown below.
teslamate_1 |
teslamate_1 | * (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2982ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:621: Ecto.Adapters.SQL.raise_sql_call_error/1
teslamate_1 | (elixir) lib/enum.ex:1336: Enum."-map/2-lists^map/1-0-"/2
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:708: Ecto.Adapters.SQL.execute_ddl/4
teslamate_1 | (ecto_sql) lib/ecto/migrator.ex:567: Ecto.Migrator.verbose_schema_migration/3
teslamate_1 | (ecto_sql) lib/ecto/migrator.ex:411: Ecto.Migrator.lock_for_migrations/4
teslamate_1 | (ecto_sql) lib/ecto/migrator.ex:335: Ecto.Migrator.run/4
teslamate_1 | (ecto_sql) lib/ecto/migrator.ex:83: Ecto.Migrator.with_repo/3
teslamate_1 | (teslamate) lib/teslamate/release.ex:6: anonymous fn/2 in TeslaMate.Release.migrate/0
teslamate_1 | 02:30:05.481 [info] Running TeslaMateWeb.Endpoint with cowboy 2.6.3 at :::4000 (http)
teslamate_1 | 02:30:05.484 [error] Postgrex.Protocol (#PID<0.3452.0>) failed to connect: *
(Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:05.484 [error] Postgrex.Protocol (#PID<0.3449.0>) failed to connect: * (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:05.485 [error] Postgrex.Protocol (#PID<0.3448.0>) failed to connect: *
(Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:05.490 [error] Postgrex.Protocol (#PID<0.3454.0>) failed to connect: * (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:05.490 [error] Postgrex.Protocol (#PID<0.3453.0>) failed to connect: *
(Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:05.490 [info] Access TeslaMateWeb.Endpoint at http://teslamate.xyz123.dynu.com
teslamate_1 | 02:30:07.116 [error] Postgrex.Protocol (#PID<0.3454.0>) failed to connect: * (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
teslamate_1 | 02:30:07.480 [error] GenStateMachine TeslaMate.Mapping terminating
teslamate_1 | *
(DBConnection.ConnectionError) connection not available and request was dropped from queue after 1984ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:621: Ecto.Adapters.SQL.raise_sql_call_error/1
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:554: Ecto.Adapters.SQL.execute/5
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:153: Ecto.Repo.Queryable.execute/4
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
teslamate_1 | (teslamate) lib/teslamate/log.ex:117: TeslaMate.Log.get_positions_without_elevation/2
teslamate_1 | (teslamate) lib/teslamate/mapping.ex:75: TeslaMate.Mapping.handle_event/4
teslamate_1 | (stdlib) gen_statem.erl:1161: :gen_statem.loop_state_callback/11
teslamate_1 | (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
teslamate_1 | 02:30:07.480 [error] GenServer TeslaMate.Api terminating
teslamate_1 | * (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2000ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:621: Ecto.Adapters.SQL.raise_sql_call_error/1
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:554: Ecto.Adapters.SQL.execute/5
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:153: Ecto.Repo.Queryable.execute/4
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
teslamate_1 | (teslamate) lib/teslamate/auth.ex:22: TeslaMate.Auth.get_tokens/0
teslamate_1 | (teslamate) lib/teslamate/api.ex:142: TeslaMate.Api.handle_continue/2
teslamate_1 | (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
teslamate_1 | (stdlib) gen_server.erl:388: :gen_server.loop/7
teslamate_1 | Last message: {:continue, :sign_in}
teslamate_1 | 02:30:07.484 [info] Application teslamate exited: TeslaMate.Application.start(:normal, []) returned an error: shutdown: failed to start child: TeslaMate.Vehicles
teslamate_1 | *
(EXIT) exited in: GenServer.call(TeslaMate.Api, :list, 35000)
teslamate_1 | * (EXIT) an exception was raised:
teslamate_1 | *
(DBConnection.ConnectionError) connection not available and request was dropped from queue after 2000ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:621: Ecto.Adapters.SQL.raise_sql_call_error/1
teslamate_1 | (ecto_sql) lib/ecto/adapters/sql.ex:554: Ecto.Adapters.SQL.execute/5
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:153: Ecto.Repo.Queryable.execute/4
teslamate_1 | (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
teslamate_1 | (teslamate) lib/teslamate/auth.ex:22: TeslaMate.Auth.get_tokens/0
teslamate_1 | (teslamate) lib/teslamate/api.ex:142: TeslaMate.Api.handle_continue/2
teslamate_1 | (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
teslamate_1 | (stdlib) gen_server.erl:388: :gen_server.loop/7
teslamate_1 | {"Kernel pid terminated",application_controller,"{application_start_failure,teslamate,{{shutdown,{failed_to_start_child,'Elixir.TeslaMate.Vehicles',{{#{'__exception__' => true,'__struct__' => 'Elixir.DBConnection.ConnectionError',message => <<\"connection not available and request was dropped from queue after 2000ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information\">>,severity => error},[{'Elixir.Ecto.Adapters.SQL',raise_sql_call_error,1,[{file,\"lib/ecto/adapters/sql.ex\"},{line,621}]},{'Elixir.Ecto.Adapters.SQL',execute,5,[{file,\"lib/ecto/adapters/sql.ex\"},{line,554}]},{'Elixir.Ecto.Repo.Queryable',execute,4,[{file,\"lib/ecto/repo/queryable.ex\"},{line,153}]},{'Elixir.Ecto.Repo.Queryable',all,3,[{file,\"lib/ecto/repo/queryable.ex\"},{line,18}]},{'Elixir.TeslaMate.Auth',get_tokens,0,[{file,\"lib/teslamate/auth.ex\"},{line,22}]},{'Elixir.TeslaMate.Api',handle_continue,2,[{file,\"lib/teslamate/api.ex\"},{line,142}]},{gen_server,try_dispatch,4,[{file,\"gen_server.erl\"},{line,637}]},{gen_server,loop,7,[{file,\"gen_server.erl\"},{line,388}]}]},{'Elixir.GenServer',call,['Elixir.TeslaMate.Api',list,35000]}}}},{'Elixir.TeslaMate.Application',start,[normal,[]]}}}"}
teslamate_1 | Kernel pid terminated (application_controller) ({application_start_failure,teslamate,{{shutdown,{failed_to_start_child,'Elixir.TeslaMate.Vehicles',{{#{'__exception__' => true,'__struct__' => 'Elixir.D

@jun3280net - Not sure if this is relevant for you. But did you for any reason change your password(s) AFTER the initial installation and configuration? I noticed that there is a whole bunch of problems that occur if you do.

In my experience, I had to redo my entire setup and choose strong complex passwords from the start. And do NOT use hashtag in the password(s).

@jun3280net - Not sure if this is relevant for you. But did you for any reason change your password(s) AFTER the initial installation and configuration? I noticed that there is a whole bunch of problems that occur if you do.

In my experience, I had to redo my entire setup and choose strong complex passwords from the start. And do NOT use hashtag in the password(s).

@spacecosmos - I was literally just reading your guide to see if I was missing anything. I'm wondering if the issue is related to the fact I applied the new docker-compose.yml file over my original teslamate implementation.

How do you restart from scratch?

@spacecosmos - I was literally just reading your guide to see if I was missing anything. I'm wondering if the issue is related to the fact I applied the new docker-compose.yml file over my original teslamate implementation.

How do you restart from scratch?

@jun3280net - I'm fairly sure that's why then. I'm not sure how you initially did it, but if you used my guide, you could probably use docker system prune _after_ the docker-compose down command.

See here:
https://linuxize.com/post/how-to-remove-docker-images-containers-volumes-and-networks/

Or maybe just start totally from scratch and nuke the entire virtual machine (if that is what you have and are able to do). I had to do that a couple of times as I always ended up messing up something on the first attempts.

How is your setup btw? Docker or manual?

@spacecosmos - restarting from scratch did the trick. Only weird part was for Grafana, my password to login with "teslmate" was literally "yourpassword". I thought it was supposed to be the password (eg ABC123test) used to create the .htpasswd file - which worked to login to Teslamate.

Anyways - to start from scratch I used :
docker-compose down
docker system prune
docker container prune
docker volume prune
docker image prune
docker image rm

Everything works now. Just need to debug a couple more items and I think I'm good to forllow @spacecosmos Tasker guide!

@jun3280net - Glad i worked! Remember that .htpasswd is only for accessing the TeslaMate Dashboard. The credentials for Grafana is the one you put in the .env file.

@spacecosmos the main issue I have now relates to the https://FQDN. I use the Google Wifi mesh setup at home. I need to do some more research on this - but the Google Wifi blocks domains that are mapped to an internal IP to address DNS Rebinding attack. So when I'm connected to my home Wifi - I'm unable to access :
https://grafana.xyz123.dynu.com
https://teslamate.xyz123.dynu.com

To test, I was able to tether off my mobile LTE connection, and can confirm the aforementioned addresses work. It just doesn't work on home Wifi.

Is there any way to access grafana/teslmate internally using IP/Ports? This is a bit annoying because I need to figure out a way to trigger the car when I am at home. Maybe its as simple as connect to Tesla Bluetooth - Shut Off Wifi - Https PUT to Trigger.

https://support.google.com/wifi/thread/11904040?msgid=11911338

@jun3280net - I would assume that you could just use the IP address of your client computer to reach it from inside your home network?

@jun3280net - I would assume that you could just use the IP address of your client computer to reach it from inside your home network?

@spacecosmos With the restriction the Google Wifi has regarding the DNS, I can only access my server using the IP Address (192.168.86.51). As Teslamate runs behind Traefik, which specify the FQDN for Teslamate and Grafana, it's not clear how I can do this?

@jun3280net - Have you tried port forwarding? (Port 443 and maybe 80 should be enough to start with.)

https://support.google.com/wifi/answer/6274503?hl=en

@jun3280net - Have you tried port forwarding? (Port 443 and maybe 80 should be enough to start with.)

https://support.google.com/wifi/answer/6274503?hl=en

@spacecosmos Thanks for your suggestions - but yes port forwarding of port 443 and 80 is required from the outset. The issue is related to the Google Router blocking DDNS routed to machines internal to the network. Fortunately, my internet service provider gives me 2 separate IPs. What I'll do is setup an old router on the second IP and try this setup again.

Have a great Thanksgiving holiday

J

The new documentation hopefully answers many of the questions that have been asked in this thread. If you have any further questions that aren't answered in the docs, don't hesitate to open a new issue.

@DrMichael this setup uses SSL for all the web access. no 3000, no 4000. One subdomain for Grafana, one for Teslamate. Everything on 443. Port 80 is used for the (automatic) SSL retrieval process. If you don't want to use 80/443 this is just not the right setup for you - use the default docker-compose file instead. This is more what you're looking for.

Ok,, I can change the 443 to 444 in the config just fine. But I cannot do that for port 80, because with httpchallenge Letsencrypt must be able to access it.

Would it be possible to use another challenge? E.g. dnschallenge?

@DrMichael this setup uses SSL for all the web access. no 3000, no 4000. One subdomain for Grafana, one for Teslamate. Everything on 443. Port 80 is used for the (automatic) SSL retrieval process. If you don't want to use 80/443 this is just not the right setup for you - use the default docker-compose file instead. This is more what you're looking for.

Ok,, I can change the 443 to 444 in the config just fine. But I cannot do that for port 80, because with httpchallenge Letsencrypt must be able to access it.

Would it be possible to use another challenge? E.g. dnschallenge?

@DrMichael - Maybe this can give you some pointers?
https://satheesh.net/2019/09/28/teslamate-digitalocean-docker-step-by-step-installation-guide/

Well, I have the advanced installation running. But port 80 is already used by Apache, so I cannot use httpchallenge for Traefik.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bahree picture bahree  ·  5Comments

jun3280net picture jun3280net  ·  4Comments

tobiasehlert picture tobiasehlert  ·  4Comments

natrlhy picture natrlhy  ·  6Comments

Try2Fly picture Try2Fly  ·  5Comments