--- title: "Add startup scripts to a VM" description: "Write a startup script for a TIR Virtual Machine and attach it so it runs as root each time the VM boots, to install packages or set up the system again." content_type: "how-to" product: "tir-vm" platform: "TIR" url: "/tir/tir-vm/how-to/add-startup-scripts-to-a-vm/" topic: ["create-and-connect"] --- # Add startup scripts to a VM A startup script is a shell script that runs as `root` every time a TIR Virtual Machine (VM) boots, the first boot and every one after it. Use one to install packages, fetch your files, or start a service, so the VM sets itself up on its own after each restart. ## Before you begin - The commands for the script, tested by hand on the VM if you can. See [Connect to a VM over SSH](/tir/tir-vm/how-to/connect-to-a-vm-over-ssh/). - Permission to update VMs in the project, to change the scripts of a VM that already exists. See [TIR Access Control](/tir/tir-iam/). Startup scripts belong to the project, so one script can be attached to several VMs. ## Write the script Every script runs on every boot, so write it so that running it again is safe. Install a package only when it is missing, and overwrite a settings file instead of adding the same lines to it again. This example is for an image that uses `apt`. It installs `htop` on the first boot, starts a service of your own on every boot, and records each boot in a file: ```bash #!/bin/bash if ! command -v htop >/dev/null; then apt-get update -q apt-get install -y -q htop fi systemctl enable --now echo "booted at $(date)" >> /root/boot-log.txt ``` Replace `` with the name of a service you have installed on the VM, or delete that line. Each script runs with `bash`, so the first line is optional. ## Save the script 1. In **Manage VMs**, select the VM's name, go to **Network & Security**, and select the **Start Scripts** side tab. 2. Enter a **Script Name** of three to 50 characters: letters, digits, hyphens, and underscores, starting with a letter and ending with a letter or digit. It must be unique in the project. 3. Paste the commands into **Enter Script**, or select **Upload file** to load a `.sh` file. 4. Select **Save Script**. The script is saved in the project, ready to attach. Attaching it to a VM is a separate step. You can also write a script while you create a VM: open **Advanced Settings**, and under **Startup Script**, select **Create a new Script**. ## Attach the script to a VM On a new VM, open **Advanced Settings** on the **Create VM** form and pick the scripts in **Select startup scripts**. They run when the VM first starts, and on every boot after that. See [Create a VM](/tir/tir-vm/how-to/create-a-vm/). On a VM that already exists: 1. On the **Start Scripts** side tab, select **Add Script**, or **Modify Script** once the VM has scripts. 2. Select the script in the **Search script name** list. 3. Select **Update**, then **Confirm** in **Confirm Attached Scripts**. The script runs the next time the VM boots. To run it now, [restart the VM](/tir/tir-vm/how-to/stop-start-and-restart-a-vm/#restart-a-vm). ## Edit, detach, or delete a script - To edit a script, select it or **Edit Script**, change it, and select **Save Script**, then **Confirm** in **Confirm Script Editing**. The change applies to every VM the script is attached to, after each one restarts. - To detach a script, remove it from the attached scripts, then select **Update** and **Confirm**. The script stops running on that VM from its next boot. - To delete a script, first detach it from every VM that uses it. Then select **Delete Script** beside it, and select **Confirm** in **Delete Script**. ## Check that the script ran A startup script leaves its output inside the VM, so check its work there. Sign in over SSH once the VM is **Running**. A script can still be running for a short while after that. For the example above, run: ```bash cat /root/boot-log.txt ``` Each boot adds a line. The scripts themselves are in `/opt/e2e/startup-scripts`, read-only, where you can read exactly what runs. For how the scripts are ordered and what happens when one fails, see [How do startup scripts run?](/tir/tir-vm/faq/#how-do-startup-scripts-run) in the FAQ. To give several VMs the same large data instead of downloading it at each boot, [mount a dataset or a shared file system](/tir/tir-vm/how-to/mount-datasets-and-file-systems-on-a-vm/).