I usually connect with my server via ssh in a terminal and run basic commands. What’s a better, more efficient and modern way of doing that? Especially considering ai and documentation along the way?
I wonder if there’s a better approach than “connect from remote and act local”. Is there a method to “code local and push to remote”?
I use a fedora server with podman, caddyfile and vi.
Ansible is one way to “code local, push to remote(s)”. Can define so-called playbooks, which is basically just a script, to do reoccuring tasks like e.g. updates.
Ansible is great, I just wish it would automatically cleanup when I remove parts of the config. I know it’s not the goal, but I dream about a tool that works this way
That works but that’s only useful if you have many machines. I have a single server so it’s the same burden as doing it manually. If only the uninstall step could be completely automated by just reverting the install step
To be fair to Ansible, that’s probably a packaging issue.
If the 1st run of an application creates a bunch of files and folders, then the packager won’t know about them and Ansible’s just relying on that.
But yeah, for 1 machine I’d find Ansible overkill (not a problem per se), but really helps when you have 5 Rasperry Pi Zeros scattered around the house 😉
I generally find writing a good role takes longer than doing it manually. Especially as you have to keep testing failure conditions as you think of them.
However, the point is, that once you’re finished with the role, you never have to do that process again.
Not if you want to rebuild
Not if you want to migrate to a new os
Not if you build a second server
Not if you move to a newcloud hosting provider
Porting to a new OS or after an update that changes how the software works is about as fast as doing it manually
Maybe it’s only one server today, but how many times would you need to rebuild it over the running lifetime?
The killer feature is that having something like ansible lets you kill your darlings, and keep servers aa cattle, not pets.
Manual setup chops isn’t a different skill here. I view ansible as a combination setup and documentation. If you’re going to figure out how, why not write down how you did it? If you’re going to write it down complete with code lines to run, why not script it?
If you’re talking about going in and restarting containers and checking logs, there are tools like Portainer that give a nice UI you can quickly use from your phone
If you’re talking about repetitive tasks, sometimes there’s a tool to automate it already (e.g. updates via watchtower, unattended-upgrades), and if not, you can write a script and possibly run it via a cronjob if that makes sense
If you’re talking about doing new stuff, you either stick with the SSH & shell commands, or you look into IaC tools like ansible as another reply mentioned. Another option is something like Nix where the setup is defined in config, so you make your changes there
There are probably multiple flashy clients and gui’s for it, but if you’re already used to the terminal, I’d recommend rsync. This might be the wrong syntax but something like rsync -av ~/local/project servername:/var/www/html/ would take your local files and update the web directory of your server with only the files that are more recent. Rsync will even read your ssh config file so if you’re got an entry for your server you can just use the host name.
I ran a little blog for a while using a static site generator so I setup the git server on my web server and wrote a git hook where every time I pushed to the repo the server would pull it’s cloned copy of the repo into the html directory. Took me a few hours to setup but it made updating the blog as simple as pushing to the repo.
I wait for something to break. Then I yell “God fucking dammit, I don’t have time for this right now!” and spend an hour triaging things before I just try docker down, pull, up and everything works.
Early on I wrote a script for my user account to run df and save the output to a file, then a second script to read that file and if the drive was full send me an email.
First, it failed because it couldn’t send the email because the email service failed under full disk conditions.
Second, it failed because it couldn’t write the file to disk because the disk was full.
Third, it failed because outbound SMTP was blocked by my ISP.
I learned a lot about how well you can fail if you really put your mind to it. Now I have Home Assistant grabbing the disk stats for my machines and flagging anything over 90%.
“code local and push remote” is only more efficient if you have a faulty connection with ssh or want to use a GUI editor that doesn’t support remote connections. What you’re doing is good. You can scoure for more “modern” ways that might have more glimmer and sparkly lights, but it won’t improve efficiency.
Declarative configuration (like docker compose) is basically “code local, push remote”, and it has a lot of benefits, including improving efficiency because you have a clearer idea of exactly what is set up on the server, to make it easier to debug or make changes.
Contrast this with just sshing in and running a bunch of commands to install something. Then coming back months later and wondering “what files did I touch? what packagea did I install? Hmm dpkg log says I added X but then later I removed it, so was it important?” Etc.
Nothing wrong with good old ssh. My VMs are different enough that building and maintaining ansible playbooks or something similar would be a bigger task than actually doing it in the traditional way. Maybe I could benefit by building simple playbooks to populate user accounts, ssh keys, smtp relay settings and other common things, but I don’t really set up new servers that often that it would justify spending time to set up tools for that.
Ansible and terraform can bath do with you want though for a single server I’d consider them both to be a somewhat overkill. But then again homelabbing often is about overkill.
Hermes + maybe $5-10 worth of tokens if I need more compute than ollama can provide (on a busy month). Running everything in a nice podlet setup and have reduced maintenance down to trivial levels. Config gets occasionally shipped to GitHub
In theory I might lose the ui if it bricked itself but in reality that doesn’t happen.
I bet you I do less work and have a more efficient and locked down network, file permissions, fully rootless, updated on the hour, 100% in code, and observable setup than 98% of you just running sudo apt upgrade and praying. But yeah, my little agent working in an nemoclaw sandbox is going to go rogue and destroy my server somehow and I definitely believe the AI hype bros that are definitely “accidentally “ are hacking orgs and not going to end the human race🙄
Man, the ignorance and prejudice over how llm work is insane.
It’s not about “going rogue”. It’s about making mistakes. It’s not a hypothetical. It has happened many times to people who were as confident as you seem to be with their setup. There’s a proverb in my language that roughly translates to “some learn by looking at others, while some need to experience it by themselves”. Maybe you’re in the latter category.
Humans definitely don’t make mistakes. Especially not with their jank home servers. All of it done without shortcuts and auditable in code, with a standard process.
You’ve set some imaginary high bar that is rarely actually met outside of nerds shit talking on the internet and a small percentage of users.
“Hey slop machine, you fucked up. Restore the last backup and document the mistake you made in AGENTS.md so we avoid making that mistake again. Im going to go make a coffee, brb”
So again, because we make backups before letting AI touch anything:
“Hey slop machine, you fucked up. Restore the last backup and document the mistake you made in AGENTS.md so we avoid making that mistake again. Im going to go make a coffee, brb”
On Monday, two days after the incident occurred, Mr Crane confirmed that the data had been recovered. The Independent has reached out to Anthropic and Cursor for comment.
with dokplpy as a server docker managementweb gui.
for the code push workflow:
keep your normal git workflow, commit & push
set up a git hook in git & dokploy that rebuilds from source on every push
or do it on a schedule and build once a day or whatever
If you’re project has an unusual way to build, you could also do a git action that pushes a docker image out somewhere, depending on yoyr git provider.
If you need a step bt step breakdown, I can give you a guide based on my personal website, but that might not apply to your project.
I created git repos on my main workstation for each homelab server/service I maintain that keeps:
documentation
notes
lessons learned
scripts, configs
runbooks
backup details
security audit details
log items that need attention
infrastructure
I just point a local LLM (offline model that runs on my workststion) into those repos and ask it to perform certain things on those servers. It can do things like update packages, install packages, make config changes, set/check permissions, read logs (and fix errors in real time), and check the health of the overall system.
I have it run pre backups before making changes, then post backups once its done.
Once changes are in place and everything is running okay, I ask it to update documentation in the repo and tag the release.
I use opencode that connects to a llama.cpp service. opencode lets me gate the AI so that any elevated commands that it needs to run (e.g. sudo or ssh), I have to approve it. It cant just go around making changes without permission.
I connect to my server using ssh and use tmux as a persistent session. Configuration wise, I use NixOS and edit the config files directly on the server via emacs.
set the server as git remote and push there directly. set hooks to deploy. I do that for a static site. Is my little iac solution. Search for alternatives to “infrastructure as code”. It can go from simple dockerfile to swarms or kubernetes…
It depends on what I’m doing I suppose. I run my main VM on Proxmox, so I mainly use its web interface for any VM work. For all the containers within, I’ve been really loving Dockhand lately, it’s just as easy to use as Portainer, it even checks for updates for me AND gives me a link for the release notes so I can decide whether to upgrade or not.
Most other things like file transfers or editing my Caddyfile I do through SSH. Can’t beat simplicity sometimes!
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
Fewer Letters
More Letters
DNS
Domain Name Service/System
Git
Popular version control system, primarily for code
ISP
Internet Service Provider
LVM
(Linux) Logical Volume Manager for filesystem mapping
NAS
Network-Attached Storage
NFS
Network File System, a Unix-based file-sharing protocol known for performance and efficiency
Plex
Brand of media server package
RAID
Redundant Array of Independent Disks for mass storage
SFTP
Secure File Transfer Protocol for encrypted file transfer, over SSH
SMTP
Simple Mail Transfer Protocol
SSH
Secure Shell for remote terminal access
VPS
Virtual Private Server (opposed to shared hosting)
ZFS
Solaris/Linux filesystem focusing on data integrity
k8s
Kubernetes container management package
I’ve been using a program someone on Lemmy has been writing: SSHPilot. It helps keep my server list organized and can easily ssh to the machines or open up a file browser for easy drag and drop of files if I have some quick files to move around. It copies ssh keys easily as well.
I went through maybe a dozen different setups before I landed on OpenMediaVault. For 90% of what I need to do, I can stick to the webUI and when that doesn’t cut it, it’s just a Debian system underneath so the terminal is easy too.
I deploy with ansible keys and install ssh with a keys-only config and only ansible access.
Then I run some standard installs and configs with ansible and all future updates to apt, apk and docker are done with one ansible playbook.
I don’t include the ansible host itself in the automation, nor my workstation, just to prevent everything from being broken at once if something goes wrong.
It’s good to get comfortable in the command line, including over ssh.
Especially considering ai and documentation along the way?
If I am going to ask AI or Google about something, I just do that to help me find the answer and then apply the answer myself. That way I learn, and can double check the AI isn’t hallucinating, at least on in obvious ways.
As for documentation, I keep a notes folder with detailed notes on manual configuration I’ve done, how and why, and the things I’ve learned along the way. I’ve found it’s both useful to help remember the things I’ve learned, and it is useful to go back to refer to.
Proxmox web UI to manage my six containers. Sometimes I use sftp (ssh) to modify files in a desktop editor instead of nano over a web interface. Recently I broke things and had to go down to the basement with a keyboard and monitor to rollback my Omada container. I kinda want to make that part easier but it’s so infrequent it’s probably not worth it.
I have a kubernetes cluster inside of Proxmox vm’s, generally I write a deployment, commit it to a git repo and then use argocd to deploy it in the cluster.
This is not something I would advise to anyone but the clinically insane, but for me there is a certain zen in having everything in git like that. It’s for me the only way I can manage the 60ish applications I run without it having a permanent spot in my brain.
I’ll take the maverick and share my niche position. I did most if not all my proxmox setup and configuration via complete reliance on LLMs. Now, before anyone says “why would you do that”, and I’ll be straight up. I was high for all of it, and not a small blaze I’m talking regularly stoned for months. And I’ll say it “got me by” for the frame work. It worked? Sorta. Music, Plex, immich, docker, arr stack, podman. Now, I can’t say I fully understand it still and I’ve done a lot of changes since that point last year and I figured it out by asking the model to backtrack what we did and I wont lie it helped me better learn how to question the models for my job, and It did decent documnetation over my server. But again, I was literally high doing it
TrueNAS is mostly via the webgui but I use SSH when needed.
I have two Ubuntu 26.04LTS VM’s running on TrueNAS. One is going to be my web host the other is for FrigateNVR and local AI processing. They are both managed via SSH. The web host has a FIDO2 ssh key for access, the other is a standard key and is not web accessible. Both can be accessed via remote desktop when at home.
Docker containers are managed via DockHand. I have about 50 containers running across the above hosts right now.
HomeAssistant is managed via the webgui and SSH when needed. It runs on its own hardware (Odroid N2+)
My traveling local host/ap/dhcp server is primarily managed over USB via SSH. Files are managed via SFTP.
My target is terraform to provide VMs on my miniPC and ansible to configure them. For my nas, probably a basic distro then some ansible stuff to setup stomate.
Everything is in docker or a virtual machine that starts on boot. Docker containers are managed with Dockhand’s web ui. Once a month I ssh and “sudo apt upgrade” but that’s it.
I tried to use olivetin to avoid having to ssh but I ran into errors I haven’t had time to investigate yet.
I have a git repo with all my docker files, config, notes, etc. I have a main overview file covering the overall system and then a directory for each machine. I edit things on my local machine, then scp and ssh to the various remotes. Once I’m happy with my changes, I commit and push to my Forgejo install on my NAS in case my main computer fails. Secrets, passwords, and keys are in my Vaultwarden.
I don’t use AI for it, but a local model could probably give me the commands to do whatever I wanted based on the repo.
self hosted gitlab. each server has a repo with all the docker configs and application configs. also have any scripts for the server itself on there as well, things like required libs, network configs, etc.
I also have a repo dedicated for let’s encrypt SSL that retrieves new certs every month. then on each server is an install script scheduled that pulls the certs down, installs them, and restarts any services automatically.
should anything go wrong, I have a siem monitor that will alert me that a service failed to start etc.
currently running four servers like this with varying degrees of complexity.
I spent a while getting Ansible to be able to setup and maintain my server(s). And ended up not using it as much as I should, mostly because the computer I used to run Ansible from became a “Steam Machine” so I’m rarely sitting on it with a keyboard now and I don’t want to have personal info and keys on my work computer.
But it was a good learning, and useful while I used it. Now I just use ssh and compose files directly.
You upgraded from ansible to ssh. As someone forced to write yaml for ansible professionally and has used many other config management tools, I can only commend your success at escaping ansible.
Twice a year is crazy. I suppose most of my maintainence is adding drives (I’m a creator and I definitely totally need to archive all of my footage), but I also run a fair few apps that have needed manual update steps, so I do all my updates manually so I can fix stuff if it breaks.
Usually I put handcuffs on her every night, to keep her off of me, and only feed her the highest grade sushi and meat. It keeps her hair shiny, keeps good health, and complaints down to a minimum. I make sure she gets adequate sleep on an expensive mattress while I sleep on a 2 inch futon on the floor.
Premise: most, if not all, of my services run in containers.
I have recently moved to docker context. It’s a pretty cool feature that I don’t see mentioned that often. Essentially it allows to run docker commands from your machine and tunnel them via SSH to your server. What I like about this is that I need all the compose file in my main machine and structure them into a repository so that I don’t have everything scattered around. The new approach I have implemented very recently is this.
One monorepo with one folder per server and in each one a folder per service containing docker compose and .env files.
With dotenv I sent the docker context whenever I enter a specific folder, so as soon as I cd into that folder, any docker command I run from there would be tunneled to the correct server.
For everything that does not run in docker, which is not much I think at the moment only vector to collect metrics and logs, I use Ansile. In this case the need is that I want Vector to run on all servers so Ansible is the better choice here.
Tailscale service configs for HTTPS ingress and DNS resolution. Podman quadlets / podlets for everything except backup software and tailscale itself. I use the open version of VS code to edit config files in place, but I push them to a private git as well as having them backed up. Storage for app data, media, and configs (everything but OS) is via NFS shares from my gaming PC’s RAID volume. I can run a plenty of apps on an old thinkpad this way. After you configure the first few quadlets with tailscale, it gets real straightforward, but there is a learning curve. Yes, I use SSH, but it is the remote conmection and terminal in Code.
Maybe a bit more on the overkill side, but I use Talos Linux (declarative K8s distribution), then Terraform for initial setup and FluxCD for everything else (including VMs via Kubevirt). It’s a hell of an initial learning curve, but afterwards I just do my talosctl upgrade and upgrade-k8s from time to time, and don’t have to worry about anything else. Upside is, Kubernetes provides a unified, extensible API for everything, for example:
reverse proxy via Ingress or Gateway-API
firewall via NetworkPolicy
even databases like Postgres through an Kubernetes Operator like CNPG, with a similar simplicity as with the big cloud providers (just a single yaml file with the specs like storage capacity, CPU and memory limits, backup target and schedule etc.)
it is very scriptable (everything is managed via the API)
automated image updates via either FluxCD itself or just dependabot/RenovateBot creating PRs to your GitOps repo
Downsides:
you have to figure out persistent storage (CSI), which is slightly more complicated than just a single filesystem and manually specifying volume mounts like with docker, but if done right, you have a simple interface with powerful capabilities via the Kubernetes API
there are simple CSI implementations that just expose node local disks via LVM or ZFS, so if you just have a single node, or don’t care about replication, it’s fairly easy to get started
initial learning curve is quite high, especially if you have no prior experience with container orchestration in general
definitely overkill if you just want something simple that “just works”
Yes, my own hardware. But before I decided to build my own server last September, I was on a similar setup on a dedicated server at Hetzner, just less powerful (I’m so goddamn glad I bought the memory and storage back then, I probably wouldn’t even get the 192GB DDR5 right now for the price I paid for all memory and storage combined).
Terraform starts at the Talos initial machine config and cluster bootstrap including CNI setup and routing configuration (I have an opnsense in front that handles ingress routing) until FluxCD is fully set up and takes over.
Ingress traffic works via a small Hetzner VPS, and BGP through Wireguard, so there is no DNAT or SNAT between the open Internet and my Kubernetes load balancers and all services see the actual client IP. This took a shit load of time to get right, because wireguard only has an mtu of 1420, but the regular uplink is usually 1500, so pmtu discovery in my load balancers implementation (Cilium) and mss clamping in opnsense had to all be configured