AI and LLMsWritten by GLWS12 min readUbuntu 24.04 LTS / AlmaLinux 9
Commands run on your server unless a section says otherwise. Replace example usernames, addresses and paths with your own values. Keep a working session open when changing remote access.

Why a hosted API is often the right choice

A CPU-only VPS cannot run large models at useful speed. A hosted API gives you strong models on demand, and your small server only needs to send requests and handle the answers. That keeps the plan cheap and the application simple. The costs are per-request charges, data leaving your server and dependence on a provider.

This guide uses placeholder names and a generic request, because every provider documents its own endpoint and fields. Read your provider's documentation for the exact URL, headers and model names.

Keep the key out of your code

An API key is a password that spends money. Never write it into source files, commit it to a repository or paste it into a chat or ticket. Store it in a file that only root and the service can read, and load it into the process as an environment variable.

This example uses the myapp service account from the Node application guide. Create that service account first or replace the group with the actual application group. Administrators use sudo to manage the file; do not make it world-readable to run a shell test.

Both systems
sudo mkdir -p /etc/myapp
sudo tee /etc/myapp/ai.env >/dev/null <<'EOF'
AI_API_KEY=PASTE_YOUR_KEY_HERE
AI_API_URL=https://api.example-provider.com/v1/chat/completions
AI_MODEL=model-name-from-the-provider
EOF
sudo chown root:myapp /etc/myapp/ai.env
sudo chmod 640 /etc/myapp/ai.env
ls -l /etc/myapp/ai.env

Load it with systemd

Reference the file from the service unit with EnvironmentFile. The process then sees the key as an environment variable and no other user can read the file. Avoid putting the key on the command line, where other users can see it with ps.

Add to the [Service] section of your unit file
EnvironmentFile=/etc/myapp/ai.env
Apply
sudo systemctl daemon-reload
sudo systemctl restart myapp
sudo systemctl show myapp -p EnvironmentFiles

Make a request from the shell

Test the key and the endpoint with curl before you write application code. Using a variable keeps the key out of your shell history if you read it from the file. The request body depends on the provider; this is the common chat-style shape.

Both systems
sudo bash <<'EOF'
set -a; . /etc/myapp/ai.env; set +a
curl --fail-with-body -sS -m 60 "$AI_API_URL" \
  -H "Authorization: Bearer $AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"$AI_MODEL\",\"max_tokens\":100,\"messages\":[{\"role\":\"user\",\"content\":\"Say hello in five words.\"}]}"
EOF
Run this as a user that can read the file, such as with sudo -u myapp. Check how your provider names the maximum-output setting, because it varies.

Set timeouts, retries and limits in your code

Network calls fail and AI calls are slow. Always set a request timeout. Retry only on temporary errors such as timeouts, rate limits and server errors, with a growing delay and a small maximum number of attempts. Cap the output length with the provider's max-tokens setting, and limit how much text your users can send, since the length of the prompt is part of the cost.

Do not let the public call your API endpoint freely. Put rate limits in front of any route that triggers a paid request, and require a login for anything that is not a demo.

Control cost and watch usage

Set a monthly spending limit and an alert in the provider's dashboard, if it offers them, and use a separate key for each application so one project's usage and leaks are easy to isolate. Log the number of requests and tokens for each call, not the prompts, and check the totals. A loop or a bot can spend your budget in hours.

Count API errors and calls in your service logs
sudo journalctl -u myapp --since today --no-pager | grep -c "ai request"
sudo journalctl -u myapp --since today --no-pager | grep -ci "rate limit"

Protect private data

Anything in the prompt leaves your server and is processed by the provider under its terms. Do not send passwords, customer personal data or confidential documents unless the provider's terms and your own obligations allow it. If you must work with sensitive text, consider a local model, and read the Ollama and sizing guides.

Rotate a leaked key

If a key appears in a repository, a log or a screenshot, treat it as compromised. Create a new key in the provider's dashboard, put it in the environment file, restart the service, then delete the old key. Check the provider's usage page for unexpected requests, and search your files and logs for any other copy.

Both systems
sudo nano /etc/myapp/ai.env
sudo systemctl restart myapp
sudo grep -rIl "sk-" /home /opt /var/www 2>/dev/null | head
The grep pattern is only an example. Use the real prefix of your provider's keys, and review any matches.

Official documentation

These upstream references provide more detail on the commands and workflows in this guide.