diff --git a/README.md b/README.md index 75cc6bb59..920719faa 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ If you have a spare domain name you can configure applications to be accessible * [Activepieces](https://www.activepieces.com/) - an open source all-in-one automation tool * [Actual](https://github.com/actualbudget/actual-server) - A local-first personal finance app * [Admidio](https://www.admidio.org/) - a free online membership management -* [Affine](https://github.com/toeverything/AFFiNE) - a next-gen knowledge base that brings planning, sorting and creating all together +* [Adventure Log](https://github.com/seanmorley15/AdventureLog) - Self-hostable travel tracker and trip planner. * [Airsonic](https://airsonic.github.io/) - catalog and stream music * [Appsmith](https://www.appsmith.com/) - low-code application platform to quickly build, deploy, and manage effective software * [Aria2](https://github.com/aria2/aria2) - a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line diff --git a/nas.yml b/nas.yml index 7e9598391..db46eadd9 100644 --- a/nas.yml +++ b/nas.yml @@ -65,6 +65,10 @@ tags: - admidio + - role: adventure_log + tags: + - adventure_log + - role: affine tags: - affine diff --git a/roles/adventure_log/defaults/main.yml b/roles/adventure_log/defaults/main.yml new file mode 100644 index 000000000..29f09d4cf --- /dev/null +++ b/roles/adventure_log/defaults/main.yml @@ -0,0 +1,82 @@ +--- +adventure_log_enabled: false +adventure_log_available_externally: false + +# directories +adventure_log_data_directory: "{{ docker_home }}/adventure_log" + +# network +adventure_log_port: "8171" +adventure_log_web_port: "8172" +adventure_log_hostname: "adventurelog" +adventure_log_network_name: "adventurelog" + +# specs +adventure_log_web_memory: 1g +adventure_log_db_memory: 1g +adventure_log_server_memory: 1g +adventure_log_nginx_memory: 1g +# docker +adventure_log_web_container_name: adventure-log-web +adventure_log_web_image_name: ghcr.io/seanmorley15/adventurelog-frontend +adventure_log_web_image_version: latest +adventure_log_db_container_name: adventure-log-db +adventure_log_db_image_name: postgis/postgis +adventure_log_db_image_version: 15-3.3 +adventure_log_server_container_name: adventure-log-server +adventure_log_server_image_name: ghcr.io/seanmorley15/adventurelog-backend +adventure_log_server_image_version: latest +adventure_log_nginx_container_name: adventure-log-nginx +adventure_log_nginx_image_name: nginx +adventure_log_nginx_image_version: stable-alpine +adventure_log_user_id: "1000" +adventure_log_group_id: "1000" + + +# adventure_log +adventure_log_public_server_url: "http://{{ adventure_log_server_container_name }}:8000" +adventure_log_origin: "https://{{ adventure_log_hostname }}.{{ ansible_nas_domain }}" +adventure_log_body_size_limit: "Infinity" +adventure_log_postgres_port: "5432" +adventure_log_postgres_db: "adventure_log" +adventure_log_postgres_user: "adventure_log" +adventure_log_postgres_password: "change_me" +adventure_log_postgres_host: "{{ adventure_log_db_container_name }}" +adventure_log_secret_key: "super_secret" +adventure_log_django_admin_username: "admin" +adventure_log_django_admin_password: "admin" +adventure_log_django_admin_email: "admin@example.com" +adventure_log_public_url: "https://{{ adventure_log_hostname }}.{{ ansible_nas_domain }}" +adventure_log_csrf_trusted_origins: "https://{{ adventure_log_hostname }}.{{ ansible_nas_domain }}" +adventure_log_debug: "false" +adventure_log_frontend_url: "http://{{ adventure_log_web_container_name }}:8080" +adventure_log_disable_registration: "false" +adventure_log_disable_registration_message: "Registration is disabled for this instance of AdventureLog." + +adventure_log_web_env: + PUBLIC_SERVER_URL: "{{ adventure_log_public_server_url }}" + ORIGIN: "{{ adventure_log_origin }}" + BODY_SIZE_LIMIT: "{{ adventure_log_body_size_limit }}" + +adventure_log_db_env: + POSTGRES_PORT: "{{ adventure_log_postgres_port }}" + POSTGRES_DB: "{{ adventure_log_postgres_db }}" + POSTGRES_USER: "{{ adventure_log_postgres_user }}" + POSTGRES_PASSWORD: "{{ adventure_log_postgres_password }}" + +adventure_log_server_env: + PGHOST: "{{ adventure_log_postgres_host }}" + PGDATABASE: "{{ adventure_log_postgres_db }}" + PGUSER: "{{ adventure_log_postgres_user }}" + PGPASSWORD: "{{ adventure_log_postgres_password }}" + SECRET_KEY: "{{ adventure_log_secret_key }}" + DJANGO_ADMIN_USERNAME: "{{ adventure_log_django_admin_username }}" + DJANGO_ADMIN_PASSWORD: "{{ adventure_log_django_admin_password }}" + DJANGO_ADMIN_EMAIL: "{{ adventure_log_django_admin_email }}" + PUBLIC_URL: "{{ adventure_log_public_url }}" + CSRF_TRUSTED_ORIGINS: "{{ adventure_log_csrf_trusted_origins }}" + DEBUG: "{{ adventure_log_debug }}" + FRONTEND_URL: "{{ adventure_log_frontend_url }}" + DISABLE_REGISTRATION: "{{ adventure_log_disable_registration }}" + # OPTIONAL: Set the message to display when registration is disabled + DISABLE_REGISTRATION_MESSAGE: "{{ adventure_log_disable_registration_message }}" diff --git a/roles/adventure_log/molecule/default/molecule.yml b/roles/adventure_log/molecule/default/molecule.yml new file mode 100644 index 000000000..ffd57a663 --- /dev/null +++ b/roles/adventure_log/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +provisioner: + inventory: + group_vars: + all: + adventure_log_enabled: true + adventure_log_data_directory: "/tmp/adventurelog" +platforms: + - name: instance + image: geerlingguy/docker-ubuntu2204-ansible:latest + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + - /var/run/docker.sock:/var/run/docker.sock + - /tmp:/tmp + cgroupns_mode: host + privileged: true + pre_build_image: true diff --git a/roles/adventure_log/molecule/default/side_effect.yml b/roles/adventure_log/molecule/default/side_effect.yml new file mode 100644 index 000000000..cc1f80212 --- /dev/null +++ b/roles/adventure_log/molecule/default/side_effect.yml @@ -0,0 +1,10 @@ +--- +- name: Stop + hosts: all + become: true + tasks: + - name: "Include {{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }} role" + ansible.builtin.include_role: + name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + vars: + adventure_log_enabled: false diff --git a/roles/adventure_log/molecule/default/verify.yml b/roles/adventure_log/molecule/default/verify.yml new file mode 100644 index 000000000..5218d9bff --- /dev/null +++ b/roles/adventure_log/molecule/default/verify.yml @@ -0,0 +1,40 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Get Adventure Log db container state + community.docker.docker_container: + name: "{{ adventure_log_db_container_name }}" + register: result_db + + - name: Get Adventure Log web container state + community.docker.docker_container: + name: "{{ adventure_log_web_container_name }}" + register: result_web + + - name: Get Adventure Log dashboard container state + community.docker.docker_container: + name: "{{ adventure_log_server_container_name }}" + register: result_server + + - name: Get Adventure Log nginx container state + community.docker.docker_container: + name: "{{ adventure_log_nginx_container_name }}" + register: result_nginx + + - name: Check if Adventure Log containers are running + ansible.builtin.assert: + that: + - result_db.container['State']['Status'] == "running" + - result_db.container['State']['Restarting'] == false + - result_web.container['State']['Status'] == "running" + - result_web.container['State']['Restarting'] == false + - result_server.container['State']['Status'] == "running" + - result_server.container['State']['Restarting'] == false + - result_nginx.container['State']['Status'] == "running" + - result_nginx.container['State']['Restarting'] == false diff --git a/roles/adventure_log/molecule/default/verify_stopped.yml b/roles/adventure_log/molecule/default/verify_stopped.yml new file mode 100644 index 000000000..03aec7373 --- /dev/null +++ b/roles/adventure_log/molecule/default/verify_stopped.yml @@ -0,0 +1,40 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Try and stop and remove Adventure Log server + community.docker.docker_container: + name: "{{ adventure_log_server_container_name }}" + state: absent + register: result_server + + - name: Try and stop and remove Adventure Log web + community.docker.docker_container: + name: "{{ adventure_log_web_container_name }}" + state: absent + register: result_web + + - name: Try and stop and remove Adventure Log db + community.docker.docker_container: + name: "{{ adventure_log_db_container_name }}" + state: absent + register: result_db + + - name: Try and stop and remove Adventure Log nginx + community.docker.docker_container: + name: "{{ adventure_log_nginx_container_name }}" + state: absent + register: result_nginx + + - name: Check if Adventure Log is stopped + ansible.builtin.assert: + that: + - not result_server.changed + - not result_web.changed + - not result_db.changed + - not result_nginx.changed diff --git a/roles/adventure_log/requirements.yml b/roles/adventure_log/requirements.yml new file mode 120000 index 000000000..9a736435a --- /dev/null +++ b/roles/adventure_log/requirements.yml @@ -0,0 +1 @@ +../../requirements.yml \ No newline at end of file diff --git a/roles/adventure_log/tasks/main.yml b/roles/adventure_log/tasks/main.yml new file mode 100644 index 000000000..e404468cc --- /dev/null +++ b/roles/adventure_log/tasks/main.yml @@ -0,0 +1,122 @@ +--- +- name: Start Adventure Log + block: + - name: Create Adventure Log Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: + - "{{ adventure_log_data_directory }}" + - "{{ adventure_log_data_directory }}/media" + - "{{ adventure_log_data_directory }}/proxy" + + - name: Create Adventure Log network + community.docker.docker_network: + name: "{{ adventure_log_network_name }}" + + - name: Create Adventure Log Db Docker Container + community.docker.docker_container: + name: "{{ adventure_log_db_container_name }}" + image: "{{ adventure_log_db_image_name }}:{{ adventure_log_db_image_version }}" + pull: true + volumes: + - "{{ adventure_log_data_directory }}/postgres:/var/lib/postgresql/data:rw" + networks: + - name: "{{ adventure_log_network_name }}" + network_mode: "{{ adventure_log_network_name }}" + container_default_behavior: no_defaults + env: "{{ adventure_log_db_env }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ adventure_log_db_memory }}" + + - name: Create Adventure Log Server Docker Container + community.docker.docker_container: + name: "{{ adventure_log_server_container_name }}" + image: "{{ adventure_log_server_image_name }}:{{ adventure_log_server_image_version }}" + pull: true + # ports: + # - "{{ adventure_log_port }}:8501" + env: "{{ adventure_log_server_env }}" + volumes: + - "{{ adventure_log_data_directory }}/media:/code/media/" + networks: + - name: "{{ adventure_log_network_name }}" + network_mode: "{{ adventure_log_network_name }}" + container_default_behavior: no_defaults + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ adventure_log_server_memory }}" + + - name: Create Adventure Log Web Docker Container + community.docker.docker_container: + name: "{{ adventure_log_web_container_name }}" + image: "{{ adventure_log_web_image_name }}:{{ adventure_log_web_image_version }}" + pull: true + ports: + - "{{ adventure_log_web_port }}:3000" + networks: + - name: "{{ adventure_log_network_name }}" + network_mode: "{{ adventure_log_network_name }}" + container_default_behavior: no_defaults + env: "{{ adventure_log_web_env }}" + labels: + traefik.enable: "{{ adventure_log_available_externally | string }}" + traefik.http.routers.adventure_log.rule: "Host(`{{ adventure_log_hostname }}.{{ ansible_nas_domain }}`) && !PathPrefix(`/media`)" + traefik.http.routers.adventure_log.tls.certresolver: "letsencrypt" + traefik.http.routers.adventure_log.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.adventure_log.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.adventure_log.loadbalancer.server.port: "3000" + memory: "{{ adventure_log_web_memory }}" + + - name: Create Adventure Log Nginx Container + community.docker.docker_container: + name: "{{ adventure_log_nginx_container_name }}" + image: "{{ adventure_log_nginx_image_name }}:{{ adventure_log_nginx_image_version }}" + pull: true + ports: + - "{{ adventure_log_port }}:80" + volumes: + - "{{ adventure_log_data_directory }}/media:/usr/share/nginx/html" + networks: + - name: "{{ adventure_log_network_name }}" + network_mode: "{{ adventure_log_network_name }}" + container_default_behavior: no_defaults + labels: + traefik.enable: "{{ adventure_log_available_externally | string }}" + traefik.http.routers.adventure_log_nginx.rule: "Host(`{{ adventure_log_hostname }}.{{ ansible_nas_domain }}`) && PathPrefix(`/media`)" + traefik.http.routers.adventure_log_nginx.tls.certresolver: "letsencrypt" + traefik.http.routers.adventure_log_nginx.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.adventure_log_nginx.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.middlewares.adventure_log_nginx-stripprefix.stripprefix.prefixes: "/media" + traefik.http.routers.adventure_log_nginx.middlewares: "adventure_log_nginx-stripprefix" + traefik.http.services.adventure_log_nginx.loadbalancer.server.port: "80" + restart_policy: always + memory: "{{ adventure_log_nginx_memory }}" + + when: adventure_log_enabled is true + +- name: Stop Adventure Log + block: + - name: Stop Adventure Log Server + community.docker.docker_container: + name: "{{ adventure_log_server_container_name }}" + state: absent + + - name: Stop Adventure Log Web + community.docker.docker_container: + name: "{{ adventure_log_web_container_name }}" + state: absent + + - name: Stop Adventure Log Db + community.docker.docker_container: + name: "{{ adventure_log_db_container_name }}" + state: absent + + - name: Stop Adventure Log Nginx + community.docker.docker_container: + name: "{{ adventure_log_nginx_container_name }}" + state: absent + when: adventure_log_enabled is false diff --git a/website/docs/applications/other/adventure-log.md b/website/docs/applications/other/adventure-log.md new file mode 100644 index 000000000..4f4ca9e6c --- /dev/null +++ b/website/docs/applications/other/adventure-log.md @@ -0,0 +1,17 @@ +--- +title: "Adventure Log" +--- + +Homepage: [https://github.com/seanmorley15/AdventureLog](https://github.com/seanmorley15/AdventureLog) + +Self-hostable travel tracker and trip planner. + +## Usage + +Set `adventure_log_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Adventure Log web interface can be found at [http://ansible_nas_host_or_ip:8171](http://ansible_nas_host_or_ip:8171). + +## Specific Configuration + +Edit all the needed container environment variables (see `defaults/main.yaml`).