A Practical Guide to Deploying AI Assistant Services on a NAS Virtual Machine
This article details how to deploy a 24/7 online AI assistant service within a NAS virtual machine. It covers the entire process from VM creation and system initialization to SSH configuration, runtime environment setup, and using systemd for process management. The guide provides practical steps, troubleshooting tips, and security best practices for maintaining a stable self-hosted AI service.
Background and Overall Architecture
An increasing number of developers want to run an always-on AI assistant or automated agent service in a private environment. This service can handle chat integrations, execute scheduled tasks, and invoke cloud-based Large Language Models (LLMs) for inference. Compared to running it directly on a laptop or desktop, deploying it in a NAS virtual machine offers two natural advantages: first, NAS devices have low power consumption and are always on, making them ideal for hosting persistent services. Second, a VM provides an isolated environment that supports snapshots and rollbacks, so if something goes wrong during experimentation, it will not affect other data on the NAS.
The overall deployment process can be summarized in five steps:
- Create a Linux virtual machine in the NAS virtualization suite;
- Complete the OS installation and initialize basic tools;
- Enable and configure SSH for remote command-line management;
- Connect to the VM via an SSH client and set up the runtime environment for the target service;
- Use systemd to manage the service process, enabling auto-start on boot and automatic restarts on crash.
Prerequisites: A NAS that supports virtualization (or any virtualization platform), sufficient disk space, and the necessary model API credentials if the service needs to invoke cloud-based LLM capabilities.
Step 1: Planning and Creating the Virtual Machine
Resource Allocation: Is 2C4G Enough?
Many people hesitate over hardware configurations before deployment. Based on practical experience, if the VM is only responsible for “orchestration and forwarding”—meaning it receives messages, organizes context, calls cloud LLM APIs, and returns results—the actual compute overhead happens in the cloud. For this scenario, 2 CPU cores and 4GB of memory (2C4G) are perfectly sufficient, with room to spare. The real factor to watch is disk space: it is recommended to allocate at least 40GB for the system disk to leave room for the runtime, dependencies, logs, and future upgrades.
If you plan to run additional components (like a container runtime or database) in the same VM later, you can scale up to 4C8G as needed. However, as an entry-level experiment, 2C4G is the most cost-effective starting point.
OS Image and Network Configuration
It is recommended to choose a mainstream Linux distribution. A desktop edition comes with a GUI, which is more beginner-friendly, while a server edition conserves resources but relies entirely on the command line. For beginners, choosing the desktop edition lowers the troubleshooting barrier, as error messages and directory structures are immediately visible.
For network mode, “Bridged” is recommended. The VM will obtain an independent IP address on the same subnet as the NAS, allowing any device on the local network to access it directly. This eliminates the need for port mapping during SSH connections and service access.
The creation process is generally standard: upload the system image to the NAS storage → create a new VM in the virtualization suite → allocate CPU, memory, and disk → mount the image and boot → follow the graphical wizard to complete the installation.
Step 2: System Initialization and Basic Tool Installation
After installing the OS, perform an initial setup in the VM console (usually a web-based VNC window). First, switch to root privileges:
sudo -i # Enter the current user password to switch to root
Then update the package index and install the necessary basic tools in one go:
apt update && apt install -y git curl wget vim openssh-server
(Commands use the apt package manager as an example; substitute with the corresponding package manager for other distributions.)
These tools serve specific purposes:
- git: Pull project code and manage versions;
- curl / wget: Download scripts and debug HTTP interfaces;
- vim: Edit configuration files from the command line;
- openssh-server: Provides SSH remote login capability, which is the foundation for all subsequent remote operations.
Step 3: Configuring SSH Remote Management
The web VNC console has two main pain points: it is difficult to copy and paste long commands, and the window is small and prone to disconnections. Therefore, configuring SSH should be the first task after OS installation.
Edit the SSH service configuration file:
nano /etc/ssh/sshd_config
Find or add the following three lines:
Port 22PermitRootLogin yesPasswordAuthentication yes
Parameter explanations:
- Port 22: Specifies the SSH listening port. The default is 22, which can remain unchanged in a local network environment.
- PermitRootLogin yes: Allows the root user to log in directly, facilitating operations during the initialization phase.
- PasswordAuthentication yes: Allows account password authentication.
After editing, press Ctrl+O to save and Enter to confirm, then press Ctrl+X to exit the editor. Restart the SSH service to apply the changes:
systemctl restart sshsystemctl status ssh # Confirm the service is in the active (running) state
Security Reminder: Allowing root password login carries high risks in a public network environment. This is only recommended for home local networks. For long-term service operation, a more secure approach is to switch to key-based authentication and disable password authentication (see Section 8).
Step 4: Connecting Remotely via an SSH Client
From any computer on the local network, use any SSH terminal tool to connect to the VM by providing four pieces of information: Host IP, Port 22, Username, and Password. If you do not know the VM’s IP address, run ip addr in the VM console to check.
Once successfully connected, it is recommended to do two things first:
- Create a standard user dedicated to deployment to avoid operating as root long-term, adhering to the principle of least privilege:
adduser deployerusermod -aG sudo deployer
- Verify network connectivity: Run a command like
curl -I https://example.comto return a status code. This confirms the VM can access the external network properly, ensuring subsequent dependency installations won’t hang.
It is worth noting that installing and running the target service typically does not require root privileges. Completing these tasks as a standard user significantly reduces the risk of accidental misconfigurations, leaving root solely for system-level administration.
Step 5: Setting Up the Runtime Environment and Hosting the Service
Installing the Runtime
Different AI services require different runtimes, typically a specific version of a server-side language environment (such as Python, Go) or running directly as a container. Using Python as an example:
apt install -y python3 python3-pipgit clone <project_repository_url>cd <project_directory>pip3 install -r requirements.txt # Or execute installation commands per project documentation
Configuring the Model API
If the service requires LLM capabilities, you typically need to provide the API Key in a configuration file or via environment variables. The model service can come from cloud platforms like Baidu AI Cloud, or any service endpoint compatible with universal interface protocols. Since API keys are sensitive credentials, it is highly recommended to inject them via environment variables rather than hardcoding them into the source code or committing them to a code repository.
Managing with systemd for Auto-Start on Boot
Running the service directly in the terminal will cause it to exit when the SSH session disconnects. The correct approach is to write a systemd service unit (example below):
# /etc/systemd/system/my-ai-assistant.service[Unit]Description=My AI Assistant ServiceAfter=network.target[Service]User=deployerWorkingDirectory=/home/deployer/appEnvironment=API_KEY=your_key_hereExecStart=/usr/bin/python3 /home/deployer/app/main.pyRestart=on-failure[Install]WantedBy=multi-user.target
Enable and start the service:
systemctl daemon-reloadsystemctl enable --now my-ai-assistantjournalctl -u my-ai-assistant -f # View logs in real-time
With this setup, the service will automatically start after a VM reboot and will be automatically restarted if the process crashes. This is the correct posture for maintaining a “long-term online” service.
Common Troubleshooting
- Cannot connect via SSH: First, run
systemctl status sshin the VM console to confirm the service is running. Then, check if the firewalls on both the NAS and the VM itself allow port 22. Finally, verify if the IP address has changed. Setting up a static IP binding in your router or virtualization suite is highly recommended. - Slow or failed dependency installation: This is usually caused by slow access to default software repositories. You can switch to a faster regional mirror source and retry.
- Service fails to start: Use
journalctl -u <service_name> -n 50to view recent logs. Most issues are caused by missing dependencies, incorrect configuration paths, or invalid API keys. - Lag or memory constraints: Running too many components simultaneously in a 2C4G environment can strain resources. Use
free -handdf -hto monitor memory and disk usage, and clean up logs or upgrade hardware configurations promptly.
Security and O&M Recommendations
Finally, here are a few recommendations for long-term operation:
- Snapshots first: Before making any major changes (like upgrading the runtime or changing configurations), take a snapshot in the virtualization suite. This allows for minute-level rollbacks if issues arise.
- Restrict privileges: Once deployment is stable, disable root password login, switch to SSH key authentication, and consider changing the default port if necessary.
- Network isolation: Keep the service exposed only to the local network. If external access is required, ensure it goes through an authenticated channel to avoid exposing bare ports.
- Regular updates: Routinely apply system patches and upgrade dependencies, but always take a snapshot before updating.
- Resource monitoring: Monitor trends in CPU, memory, and disk usage to prevent log bloat from filling up the disk and causing service anomalies.
By following the process above, going from VM creation to a persistent running service can be completed in about an hour. This methodology can be replicated across almost all self-hosted AI service deployment scenarios: first establish a solid foundation with a “remotely manageable Linux VM,” then layer on the runtime and service management, and finally ensure long-term stability through snapshots and privilege controls.
