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

# Installation

> Step-by-step guide to installing StartMyVPN on your server.

<Note>
  Before you start, make sure PHP 8.4 and the IonCube Loader v15+ are installed and verified with `php -v`. See [Requirements](/getting-started/requirements) for details. Skipping this will cause the application to fail during `composer install` with `cannot be decoded by this version of the ionCube Loader`.
</Note>

## 1. Upload the application files

Download the latest StartMyVPN release `.zip` from your customer portal and upload it to your server, then extract it:

```bash theme={null}
# Upload the zip via SFTP / SCP, then on the server:
unzip startmyvpn-latest.zip -d /var/www/startmyvpn
cd /var/www/startmyvpn
```

## 2. Install PHP dependencies

```bash theme={null}
composer install --no-dev --optimize-autoloader
```

## 3. Install and build front-end assets

Assets are compiled on each install so your branding, theme colors, and any per-client customizations are baked into the bundle. Run both commands from the release directory:

```bash theme={null}
npm ci
npm run build
```

<Note>
  Use `npm ci` (not `npm install`) to install the exact versions from `package-lock.json`. This guarantees the build matches what was tested against this release.
</Note>

After a successful build you'll see the compiled files under `public/build/` and a `manifest.json` that Laravel's `@vite` directive uses to reference them.

## 4. Create the environment file

```bash theme={null}
cp .env.example .env
php artisan key:generate
```

## 5. Configure the environment

Open `.env` and set the core values:

```ini theme={null}
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=startmyvpn
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password
```

<Warning>
  `APP_URL` must match the exact scheme (`http://` vs `https://`) and host that visitors use in the browser. A mismatch causes the `@vite` helper to generate asset URLs on the wrong scheme, which shows up as TLS errors or blank-styled pages.
</Warning>

Then create the database and run migrations:

```bash theme={null}
mysql -u root -p -e "CREATE DATABASE startmyvpn CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
php artisan migrate --force
```

## 6. Seed initial data

```bash theme={null}
php artisan db:seed
```

This creates the default admin account and initial settings.

## 7. Publish Livewire assets

```bash theme={null}
php artisan livewire:publish --assets
```

<Warning>
  This step is required. Skipping it will cause blank pages and broken admin panel functionality because Livewire's JavaScript assets will not be served.
</Warning>

## 8. Set storage permissions

```bash theme={null}
sudo chown -R www-data:www-data /var/www/startmyvpn/storage /var/www/startmyvpn/bootstrap/cache
sudo chmod -R 775 /var/www/startmyvpn/storage /var/www/startmyvpn/bootstrap/cache
```

## 9. Create the storage symlink

```bash theme={null}
php artisan storage:link
```

## 10. Optimize for production

```bash theme={null}
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

## 11. Access the app

Point your web server at `/var/www/startmyvpn/public` (see [Web Server](/getting-started/web-server) for Nginx/Apache configs), then open your domain in a browser. The first-run setup wizard at `/setup` walks you through the rest of the configuration.

<Note>
  Default admin credentials are created by the seeder. Change your password immediately after first login from **Admin → Settings → Profile**.
</Note>

***

## Update procedure

When a new version is released, download the updated `.zip`, replace the application files (keeping your `.env` and `storage/` directory), then run:

```bash theme={null}
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan migrate --force
php artisan livewire:publish --assets
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart
```

<Note>
  Always back up your database before running `php artisan migrate --force` on a new release.
</Note>
