Installation Hetzner Cloud

Install t2core on a Linux host created remotely with Ansible at a Hetzner Cloud Project

You will need:

  • Ansible on your local maschine. Please refer to the Ansible docs to get started.

  • A preconfigured Hetzner Project with a configured ssh key

Create a folder on your local maschine and change to that dir:

mkdir ~/t2core_ansible/

Create an enviroment file ~/t2core_ansible/.env:

PWD=./
DOCKER_REGISTRY=docker.io
DOCKER_PROJECT=tri2
DOCKER_TAG=latest
T2CORE_SECRET_KEY=dosiufzgd89f7gzjd8f7zgjSEFSfesEFEWFgHjk98dfzsj098dzfj
T2CORE_DATABASE_PASSWORD=sdlfihsmd9f8zgsDFSDfef8sdzgfsRGD8dzgfsz8df

Change the shown T2CORE_SECRET_KEY and T2CORE_DATABASE_PASSWORD as this are only the default values.

Create another file ~/t2core_ansible/env.yml:

---

# the API used to connect to the project
hetzner_cloud_project_access_token: HQ3OddCL2sdflkjsldkflskdjfK7uagvM7LNge3SUtqQHRQ

# the servertype to be created, cx11 is the minimum
hetzner_cloud_project_server_type: cx11

# the datacenter where the maschine is created
hetzner_cloud_project_server_location: fsn1

# the base image of the server
hetzner_cloud_project_server_image: ubuntu-18.04

# the hostname of the created server
hetzner_cloud_project_server:
  - host1

# the ssh key name configured in the project to access the maschine via ansible
ssh_key_name: mykeyname

Change at least the shown hetzner_cloud_project_access_token to the one of your project and ssh_key_name to the name of the ssh key.

Create the file ~/t2core_ansible/docker-compose.yml:

version: "2.2"
services:

  t2_core:
    image: "${DOCKER_REGISTRY}/${DOCKER_PROJECT}/t2-core:${DOCKER_TAG}"
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ${PWD}/t2core_data:/data:rw
    environment:
      # enables debug mode in django. this is very insecure. __do__ __not__ enable it, when django runs on a public environment!
      DEBUG: "false"
      START_PAGE_APP_URL: 't2ldap.urls'
      SECRET_KEY: "${T2CORE_SECRET_KEY}"
      IMPORTER_NETWORK_NAME_PREFIX: "localhost_"
      DATABASE_HOST: "database"
      DATABASE_PORT: "5432"
      DATABASE_NAME: "t2_core"
      DATABASE_USERNAME: "t2core"
      DATABASE_PASSWORD: "${T2CORE_DATABASE_PASSWORD}"
      DOCKER_REGISTRY: "${DOCKER_REGISTRY}"
      DOCKER_PROJECT: "${DOCKER_PROJECT}"
      DOCKER_TAG: "${DOCKER_TAG}"

    networks:
      - internal
    links:
      - "t2_database:database"
    labels:
      traefik.enable: "true"
      traefik.docker.network: "t2core_router"
      traefik.frontend.passhostheader: "False"
      traefik.http.routers.t2_core.entrypoints: "web"
      traefik.http.routers.t2_core.rule: "PathPrefix(`/`)"
      traefik.http.routers.t2_core.service: "t2_core"

      traefik.http.routers.t2_core_s.entrypoints: "websecure"
      traefik.http.routers.t2_core_s.rule: "PathPrefix(`/`)"
      traefik.http.routers.t2_core_S.service: "t2_core"
      traefik.http.routers.t2_core_S.tls: ""

      traefik.http.services.t2_core.loadbalancer.server.port: "8000"
      traefik.http.services.t2_core.loadbalancer.server.scheme: "http"

      traefik.tcp.routers.t2_ldapproxy.entrypoints: "ldap"
      traefik.tcp.routers.t2_ldapproxy.rule: "HostSNI (`*`)"
      traefik.tcp.routers.t2_ldapproxy.service: "t2_ldapproxy"#
      traefik.tcp.routers.t2_ldapproxy_s.entrypoints: "ldapsecure"
      traefik.tcp.routers.t2_ldapproxy_s.rule: "HostSNI (`*`)"
      traefik.tcp.routers.t2_ldapproxy_s.service: "t2_ldapproxy"
      traefik.tcp.routers.t2_ldapproxy_s.tls: ""
      traefik.tcp.services.t2_ldapproxy.loadbalancer.server.port: "389"


  t2_database:
    image: postgres:13
    restart: always
    volumes:
      - t2core_database:/data:rw
    environment:
      POSTGRES_PASSWORD: "${T2CORE_DATABASE_PASSWORD}"
      POSTGRES_USER: "t2core"
      POSTGRES_DB: "t2_core"
      PGDATA: "/data"
    networks:
      - internal


