Repository navigation
Quick Start
Use this only for a new Ubuntu 24.04 server. Replace example values before running anything.
git clone git@github.com:0x4e3/server-bootsrtap.git
cd server-bootsrtap
uv sync --group dev
uv run pre-commit install
uv run pre-commit install --hook-type commit-msgYour controller needs:
- Python 3.12 or newer
uv-
just, for the project check recipes - a running Docker engine, for lightweight tests
- SSH access to the server as
rootor a user with passwordless or interactive sudo access - a public SSH key, for example
~/.ssh/id_ed25519.pub
Edit inventories/production/hosts.yaml:
---
all:
children:
bootstrap:
hosts:
server-01:
ansible_host: 203.0.113.10
ansible_user: root
traefik_hosts:
hosts:
server-01:
vaultwarden_hosts:
hosts: {}
three_x_ui_hosts:
hosts: {}
telemt_hosts:
hosts: {}Keep the host in bootstrap until bootstrap is complete. Add it to
traefik_hosts only when it should receive Docker and Traefik.
group_vars/vault.yaml is ignored by Git. Create it with Ansible Vault:
uv run ansible-vault create group_vars/vault.yamlAdd this minimum bootstrap content. Use your real public key and generate a strong password and a random salt.
---
vault_bootstrap_login_user_ssh_public_keys:
- "ssh-ed25519 AAAA... you@example"
vault_bootstrap_users_default_password: "replace-with-a-long-random-password"
vault_bootstrap_users_password_salt: "replace-with-a-random-salt"
vault_traefik_acme_email: "ops@example.com"
vault_traefik_dashboard_password: "replace-if-dashboard-is-enabled"
vault_vaultwarden_admin_token: "replace-if-vaultwarden-is-enabled"
vault_telemt_config: "replace-if-telemt-is-enabled"Verify that Git ignores it:
git check-ignore -v group_vars/vault.yamlAt the cloud provider, router, or security group level, allow:
- TCP 22 temporarily, for the first setup run
- TCP 22571, the current default hardened SSH port
- TCP 80 and 443 for every
traefik_hostsserver
If the new SSH port is not reachable from the controller, do not start setup. You can lock yourself out.
uv run ansible-playbook \
-i inventories/production/hosts.yaml \
--ask-vault-pass \
playbooks/bootstrap.yamlIf the initial ansible_user needs a sudo password, add -K to this command
and enter that sudo password when prompted. Do not add -K when connecting as
root or a user with passwordless sudo.
The default managed user is bootstraper. Bootstrap can upgrade packages and
reboot the server. Wait for the play to finish successfully.
Test the new user before moving on:
ssh -i ~/.ssh/id_ed25519 bootstraper@203.0.113.10 'sudo -n true'For a fresh server still listening on 22:
uv run ansible-playbook \
-i inventories/production/hosts.yaml \
--ask-vault-pass \
playbooks/setup.yaml \
-e 'setup_ssh_port=22'Add -K here too only when the bootstrap user does not have passwordless sudo.
After it completes, test the hardened SSH port:
ssh -i ~/.ssh/id_ed25519 -p 22571 bootstraper@203.0.113.10 'sudo -n true'If this command fails, do not run applications. Read Setup and SSH Migration.
ssh -i ~/.ssh/id_ed25519 -p 22571 bootstraper@203.0.113.10 \
'sudo systemctl is-active crowdsec crowdsec-firewall-bouncer && sudo iptables -S INPUT'For a Traefik host, also check:
ssh -i ~/.ssh/id_ed25519 -p 22571 bootstraper@203.0.113.10 \
'sudo systemctl is-active docker && sudo docker ps'Read Applications, add the host to the appropriate application group, configure its required variables, then run:
uv run ansible-playbook \
-i inventories/production/hosts.yaml \
--ask-vault-pass \
playbooks/apps.yaml