- name: Deployment playbook hosts: all become: true vars: ansible_python_interpreter: /usr/bin/python3.11 tasks: - name: Append command to .bash_history blockinfile: path: "~/.bash_history" create: yes block: | #1724983098 cd /root/node/ ; docker compose logs --since 3h -f marker: "" - name: Set locale to C.UTF-8 ansible.builtin.command: cmd: localectl set-locale LANG=C.UTF-8 changed_when: false - name: Create APT configuration file to assume yes ansible.builtin.copy: dest: /etc/apt/apt.conf.d/90forceyes content: | APT::Get::Assume-Yes "true"; mode: '0644' - name: Update /etc/bash.bashrc ansible.builtin.blockinfile: path: /etc/bash.bashrc block: | export HISTTIMEFORMAT='%F, %T ' export HISTSIZE=10000 export HISTFILESIZE=10000 shopt -s histappend export PROMPT_COMMAND='history -a' export HISTCONTROL=ignoredups export LANG=C.UTF-8 export LC_ALL=C.UTF-8 alias ls='ls --color=auto' shopt -s cmdhist - name: Ensure ~/.inputrc exists ansible.builtin.file: path: /root/.inputrc state: touch mode: '0644' - name: Update ~/.inputrc ansible.builtin.blockinfile: path: ~/.inputrc block: | "\e[A": history-search-backward "\e[B": history-search-forward - name: Ensure ~/.nanorc exists ansible.builtin.file: path: /root/.nanorc state: touch mode: '0644' - name: Update ~/.nanorc ansible.builtin.blockinfile: path: ~/.nanorc block: | set nohelp set tabsize 4 set tabstospaces set autoindent set positionlog set backup set backupdir /tmp/ set locking include /usr/share/nano/*.nanorc - name: Set hostname ansible.builtin.shell: | hostnamectl set-hostname {{ serverid }} echo "127.0.1.1 {{ serverid }}" >> /etc/hosts changed_when: false - name: Update and upgrade apt ansible.builtin.apt: update_cache: true upgrade: dist force_apt_get: true autoremove: true register: apt_update_result retries: 5 delay: 50 until: apt_update_result is succeeded async: "{{ 60 * 20 }}" poll: 30 - name: Install packages ansible.builtin.apt: name: - ca-certificates - zlib1g-dev - libncurses5-dev - libgdbm-dev - libnss3-dev - curl - jq - git - zip - wget - make - python3 - python3-pip - iftop state: present update_cache: true async: "{{ 60 * 20 }}" poll: 30 - name: Install grist-api and colorama (attempt 1) ansible.builtin.command: pip3 install grist-api colorama --break-system-packages args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false register: pip_install_1 ignore_errors: true - name: Install grist-api and colorama (attempt 2) ansible.builtin.command: pip3 install grist-api colorama --break-system-packages args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false register: pip_install_2 ignore_errors: true when: pip_install_1 is failed - name: Install grist-api and colorama (attempt 3) ansible.builtin.command: pip3 install grist-api colorama --break-system-packages args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false when: pip_install_1 is failed and pip_install_2 is failed - name: Install Docker ansible.builtin.shell: curl -fsSL https://get.docker.com | bash changed_when: false async: "{{ 60 * 5 }}" poll: 30 - name: Update Docker daemon journald logging ansible.builtin.copy: dest: /etc/docker/daemon.json content: | { "log-driver": "journald" } mode: '0644' - name: Restart Docker ansible.builtin.service: name: docker state: restarted - name: Update journald log SystemMaxUse=2G configuration ansible.builtin.lineinfile: path: /etc/systemd/journald.conf line: 'SystemMaxUse=2G' insertafter: EOF create: true mode: '0644' - name: Restart journald ansible.builtin.service: name: systemd-journald state: restarted - name: Docker login ansible.builtin.shell: docker login -u "{{ docker_username }}" -p "{{ docker_password }}" register: docker_login_result changed_when: false failed_when: "'Login Succeeded' not in docker_login_result.stdout" - name: Clone repository ansible.builtin.git: repo: https://gitea.vvzvlad.xyz/vvzvlad/nexus dest: "{{ ansible_env.HOME }}/node" version: "{{ git_version }}" force: true async: "{{ 60 * 15 }}" poll: 30 - name: Make update.sh executable ansible.builtin.shell: | chmod +x ./update.sh args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false - name: Update environment variables ansible.builtin.shell: | ./update.sh ID "{{ id }}" ./update.sh GRIST_SERVER "{{ grist_server }}" ./update.sh GRIST_DOC_ID "{{ grist_doc_id }}" ./update.sh GRIST_API_KEY "{{ grist_api_key }}" args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false - name: Build dockers images ansible.builtin.command: docker build -t nexus-image . args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false - name: Check external IP before ansible.builtin.command: curl https://ifconfig.me register: ip_before changed_when: false - name: Validate IP address ansible.builtin.assert: that: - ip_before.stdout | ansible.utils.ipaddr fail_msg: "The returned value is not a valid IP address." success_msg: "The returned value is a valid IP address." - name: Download tun2socks ansible.builtin.get_url: url: https://github.com/xjasonlyu/tun2socks/releases/download/v2.5.2/tun2socks-linux-amd64.zip dest: /tmp/tun2socks-linux-amd64.zip mode: '0644' async: "{{ 60 * 5 }}" poll: 30 - name: Unzip tun2socks ansible.builtin.unarchive: src: /tmp/tun2socks-linux-amd64.zip dest: /usr/local/sbin/ remote_src: true mode: '0755' - name: Create proxy file ansible.builtin.copy: content: "{{ proxy }}" dest: /root/proxy mode: '0644' - name: Create tun2socks systemd service ansible.builtin.copy: dest: /etc/systemd/system/tun2socks.service content: | [Unit] Description=Tun2Socks gateway After=network.target Wants=network.target [Service] User=root Type=simple RemainAfterExit=true ExecStartPre=/bin/sh -c 'ip route add $(cat /root/proxy | grep -oP "(?<=@)[0-9.]+(?=:)" )/32 via $(ip route | grep -oP "(?<=default via )[0-9.]+")' ExecStart=/bin/sh -c '/usr/local/sbin/tun2socks-linux-amd64 --device tun0 --proxy $(cat /root/proxy)' ExecStopPost=/bin/sh -c 'ip route del $(cat /root/proxy | grep -oP "(?<=@)[0-9.]+(?=:)" )/32 via $(ip route | grep -oP "(?<=default via )[0-9.]+")' Restart=always [Install] WantedBy=multi-user.target mode: '0644' - name: Create network configuration for tun0 ansible.builtin.copy: dest: /etc/systemd/network/10-proxy.network content: | [Match] Name=tun0 [Network] Address=10.20.30.1/24 [Route] Gateway=0.0.0.0 mode: '0644' - name: Enable and start tun2socks service ansible.builtin.systemd: name: tun2socks enabled: true state: started - name: Reload network configuration ansible.builtin.command: networkctl reload changed_when: false - name: Restart tun2socks service ansible.builtin.systemd: name: tun2socks state: restarted - name: Check external IP after ansible.builtin.command: curl https://ifconfig.me register: ip_after changed_when: false - name: Validate IP address ansible.builtin.assert: that: - ip_after.stdout | ansible.utils.ipaddr fail_msg: "The returned value is not a valid IP address." success_msg: "The returned value is a valid IP address." - name: Show IPs ansible.builtin.debug: msg: "External IP before: {{ ip_before.stdout }}, External IP after: {{ ip_after.stdout }}" - name: Compare external IPs ansible.builtin.fail: msg: "External IP before and after should not be the same" when: ip_before.stdout == ip_after.stdout - name: Up docker compose stack ansible.builtin.command: docker compose up -d args: chdir: "{{ ansible_env.HOME }}/node" environment: COMPOSE_INTERACTIVE_NO_CLI: 'true' changed_when: false async: "{{ 60 * 80 }}" poll: "{{ 60 }}" - name: Copy checker service file ansible.builtin.copy: dest: /etc/systemd/system/node-checker.service content: | [Unit] Description=Node Checker Service After=network.target [Service] Type=simple User=root WorkingDirectory={{ ansible_env.HOME }}/node ExecStart=/usr/bin/bash {{ ansible_env.HOME }}/node/update-and-run-checker.sh Restart=always RestartSec=1800 [Install] WantedBy=multi-user.target mode: '0644' - name: Reload systemd ansible.builtin.systemd: daemon_reload: yes - name: Enable and start node-checker service ansible.builtin.systemd: name: node-checker enabled: yes state: started - name: Remove docker login credentials ansible.builtin.file: path: /root/.docker/config.json state: absent