Code Monkey home page Code Monkey logo

homebots's Introduction

Getting started TL;DR:

Local Dev:

  • Duplicate .env.example to .env, replacing vars as needed. You only have to do this for the systems you are going to spin up.
  • If using prometheus and node exporters, set a prometheus-grafana/prometheus/targets.json based off targets.json.example

Deployment:

TODO:

  • Sort out SSL for the line above lol. (maybe service.host.domain.com?)
  • Fix Error response from daemon: Address already in use
  • Fix (very occasional): Error response from daemon: Pool overlaps with other one on this address space

Approach

So the approach we are taking is multiple compose files by chunk, and then starting it all by creating compose.yml variants that have the services we want. For example:

$ docker compose -f compose.all.yml up -d

The structure is that all the compose.ymls exist in the root folder (because of the relative file reference constraint of merge), with config all housed in project folders. For example:

/
    compose.yml
    prometheus-grafana/
        compose.prometheus-grafana.yml
        prometheus/
        grafana/
    pihole/
        .env
        compose.pihole.yml
        ...

Config

There are two modes or working - local development, and then deployment.

  • Local development
    • .env files
    • Secrets are in local conf files
    • The workflow is to essentially do docker compose loops:
docker compose -f compose.all.yml down --remove-orphans && docker compose -f compose.all.yml up -d
  • Deployment:
    • .env.prod files that are amended by 1Password lookups.
    • Secrets are taken from 1password (therefore you need to have those containers running)
    • You deploy using ansible:
ansible-playbook main.yml

Credentials:

Item Dev Prod
Tailscale Key .env file .env.prod amended by 1p
Grafana login local .secrets file 1P written to .secrets
Unifi pass unifi-poller/.env .env.prod amended by 1p

SSL

Two ways of accessing services. For development, we access at localhost over ssl, and enabling this browser flag makes the check go away: chrome://flags/#allow-insecure-localhost / brave://flags/#allow-insecure-localhost. It's still red, but at least you don't have to click through.

For deployment, We're going to use a wildcard cert for the domain, and route the services at http://host.domain.com/service. We'll use internal dns on the pihole to resolve to an internal IP, there'll be no listing on public internet. We'll provision that cert via traefik's let's encrypt module, but note that means we probably need to ensure that's only done on one host.

Secrets

I wanted to use docker secrets here, but they just aren't supported by enough images (the docker file has to include typically a __file reference so the image knows where to look for the secret, which is different from accessing an env var). So rather than have a mix of secrets and .env vars, we're just falling back to .env vars for now. Later when docker secrets are more well supported we can do that.

nb: as of this commit, only grafand and pihole support the __FILE variant.

Service specific Readme

Prometheus / Grafana

Based of this awesome source, modified to use docker secrets and tailscale for grafana.

Importing dashboards

The easiest way to do this is to import them from inside grafana, configure them how you like, then go and copy the resulting json to a {template}.json file in prometheus-grafana/grafana/provisioning/dashboards

Tailscale

A few things.

  • The docker compose files floating around the internet aren't great. Best to migrate from the official doco's command to compose using https://www.composerize.com/ or similar. That's how I got to this one (pro tip: network_mode: host)
  • If you remove a machine or expire a key, and you are using persistent storage, you need to kill the state as well as replace the key for it to work. Otherwise (I'm guessing) it conflicts between the fact that the state files were made with an old key, and you're now trying to use a new one.
  • Incidentally, wiping the state folder is also the best way to get rid of the incrementing suffixes problem if you keep cycling for some reason.
  • The fact that the state folder is owned by root seems scary, but actually isn't.

Deployment

1Password, Ansible, and git.

Idea:

  • Use ansible to clone the repo from github
  • Create the files containing secrets by retrieving those secrets from 1Password, and directly writing them to the destination file. Something like:
- name: Pi public key
  copy:
    dest: '/home/{{ user }}/.ssh/rasberrypi.local.pub'
    content: "{{ lookup('onepassword', 'Raspberry Pi', field='public') }}"
    mode: 0640

We can use 1Password service accounts here, and the command line tool, so we don't have to mess around with 1password connect.

  • Install Ansible: sudo apt-get install -y python3-pip
  • Clone the repo: git clone https://github.com/lukegiuliani/homebots.git. Enter the directory: cd homebots.
  • Set up and set your credentials for 1Password connect.
  • Install requirements: ansible-galaxy collection install -r requirements.yml
  • Customise env vars:
    • TODO: Write this list.
  • Run the playbook: ansible-playbook deploy.yml

Deployment sequence:

  1. Collect secrets from 1Password.
  2. Check out / update the repo from github.
  3. Copy the relevant .env.prod files, replacing

Docker contexts? TL;DR: No.

Can we use docker contexts?

Idea:

  • Do basical machine set up essentially manually: ** Install docker ** Get rid of systemd-resolved on ubuntu per pihole docker documentation.

Then use docker contexts:

docker context create remote --docker "host=ssh://user@remotemachine"

I suspect this isn't goint work as we are using secrets, referencing files, and those files don't exist on the destination machine, and getting them there is non-trivial.

homebots's People

Contributors

lukegiuliani avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.