# systemd services

Create, edit, control and delete systemd services on a VPS, with rollback if they fail to start and journal logs.

Source: https://ardumaker.com/en/docs/systemd/

- Category: Servers and infrastructure
- Status: Available
- Requirements: A running company VPS; Being a company member with access to the VPS; A system with systemd (Ubuntu 16.04 is not supported; check with `ver_funciones_vps`)
- MCP tools (Read only): `listar_servicios_vps`, `ver_servicio_vps`, `ver_logs_systemd_vps`
- MCP tools (Write or modify): `crear_servicio_vps`, `editar_servicio_vps`
- MCP tools (Destructive): `eliminar_servicio_vps`, `controlar_servicio_vps`

## What can you do with it?

- List every service on the VPS and see one in detail: its unit file, whether it is active and whether it starts at boot.
- Create a service from the full content of a unit file.
- Replace the unit file of an existing service.
- Start, stop, restart, enable or disable a service.
- Delete a service (except protected ones) and read its logs.

## When should you use it?

- A process that must keep running and does not belong to an ArduMaker app: a worker, a bot, a metrics exporter.
- Restarting a service after changing its configuration.
- Checking why a service keeps crashing.

> **INFO:** What the Apps catalog offers is installed with Apps, and the processes of a Git app go in its deploy configuration: that way the platform shows them, restarts them on each deploy and backs them up. A standalone systemd service is for what fits neither case.

## How does it work in ArduMaker?

### Create

1. The name is validated: lowercase, and spaces and `/` become hyphens. Only letters, digits and `_ . @ : -`, up to 200 characters; otherwise `nombre_invalido`.
2. If `/etc/systemd/system/<nombre>.service` already exists, a `.backup` copy is saved.
3. The content is written as received (no extra validation), with 644 permissions.
4. `systemctl daemon-reload`, then `systemctl start` and `systemctl enable`.
5. If any of those steps fails, the new unit is deleted, the copy is restored and systemd is reloaded. The answer says which step failed (`Failed to start service`, `Failed to enable service`…).

In practice, creating a service always leaves it running and enabled at boot; a service that does not start is not left behind.

### Edit

Editing replaces the whole file with the same procedure, but it runs `start`, not `restart`: **if the service was already running, it keeps the previous configuration** until it is restarted with `controlar_servicio_vps` and the `restart` action.

### Control and delete

- `start`, `stop` and `restart` act now; `enable` and `disable` only change whether it starts with the system.
- Control has no protected list: `nginx` or `docker` can be stopped.
- Deleting stops, disables, removes `/etc/systemd/system/<nombre>.service` and reloads systemd. A unit that came with a system package is stopped and disabled, but its file is not in that folder and is not deleted.
- These cannot be deleted: `ssh`, `sshd`, `networking`, `systemd-journald`, `systemd-logind`, `docker`, `containerd`, `nginx`, `apache2`, `mysql` and `postgresql`.

## What actually changes?

- `/etc/systemd/system/<nombre>.service` (644) and the `enable` link for system boot.
- The running process, with standard output and error in the journal.
- An entry in the VPS activity log for each creation, edit, action or deletion.

## Unit example

A unit like the one ArduMaker builds for deploy processes:

```ini
[Unit]
Description=mi-worker
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/mi-worker
Environment="MODO=produccion"
ExecStart=/opt/mi-worker/venv/bin/python worker.py
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
```

- `Restart=always` brings it back up if it crashes.
- `StandardOutput=journal` makes `ver_logs_systemd_vps` show its output.
- `WantedBy=multi-user.target` is what makes `enable` possible.

## Diagram

**Creating a service**

```text
Request (name + unit content)
  ↓
Name validation (nombre_invalido)
  ↓
VPS agent (writes the unit and keeps a copy)
  ↓
systemd (daemon-reload → start → enable)
  ↓
Result (active and enabled, or rollback)
```

## Expected result

- The create, edit and control answers include `status`, `is_active` and `is_enabled` read after the operation.
- `ver_servicio_vps` returns `service_file`, `content`, `status`, `is_active`, `is_enabled` and `details`.
- `ver_logs_systemd_vps` returns the last 500 lines of the service journal.

```bash
systemctl status mi-worker
journalctl -u mi-worker -n 100 --no-pager
```

## Errors and troubleshooting

| Answer | Cause | What to do |
| --- | --- | --- |
| `Failed to start service` | The process did not start; the creation was reverted | Check `ExecStart`, paths and permissions; read the logs |
| `Failed to reload systemd daemon` | The unit has a format error | Fix the content |
| 403 on delete | Protected name | Stop or disable it instead |
| 404 `Service not found` | That service does not exist | List first |
| `nombre_invalido` | Characters not allowed in the name | Use the valid format |
| `funcion_no_disponible` (409) | The VPS system has no usable systemd | Retrying does not help |
| I changed the unit and nothing happened | Editing runs `start`, not `restart` | Restart the service |

Creating and editing are safe to repeat with the same content. `controlar_servicio_vps` is not, in general (repeating a `stop` or `restart` cuts the service again), and it can stop critical services. If the VPS does not answer, the error can be retried (424).

## MCP access

Yes, in the `/mcp` and `/mcp/vps` profiles. A read-only agent only sees `listar_servicios_vps`, `ver_servicio_vps` and `ver_logs_systemd_vps`.

| Tool | Type | Notes |
| --- | --- | --- |
| `listar_servicios_vps`, `ver_servicio_vps` | Read | — |
| `ver_logs_systemd_vps` | Read | Comes marked as untrusted content |
| `crear_servicio_vps` | Write | Accepts `idempotency_key` |
| `editar_servicio_vps` | Write | Full replace |
| `controlar_servicio_vps` | Destructive | No protected-service guard |
| `eliminar_servicio_vps` | Destructive | Rejects protected names |

For the processes of a Git app, prefer `ver_config_deploy_app` and `guardar_config_deploy_app` over these tools. Reference at [/mcp/docs](https://ardumaker.com/en/mcp/docs) and examples at [/mcp/servicios](https://ardumaker.com/en/mcp/servicios).

## Related features

- [Scheduled tasks](https://ardumaker.com/en/docs/cron/)
- [GitHub deploy](https://ardumaker.com/en/docs/github-deploy/)
- [Monitoring](https://ardumaker.com/en/docs/monitorizacion/)
- [Web terminal](https://ardumaker.com/en/docs/terminal-web/)
- [VPS servers](https://ardumaker.com/en/docs/vps/)
