> ## Documentation Index
> Fetch the complete documentation index at: https://ona.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optional: Make Ona Your Own

> Personalize your Ona experience with dotfiles, profile-level variables, and IDE settings

You've learned how Ona standardizes environments for teams. Now let's make those environments feel like yours. This lab covers three ways to carry your personal setup into every environment you create, without affecting your teammates.

## 1. Dotfiles: Your shell, your way

Dotfiles are configuration files (`.zshrc`, `.gitconfig`, `.vimrc`, etc.) that define your shell aliases, editor preferences, Git identity, and tool configs. Ona clones your dotfiles repo into every new environment automatically.

### Set up your dotfiles repository

1. Create a Git repository containing your config files. If you don't have one yet, [GitHub's dotfiles guide](https://dotfiles.github.io) is a good starting point.

2. Add an install script. Ona looks for the first of these files and runs it:
   * `install.sh` / `install`
   * `bootstrap.sh` / `bootstrap`
   * `setup.sh` / `setup`

3. Point Ona to your repo:
   * **Web UI**: Go to [Settings → Preferences](https://app.ona.com/settings/preferences) and enter your dotfiles repository URL
   * **CLI**: Run `ona user dotfiles set --repository https://github.com/you/dotfiles`

### Example install script

A minimal `install.sh` that sets up zsh, aliases, and Git config:

```bash theme={null}
#!/bin/bash
set -e

# Set zsh as default shell
sudo chsh "$(id -un)" --shell "/usr/bin/zsh"

# Symlink dotfiles into home directory
ln -sf ~/dotfiles/.zshrc ~/.zshrc
ln -sf ~/dotfiles/.gitconfig ~/.gitconfig
ln -sf ~/dotfiles/.vimrc ~/.vimrc

# Install tools only if missing
if ! command -v fzf >/dev/null 2>&1; then
    echo "Installing fzf..."
    FZF_VERSION="0.60.3"
    curl -sL "https://github.com/junegunn/fzf/releases/download/v${FZF_VERSION}/fzf-${FZF_VERSION}-linux_amd64.tar.gz" | tar xzf -
    sudo mv fzf /usr/local/bin
fi

echo "Dotfiles installed."
```

### Try it: Verify your dotfiles

If you've configured a dotfiles repo, open a terminal in your environment and check:

```bash theme={null}
# Confirm dotfiles were cloned
ls ~/dotfiles/

# Check your shell
echo $SHELL

# Verify a custom alias (if you defined one)
alias
```

### Best practices

* **Keep the install script fast**: it runs on every environment start. Heavy installs slow down startup.
* **Make it non-interactive**: the script runs without a TTY. Commands that prompt for input will hang.
* **Don't store secrets**: use Ona's [secrets feature](/ona/configuration/secrets/overview) instead.
* **Check before installing**: guard tool installs with `command -v` checks so they're idempotent.

### Updating dotfiles in a running environment

Changes to your dotfiles repo apply automatically to new environments. For a running environment:

```bash theme={null}
cd ~/dotfiles && git pull && ./install.sh
```

***

## 2. Profile-level variables: Your personal config everywhere

User secrets are personal key-value pairs available in every environment you create. They're ideal for personal tokens, preferred settings, and config that shouldn't be shared with the team.

User secrets **override** project and organization secrets with the same name, so you can customize behavior per-user without changing shared config.

### Create a user secret

1. Navigate to [Settings → My Account → Secrets](https://app.ona.com/settings/secrets)
2. Click **New Secret**
3. Choose **Environment Variable**
4. Set the name and value

### Common user-level variables

| Variable          | Purpose                                         |
| ----------------- | ----------------------------------------------- |
| `GITHUB_TOKEN`    | Personal GitHub access token                    |
| `LINEAR_API_KEY`  | Personal Linear API key                         |
| `NPM_TOKEN`       | Private npm registry access                     |
| `EDITOR`          | Preferred terminal editor (`vim`, `nano`, etc.) |
| `GIT_AUTHOR_NAME` | Override Git author name                        |

### Try it: Set and verify a variable

1. Go to [Settings → My Account → Secrets](https://app.ona.com/settings/secrets)
2. Create a new environment variable:
   * **Name**: `MY_WORKSHOP_VAR`
   * **Value**: `hello-from-ona`
3. Start a new environment (or restart your current one)
4. Verify:

```bash theme={null}
echo $MY_WORKSHOP_VAR
# Output: hello-from-ona
```

### How precedence works

When multiple secrets share the same name, Ona resolves them in this order:

1. **User secrets** (highest priority; yours win)
2. **Project secrets** (shared within a project)
3. **Organization secrets** (shared across the org)

This means you can override a team-wide `API_BASE_URL` with your own staging endpoint without affecting anyone else.

### Environment variables vs file secrets

|                | Environment variables                                | File secrets                          |
| -------------- | ---------------------------------------------------- | ------------------------------------- |
| **Access**     | `$VAR_NAME` in shell, `process.env.VAR_NAME` in code | Read from a file path                 |
| **Visibility** | Visible in `ps auxe`, logs, crash dumps              | Not visible in process listings       |
| **Best for**   | Config values, feature flags, rotatable API keys     | Passwords, private keys, certificates |

For sensitive credentials that can't be easily rotated, prefer [file secrets](/ona/configuration/secrets/files).

***

## 3. IDE settings: Preserve your editor across environments

Ona environments are ephemeral, but your editor preferences don't have to be. There are two layers of IDE customization: **project-level** (shared with the team via `devcontainer.json`) and **personal** (synced across environments via Settings Sync or dotfiles).

### Project-level: devcontainer.json customizations

Extensions and settings defined in `devcontainer.json` apply to everyone on the project:

```json theme={null}
{
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      }
    },
    "jetbrains": {
      "plugins": ["com.wix.eslint"]
    }
  }
}
```

This is the team baseline. Everyone gets the same extensions and formatting rules.

### Personal: VS Code Settings Sync

To carry your personal VS Code theme, keybindings, snippets, and extensions across environments:

1. Open VS Code (desktop or browser)
2. Turn on **Settings Sync**: `Cmd+Shift+P` → `Settings Sync: Turn On`
3. Sign in with your GitHub or Microsoft account
4. Select what to sync:
   * Settings
   * Keybindings
   * Extensions
   * Snippets
   * UI State

Once enabled, every new environment you open in VS Code will pull your synced preferences automatically. This works in both VS Code Desktop and VS Code Browser.

See the [official Settings Sync documentation](https://code.visualstudio.com/docs/configure/settings-sync) for details.

### Personal: Editor config via dotfiles

For terminal-based editors (Vim, Neovim, Emacs) or additional VS Code settings, include config files in your dotfiles repo:

```bash theme={null}
# In your dotfiles repo
.vimrc              # Vim configuration
.config/nvim/       # Neovim configuration
.config/Code/User/  # VS Code settings (alternative to Settings Sync)
```

Your dotfiles install script symlinks these into place, so they're available in every environment.

### Try it: Check your editor setup

1. Open your environment in VS Code
2. Check which extensions are installed: `Cmd+Shift+X` / `Ctrl+Shift+X`
3. Verify Settings Sync status: `Cmd+Shift+P` → `Settings Sync: Show Synced Data`
4. If you use a terminal editor, confirm your config loaded:

```bash theme={null}
# For Vim users
vim --version | head -1

# Check if your vimrc is in place
ls -la ~/.vimrc
```

***

## Putting it all together

Here's how the three personalization layers combine:

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#ffffff','primaryTextColor':'#000000','primaryBorderColor':'#000000','lineColor':'#000000','secondaryColor':'#ffffff','tertiaryColor':'#ffffff'}}}%%
graph TB
    A[Team Base<br/>devcontainer.json] --> B[Your Dotfiles<br/>shell, git, tools]
    A --> C[Your Secrets<br/>tokens, config]
    A --> D[Your IDE Settings<br/>Settings Sync]
    B --> E[Your Personalized<br/>Environment]
    C --> E
    D --> E
```

| Layer               | Scope    | Managed by | Applies to              |
| ------------------- | -------- | ---------- | ----------------------- |
| `devcontainer.json` | Project  | Team       | Everyone on the project |
| Dotfiles            | Personal | You        | All your environments   |
| User secrets        | Personal | You        | All your environments   |
| Settings Sync       | Personal | You        | All VS Code instances   |

The team defines the baseline. You layer your preferences on top. Every environment feels like home without drifting from the team standard.

## What you've learned

You now know how to:

* **Configure dotfiles** to bring your shell, Git, and tool preferences to every environment
* **Set user-level secrets** for personal tokens and config that override team defaults
* **Sync IDE settings** so your theme, keybindings, and extensions follow you across environments

***

**Workshop complete!** Return to [Workshop Overview](/workshops/overview) to review what you've learned, or explore the [Examples Library](/workshops/optional-examples) for more configurations.
