All the necessary instructions, docker files, scripts, etc. necessary for building my self hosted server (almost) from scratch.
- Infrastructure of snyssen.be
As this project is in constant flux and I am the sole contributor, please bear in mind that this README could become out of sync with the actual repository content. You should also remember that the documentation and files present are firstly made for my own use. As such, I won't be responsible for any issue you might have when trying to reproduce my setup, and you should probably at least have some grasp of how to use Linux, Docker and Ansible before attempting this. That said, I am open to offer some help to adventurous people trying to make use of this repository.
As an avid self-hoster, I depend on my server for a plethora of everyday tasks. This repository includes everything I need to deploy all the services necessary for said tasks. Once fully operational, this servers allows me to, among other things:
- Reduce or eliminate my dependency to big corporations services. It can do so by:
- Acting as a cloud file manager and backup (think Google Drive or One Drive)
- Syncing my agenda and tasks using WebDav and CalDav, thus replacing Google Agenda and such
- Offer private and secure instant messaging options, even though the usage will be limited as it can be hard to convince friends and loved ones to switch from known brands
- Automatically import and catalog my pictures
- Provide music, movies and tv shows anywhere, on any device
- Host my public and private source codes and projects
- Archive and organize my thoughts, problems and solutions
- Serve my various websites
- Play some games with friends
- Etc.
Clone the repos on the client machine (the one with Ansible installed) and cd into it:
git clone https://github.com/snyssen/infra-snyssen.be.git && cd infra-snyssen.be
Run the setup script:
just setup
This script will do the following:
- Set a pre-commit hook to prevent you from making commits without encrypting the Ansible vaults first.
- Install the Ansible, Vagrant and other requirements.
- Create the ansible password file for encrypting and decrypting the vaults. You will be asked for the encryption key. The generated file (
.vault_pass
) should of course never be committed.
Playbooks follow the <context>-<action>.yml
filename scheme. As such, they are ordered by context. For each demonstrated command, additional variables are added in json format, with |
for separating possible values (when applicable).
For each playbook, multiple environments are available and should be configured for your use case. Environments are defined as inventory files in /hosts
. There are currently 3 environments:
- dev: Should be used with vagrant for development.
- staging: Should be used with an expandable server, for final testing before actual deployment
- prod: Should be used for actual production deployment
The dev environment is the default one: if you don't specify the environment to use, all playbooks will be run against this one. You can specify the inventory with the -i
flag:
ansible-playbook <playbook_file.yml> -i hosts/<inventory_file.yml>
Use this playbook to deploy a fresh instance of the server. For example, to have a fresh instance on staging use:
ansible-playbook setup-deploy.yml -e '{"docker_compose_state":"present|absent|restarted","stacks_deploy_list":["backbone","nextcloud"]}'
docker_compose_state
(optional, default = present): The state of the stacks after they are deployedstacks_deploy_list
: (optional) Explicitly defines the list of stacks that should be deployed. If undefined, all stacks are deployed; otherwise only specified stacks are.
Restore a previous server backup from scratch. This is useful for disaster recovery.
ansible-playbook setup-restore.yml -e '{"restic_server":"local|remote","stacks_deploy_list":["backbone","nextcloud"]}'
restic_server
(optional, default = local): The backup server to use.local
refers to a LAN accessible restic rest server that is deployed along the main server;remote
refers to a WAN accessible s3 bucket.stacks_deploy_list
: (optional) Explicitly defines the list of stacks that should be deployed. If undefined, all stacks are deployed; otherwise only specified stacks are.
The playbook requires user input during execution to choose the file backup and then database backups to restore.
Sends a magic packet to wake supported servers on LAN. The backup server is the sole server having this capability at the moment.
ansible-playbook [-i hosts/prod.yml] server-wol.ansible.yml
Completely wipes the apps server, stopping all applications and destroying all the data. This is usually only used during development, as a faster way to iterate without having to fully recreate the VM.
ansible-playbook server-wipe.ansible.yml
Reboots the server(s). It is recommended to use the --limit
flag to only apply this to a single group, as you usually don't want to reboot all your servers but only one at a time.
ansible-playbook server-reboot.yml --limit=apps|backup|dns -e '{"reboot_delay":300,"prevent_apps_restart":true|false}'
reboot_delay
: (optional, default = immediately) The delay (in seconds) the server should wait before rebooting. Values below 60 are ignored. If not explicitly set, will be asked to user on playbook execution.prevent_apps_restart
(default = false): Whether all apps should be restarted or not after reboot. If set to true, apps won't be restarted.
Shutdowns the server(s). It is recommended to use the --limit
flag to only apply this to a single group, as you usually don't want to shutdown all your servers but only one at a time.
ansible-playbook server-shutdown.yml --limit=apps|backup|dns -e '{"shutdown_delay": 300}'
shutdown_delay
: (optional, default = immediately) The delay (in seconds) the server should wait before shutting down. Values below 60 are ignored. If not explicitly set, will be asked to user on playbook execution.
Gather all facts about all servers and output them to console.
ansible-playbook -i hosts/prod.yml server-gather-facts.ansible.yml --limit=apps|backup|dns
Deploys all stacks to the app server.
ansible-playbook stacks-deploy.yml -e '{"docker_compose_state":"present|absent|restarted","stacks_deploy_list":["backbone","nextcloud"]}'
docker_compose_state
(optional, default = present): The state of the stacks after they are deployedstacks_deploy_list
: (optional) Explicitly defines the list of stacks that should be deployed. If undefined, all stacks are deployed; otherwise only specified stacks are.
Changes the state of specific stacks.
ansible-playbook stacks-manage.yml -e '{"stacks_state":"present|absent|restarted","stacks_include_str"="nextcloud restic","stacks_exclude_str"="speedtest photoprism"}'
stacks_state
: (optional, asked on start) Sets the stack state. If not explicitly set, will be asked to user on playbook execution.stacks_include_str
: (optional, asked on start) Space separated list of stacks names which state should be changed. Leave empty to include all apps. Note that this setting is mutually exclusive with the 'stacks_exclude' one; if both are set, only this one will be used.stacks_exclude_str
: (optional, asked on start) Space separated list of stacks names which state should not be changed. Leave empty to not exclude any app.
Runs a backup through autorestic.
ansible-playbook playbooks/backup-run.ansible.yml [-e '{"backup_locations":["nextcloud","postgres"]}']
backup_locations
(optional) Specify which autorestic location(s) to backup. If left unset, it runs through all of the locations set for autorestic; otherwise, it only runs for the locations provided. Specific backends can also be chosen by appending a location with@backend
, e.g.nextcloud@backup-snyssen-be
; see Autorestic documentation.
Lists backups snapshots through autorestic.
ansible-playbook playbooks/backup-list.ansible.yml -e '{"backup_backend":"backup-snyssen-be|snyssen-be-autorestic","backup_locations":["postgres","nextcloud"]}'
backup_backend
Specify the backend to query.backup_locations
(optional) Filter snapshots per location
Checks the integrity of the backups, using restic check
.
ansible-playbook playbooks/backup-integrity.ansible.yml -e backup_backend=backup-snyssen-be|snyssen-be-autorestic
backup_backend
Specify the backend to query.
Restores a backup using autorestic.
ansible-playbook playbooks/backup-restore.ansible.yml -e '{"backup_backend":"backup-snyssen-be|snyssen-be-autorestic","backup_location":"postgres","backup_replace":true|false,"backup_snapshot":"22ae11c4","backup_restore_directory":"/mnt/tmp"}'
backup_backend
Specify the backend from which snapshot will be loaded.backup_location
Specify the location to restore.backup_snapshot
(optional) Specify the snapshot ID to restore. Snapshot IDs can be found using the Backup - list command. If left unset, restores the latest.backup_restore_directory
(optional) Specify another root directory in which to restore the backup. if left unset, will restore using/
as root, i.e. it will restore the files in their original location. When unset, it might be useful to enablebackup_replace
to ensure a proper restore.
Backs up the server.
ansible-playbook backup-old-run.yml [-e "backup_skip_databases={true,false} backup_skip_files={true,false} backup_files_skip_local={true,false} backup_files_skip_remote={true,false}"]
backup_skip_databases
(default = false): Whether to skip the databases backups or not. If set to true, no database backup will be made.backup_skip_files
(default = false): Whether to skip the files backup or not. If set to true, no file will be backed up.backup_files_skip_local
(default = false): Whether to skip the local backup or not. If set to true, files won't be saved to the local backup server.backup_files_skip_remote
(default = false): Whether to skip the remote backup or not. If set to true, files won't be saved to the remote backup server.
Restores a server backup.
ansible-playbook backup-old-restore.yml [-e "backup_skip_files={true,false} backup_skip_databases={true,false} restic_server={local,remote} db_restore_include=['nextcloud', 'photoprism'] db_restore_exclude=['recipes']"]
backup_skip_databases
(default = false): Whether to skip the databases restore or not. If set to true, no database will be restored.backup_skip_files
(default = false): Whether to skip the files restore or not. If set to true, no file will be restored.restic_server
(default = local): The backup server to use.local
refers to a LAN accessible restic rest server that is deployed along the main server;remote
refers to a WAN accessible s3 bucket.db_restore_include
(default = all): databases to restore. If left empty, all dbs are included. Note that this setting is mutually exclusive with 'db_restore_exclude'; if both are set, only this one will be useddb_restore_exclude
(default = none): databases that should not be restored
Checks all snapshots.
ansible-playbook [-i hosts/prod.yml] backup-old-check.ansible.yml [-e "restic_server={local,remote}"]
List all available snapshots.
ansible-playbook [-i hosts/prod.yml] backup-old-list-snapshots.ansible.yml [-e "restic_server={local,remote}"]
Get logs of latest backup run
ansible-playbook [-i hosts/prod.yml] backup-old-get-logs.ansible.yml [-e "restic_server={local,remote}"]
Executes the snapraid-runner on the apps server.
ansible-playbook [-i hosts/prod.yml ]snapraid-runner-execute.ansible.yml [-e "snapraid_runner_ignore_threshold=true skip_healthcheck=true"]
snapraid_runner_ignore_threshold
(default = false): ignore the default delete threshold, allowing snapraid to be run even after a large delete operation.skip_healthcheck
(default = false): do not trigger the healthcheck upon successful completion
Retrieves logs from the latest snapraid run.
ansible-playbook [-i hosts/prod.yml] snapraid-get-logs.ansible.yml
Runs an occ command inside the Nextcloud instance. The command is prompted before executing it. It should not contain the occ
part but only its args.
ansible-playbook [-i hosts/prod.yml] nextcloud-occ.ansible.yml
Runs a command inside the Minecraft console. The command is prompted before executing it.
ansible-playbook [-i hosts/prod.yml] minecraft-execute.ansible.yml