2025-12-15 19:28:02 +01:00
|
|
|
- name: Deploy Memos on memos-box
|
2026-09-11 21:56:12 +02:00
|
|
|
hosts: memos
|
2025-11-06 23:09:44 +01:00
|
|
|
become: yes
|
|
|
|
|
vars_files:
|
|
|
|
|
- ./memos_vars.yml
|
|
|
|
|
vars:
|
|
|
|
|
memos_subdomain: "{{ subdomains.memos }}"
|
|
|
|
|
memos_domain: "{{ memos_subdomain }}.{{ root_domain }}"
|
|
|
|
|
|
|
|
|
|
tasks:
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Ensure required packages are installed
|
2025-11-06 23:09:44 +01:00
|
|
|
apt:
|
|
|
|
|
name:
|
|
|
|
|
- wget
|
2025-12-15 19:28:02 +01:00
|
|
|
- tar
|
2025-11-06 23:09:44 +01:00
|
|
|
state: present
|
2025-12-15 19:28:02 +01:00
|
|
|
update_cache: true
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Create memos system user
|
|
|
|
|
user:
|
|
|
|
|
name: "{{ memos_user }}"
|
|
|
|
|
system: yes
|
|
|
|
|
shell: /bin/false
|
|
|
|
|
home: "{{ memos_data_dir }}"
|
|
|
|
|
create_home: no
|
|
|
|
|
comment: "Memos Service"
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Create memos data directory
|
|
|
|
|
file:
|
|
|
|
|
path: "{{ memos_data_dir }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: "{{ memos_user }}"
|
|
|
|
|
group: "{{ memos_user }}"
|
|
|
|
|
mode: '0750'
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Create memos config directory
|
|
|
|
|
file:
|
|
|
|
|
path: "{{ memos_config_dir }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: '0755'
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Download memos binary archive
|
2025-11-06 23:09:44 +01:00
|
|
|
get_url:
|
2025-12-15 19:28:02 +01:00
|
|
|
url: "{{ memos_url }}"
|
|
|
|
|
dest: "/tmp/memos.tar.gz"
|
2025-11-06 23:09:44 +01:00
|
|
|
mode: '0644'
|
|
|
|
|
|
|
|
|
|
- name: Extract memos binary
|
|
|
|
|
unarchive:
|
2025-12-15 19:28:02 +01:00
|
|
|
src: "/tmp/memos.tar.gz"
|
|
|
|
|
dest: "/tmp"
|
2025-11-06 23:09:44 +01:00
|
|
|
remote_src: yes
|
|
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Move memos binary to /usr/local/bin
|
2025-11-06 23:09:44 +01:00
|
|
|
copy:
|
2025-12-15 19:28:02 +01:00
|
|
|
src: "/tmp/memos"
|
|
|
|
|
dest: "{{ memos_bin_path }}"
|
2025-11-06 23:09:44 +01:00
|
|
|
remote_src: yes
|
2025-12-15 19:28:02 +01:00
|
|
|
mode: '0755'
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Create memos environment file
|
|
|
|
|
copy:
|
|
|
|
|
dest: "{{ memos_config_dir }}/memos.env"
|
|
|
|
|
content: |
|
|
|
|
|
MEMOS_MODE=prod
|
|
|
|
|
MEMOS_ADDR=0.0.0.0
|
|
|
|
|
MEMOS_PORT={{ memos_port }}
|
|
|
|
|
MEMOS_DATA={{ memos_data_dir }}
|
|
|
|
|
MEMOS_DRIVER=sqlite
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: '0644'
|
|
|
|
|
notify: Restart memos
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Create memos systemd service
|
2025-11-06 23:09:44 +01:00
|
|
|
copy:
|
|
|
|
|
dest: /etc/systemd/system/memos.service
|
|
|
|
|
content: |
|
|
|
|
|
[Unit]
|
2025-12-15 19:28:02 +01:00
|
|
|
Description=Memos - A privacy-first, lightweight note-taking service
|
2025-11-06 23:09:44 +01:00
|
|
|
After=network.target
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
Type=simple
|
2025-12-15 19:28:02 +01:00
|
|
|
User={{ memos_user }}
|
|
|
|
|
Group={{ memos_user }}
|
|
|
|
|
WorkingDirectory={{ memos_data_dir }}
|
|
|
|
|
EnvironmentFile={{ memos_config_dir }}/memos.env
|
|
|
|
|
ExecStart={{ memos_bin_path }}
|
|
|
|
|
Restart=always
|
|
|
|
|
RestartSec=3
|
|
|
|
|
StandardOutput=journal
|
|
|
|
|
StandardError=journal
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: '0644'
|
|
|
|
|
notify: Restart memos
|
|
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
- name: Reload systemd daemon
|
|
|
|
|
systemd:
|
|
|
|
|
daemon_reload: yes
|
|
|
|
|
|
2025-11-06 23:09:44 +01:00
|
|
|
- name: Enable and start memos service
|
|
|
|
|
systemd:
|
|
|
|
|
name: memos
|
|
|
|
|
enabled: yes
|
|
|
|
|
state: started
|
|
|
|
|
|
|
|
|
|
- name: Wait for memos to be ready
|
|
|
|
|
uri:
|
2025-12-15 19:28:02 +01:00
|
|
|
url: "http://127.0.0.1:{{ memos_port }}/healthz"
|
|
|
|
|
method: GET
|
2025-11-06 23:09:44 +01:00
|
|
|
status_code: 200
|
2025-12-15 19:28:02 +01:00
|
|
|
register: memos_health
|
|
|
|
|
retries: 10
|
|
|
|
|
delay: 3
|
|
|
|
|
until: memos_health.status == 200
|
|
|
|
|
|
|
|
|
|
- name: Display memos status
|
|
|
|
|
debug:
|
|
|
|
|
msg: "Memos is running on port {{ memos_port }}. Access via Tailscale at http://{{ memos_tailscale_hostname }}:{{ memos_port }}"
|
|
|
|
|
|
|
|
|
|
handlers:
|
|
|
|
|
- name: Restart memos
|
|
|
|
|
systemd:
|
|
|
|
|
name: memos
|
|
|
|
|
state: restarted
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
|
caddy: close out Plan 4
All five close-out greps return nothing: no sites-enabled handling outside
roles/, no `systemctl reload caddy`, no caddy_sites_dir self-reference, no
inline proxy unit writes. 37 playbooks syntax clean. The 14 Caddy site files
and 6 proxy units on the hosts are byte-identical to the Stage 0 baseline.
Seven play names still said "on vipy" while the play targeted a group. Renamed
to "on the edge host" - the last place a play claimed a hostname after Plan 2.
Documented the four vhosts in /etc/caddy/sites-enabled that no playbook writes
(uptime-kuma, arbretstaging, bitcoininfra, scriberr) in the caddy_site README.
None deleted.
uptime-kuma.conf was going to be deleted as dead config. It is not dead: the
louislam/uptime-kuma container is STILL RUNNING on watchtower - created
2026-02-07, restart=unless-stopped, healthy - and uptime.contrapeso.xyz returns
302, not the 502 a dead backend would give. The "decommissioning" retired the
Ansible code and the vault credentials, not the service. PLAN_3 claimed "the
tokens died with the server"; that is corrected there.
The Caddyfile.* backups are kept: one per host, Nov-Dec 2025, not churning, and
the only record of each Caddyfile before the import line was added.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:53:09 +02:00
|
|
|
- name: Configure Caddy reverse proxy for Memos on the edge host (via Tailscale)
|
2026-09-11 21:56:12 +02:00
|
|
|
hosts: edge
|
2025-12-15 19:28:02 +01:00
|
|
|
become: yes
|
|
|
|
|
vars_files:
|
|
|
|
|
- ./memos_vars.yml
|
|
|
|
|
vars:
|
|
|
|
|
memos_subdomain: "{{ subdomains.memos }}"
|
|
|
|
|
memos_domain: "{{ memos_subdomain }}.{{ root_domain }}"
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2025-12-15 19:28:02 +01:00
|
|
|
tasks:
|
lnbits, memos, mempool: use the caddy_site role
lnbits is the header_up shape; memos and mempool are the Tailscale MagicDNS
shape. 108 lines removed, 25 added.
mempool was the one playbook already reloading Caddy correctly
(systemd: state: reloaded rather than command: systemctl reload caddy), so
its end marker differed - the role's handler does the same thing.
Verified:
- lnbits: full --check, site task ok, byte-identical to the live file
- memos, mempool: --check --diff via --limit edge shows exactly one added
line each, the standardised MagicDNS comment. Both playbooks fail earlier
in check mode on their VM play ("Extract memos binary", the same
download-does-not-happen-in-check-mode artifact as forgejo), but the edits
are confined to the hosts: edge play - memos at line 169+, play 2 starts
at 159; mempool at 617+, play 2 starts at 606.
The added comment means the next real run of memos/mempool rewrites one
comment line. Those two host files were already stale against their
playbooks before this change.
All 14 site files on all 3 hosts still byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 23:29:06 +02:00
|
|
|
- name: Publish Memos through Caddy (via Tailscale)
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: caddy_site
|
|
|
|
|
vars:
|
|
|
|
|
caddy_site_name: memos
|
|
|
|
|
caddy_site_domain: "{{ memos_domain }}"
|
|
|
|
|
caddy_site_upstream: "{{ memos_tailscale_hostname }}:{{ memos_port }}"
|
|
|
|
|
caddy_site_resolvers: "100.100.100.100"
|