volumes:
  t2core_database:

networks:
  # internal network between django and its database
  internal:

Bemerkung

Database version: the postgres database version must be set to a major version (postgres:12, postgres:13), because database files are not compatible between major versions. Currently this is version 13, installations can be migrated between versions, but this cannot be done automatically. See https://www.postgresql.org/docs/current/upgrading.html and https://github.com/docker-library/postgres/issues/766

Create the file ~/t2core_ansible/up.yml:

#!/usr/bin/env Ansible-playbook
---

- name: Starts a t2 core demo in a Hetzner Cloud Project
  hosts: localhost
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
  tasks:

    - name: Create a basic server
      hcloud_server:
        name: "{{ item }}"
        server_type: "{{ hetzner_cloud_project_server_type }}"
        image: "{{ hetzner_cloud_project_server_image }}"
        location: "{{ hetzner_cloud_project_server_location }}"
        state: "present"
        api_token: "{{ hetzner_cloud_project_access_token }}"
        ssh_keys:
          - "{{ ssh_key_name }}"
      loop: "{{ hetzner_cloud_project_server }}"
      loop_control:
        index_var: index_var
      register: create_results

    - name: Set Host Facts
      add_host:
        hostname: "{{ item.hcloud_server.name }}"
        ansible_ssh_host: "{{ item.hcloud_server.ipv4_address }}"
        ansible_ssh_user: "root"
        ansible_ssh_port: 22
        ansible_python_interpreter: "{{ ansible_python_interpreter}}"
        ansible_ssh_common_args: '-o StrictHostKeyChecking=no'

        groups: hetzner_cloud_project
      loop: "{{ create_results.results }}"
      changed_when: false

    - name: Wait until port 22 comes up
      wait_for:
        host: "{{ item.hcloud_server.ipv4_address }}"
        port: 22
        timeout: 300
      loop: "{{ create_results.results }}"

- name: Install t2_core
  hosts: hetzner_cloud_project
  gather_facts: yes
  tasks:
    - name: Install docker / docker-compose
      apt:
        package: ["docker.io", "docker-compose"]
        state: present
        update_cache: yes

    - name: mkdir Install dir /usr/share/t2core/
      file:
        path: "/usr/share/t2core/"
        state: "directory"

    - name: "Copy compose environment '.env' to /usr/share/t2core/.env"
      copy:
        src: ".env"
        dest: "/usr/share/t2core/.env"
        force: yes

    - name: "Copy 'docker-compose.yml' to /usr/share/t2core/docker-compose.yml"
      copy:
        src: "docker-compose.yml"
        dest: "/usr/share/t2core/docker-compose.yml"
        force: yes

    - name: Starting Project via /usr/share/t2core/docker-compose.yml
      command: docker-compose up -d --remove-orphans
      args:
        chdir: /usr/share/t2core/

Create the file ~/t2core_ansible/down.yml:

#!/usr/bin/env ansible-playbook
---

- name: Starts a t2 core demo in a Hetzner Cloud Project
  hosts: localhost
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
  tasks:

    - name: removing server
      hcloud_server:
        name: "{{ item }}"
        server_type: "{{ hetzner_cloud_project_server_type }}"
        image: "{{ hetzner_cloud_project_server_image }}"
        location: "{{ hetzner_cloud_project_server_location }}"
        state: "absent"
        api_token: "{{ hetzner_cloud_project_access_token }}"
        ssh_keys:
          - "{{ ssh_key_name }}"
      loop: "{{ hetzner_cloud_project_server }}"
      loop_control:
        index_var: index_var

Make both Playbooks executable with:

chmod u+x up.yml
chmod u+x down.yml

To finally boot the server up you have to give Ansible the created env.yml:

./up.yml -e @env.yml

Bemerkung

If you manage more than one host with this playbook you can create an individual env_prod.yml for each one.

Bemerkung

To completly remove the host you can use ./down.yml -e @env.yml. This will shutdown the host and remove it from the project.

The server boots up and is avaible on port 80 and 443 afterwards. It depends on your cloud config and ssh settings but you can now log in to the server and get the password of the newly created user root from the container logs:

root@host1:~# ssh root@78.46.228.245
cd /usr/share/t2core/
docker-compose logs t2_core
t2_core_1      | new password of user "root" is:
t2_core_1      |
t2_core_1      |                5e425930-a8d2-4d97-bfe0-18a6df19c66c

Bemerkung

This is a random generated password. The one shown here will not work on your maschine.

The installation is done now. You are able to log in and you can proceed to the configuration.