Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions docs/02-guides/14-scripts/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
sidebar_label: Scripts
title: Scripts in Easypanel
description: Learn how to create and run reusable shell scripts directly from the Easypanel UI for your App and Box services.
---

# Scripts

Scripts in Easypanel let you define named shell commands that you can run against your services on demand, directly from the UI. They are available for both **App** and **Box** services.

Use scripts for one-off operational tasks — database migrations, cache clearing, data seeding, health checks, and anything else you would normally type into the console but want to save and reuse.

## When to Use Scripts

| Situation | Recommended tool |
|-----------|-----------------|
| Run a command once or on demand | **Scripts** |
| Run a command on a schedule | [Cron Job](/docs/guides/cron-job) |
| Keep a process running continuously | Processes |
| Explore or debug interactively | Console |

Scripts are ideal when the task is repeatable but not automatic. Instead of opening the console and typing the same command every time you deploy, you define it once and run it with a click.

## Finding the Scripts Section

1. Open your **project** in Easypanel.
2. Click on your **App** or **Box** service.
3. In the left navigation, select **Scripts**.

## Creating a Script

1. In the **Scripts** section, click **Add Script**.
2. Give the script a descriptive **name** (e.g., `migrate`, `seed-db`, `clear-cache`).
3. Enter the shell **command** to run (e.g., `php artisan migrate --force`).
4. Click **Save**.

:::tip
Name your scripts after what they do, not how they do it. `migrate` is clearer than `run-artisan-command`.
:::

## Running a Script

Once saved, each script appears as a row in the Scripts list. Click the **Run** button next to the script to execute it immediately inside your running container.

A log output panel will open so you can follow the execution in real time and confirm success or diagnose errors.

:::info
Scripts run inside the container using the same environment as your service, so all environment variables defined in the **Environment** section are available.
:::

## Editing and Deleting Scripts

- To **edit** a script, click the edit icon next to it, update the name or command, and save.
- To **delete** a script, click the delete icon and confirm.

Deleting a script does not affect your service or any previously run executions.

## Practical Examples

### Database migration (Laravel)

```bash
php artisan migrate --force
```

### Database seeding (Laravel)

```bash
php artisan db:seed --force
```

### Clear application cache (Laravel)

```bash
php artisan cache:clear && php artisan config:clear && php artisan route:clear
```

### Run Prisma migrations (Node.js)

```bash
npx prisma migrate deploy
```

### Run database migrations (Django)

```bash
python manage.py migrate
```

### Collect static files (Django)

```bash
python manage.py collectstatic --noinput
```

### Check application health (any service)

```bash
curl -f http://localhost:3000/health || exit 1
```

## Best Practices

**Keep scripts focused** — one script per task. Avoid combining unrelated operations in a single script; it makes failures harder to diagnose.

**Use `--force` or `--no-interaction` flags** — scripts run non-interactively, so commands that prompt for confirmation will hang. Pass the appropriate flags to skip prompts.

**Test in staging first** — destructive scripts (e.g., dropping tables, clearing data) should be validated in a staging environment before running in production.

**Prefer scripts over console for repeated tasks** — if you find yourself typing the same command in the console on every deploy, move it to a script.

## Conclusion

Scripts give you a simple, reliable way to manage operational tasks for your services without leaving the Easypanel UI. Whether you are running migrations after a deployment, seeding a fresh database, or clearing caches, scripts let you define the command once and run it whenever you need it.

If you have any questions or need further assistance, feel free to reach out on our [Discord channel](https://discord.gg/9bcDSXcZQ7).
219 changes: 219 additions & 0 deletions docs/03-services/08-compose/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
---
sidebar_label: Overview
title: Compose Service
description: Deploy multi-container Docker Compose stacks in Easypanel with inline or Git-based source, domain routing, redirects, security, and maintenance controls.
---

# Compose Service


The Compose Service lets you deploy multi-container applications using Docker Compose syntax directly within Easypanel. Unlike the App Service — which manages a single container — the Compose Service lets you define multiple containers, networks, and volumes in a single `docker-compose.yml` file and run them as a coordinated stack.

## Creating a Compose Service

1. Open your project and click **+ Service**.
2. In the service picker, select **Compose**.
3. Enter a **Service Name** and click **Create**.

You are taken to the service overview with all configuration tabs in the left sidebar.

## Service Controls

A persistent action bar appears at the top of every Compose service page:

| Button | Description |
|--------|-------------|
| **Deploy** | Trigger a new deployment |
| **Stop** | Stop all containers in the stack |
| **Restart** | Restart the service |
| **Logs** | View real-time log output |
| **Console** | Open an in-browser terminal |
| **Open** | Open the primary domain in a new tab |
| **Notes** | Add or view service notes |
| **Destroy** | Permanently delete the service (requires typing the service name to confirm) |

Live resource stats — CPU %, Memory, and Network I/O — are also displayed in the header. The service name shows a **COMPOSE** badge, and a rename icon lets you rename the service at any time.

## Overview

The Overview tab shows a real-time **Logs** panel that streams output from all containers in the compose stack over a WebSocket connection. Controls in the panel let you minimize, refresh, or expand the log view to fullscreen.

## Source

The Source tab is where you provide your Docker Compose configuration. It has two sub-tabs.

### docker-compose.yml

A full-featured code editor where you paste or write your `docker-compose.yml` content directly in the UI. Click **Save** to persist the compose file.

:::info
This is the quickest way to get started. Paste your existing compose file, save, and deploy.
:::

:::warning Do not expose external ports in your compose file
Do **not** use the `ports` directive in your `docker-compose.yml` to expose containers to the host. Easypanel will warn you in the console if it detects published ports, and they can conflict with other services running on the server.

Instead, use the **Domains** tab to route traffic to any internal service and port. You only need to specify the internal container port — Easypanel and Traefik handle the rest.

```yaml
# ❌ Avoid this
services:
web:
image: nginx
ports:
- "80:80"

# ✅ Do this instead — leave ports out, configure routing in the Domains tab
services:
web:
image: nginx
expose:
- "80"
```
:::

### Git

Connect a Git repository that contains your Compose file:

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| Repository URL | Yes | — | URL of the Git repository |
| Branch | Yes | — | Branch to deploy from |
| Build Path | Yes | `/` | Path within the repository |
| Docker Compose File | Yes | `docker-compose.yml` | Path to the compose file within the repository |

Click **Save** after filling in the fields, then **Deploy** to sync and run the stack.

For private repositories, generate an SSH key from the Git tab and add the public key to your Git provider.

## Deployments

### Deployment History

A list of all past deployments with their status and timestamp. Each entry can be expanded to view the full action log for that run. The empty state shows "No actions found."

### Deployment Trigger

Each Compose service has a webhook URL you can use to trigger deployments from external systems:

```
http://{server-ip}:3000/api/compose/deploy/{token}
```

Making a request to this URL triggers a new deployment. Use it to integrate Easypanel with CI/CD pipelines, GitHub Actions, or any external tool. A copy button is available next to the URL, and a **Refresh Deploy Token** button lets you regenerate the token if it is ever exposed.

:::caution
Treat the deploy trigger URL as a secret. Regenerate the token immediately if it is exposed.
:::

## Environment

The Environment tab provides a code editor where you define environment variables in `.env` format (`KEY=VALUE`). Variables defined here are made available to **all services** in the compose stack.

The **Create .env file** toggle, when enabled, instructs Easypanel to write a `.env` file that Docker Compose will automatically load at runtime.

:::info
The following magic environment variable is available within your Easypanel project:
- `$(PROJECT_NAME)`: Resolves to the project name.
:::

Click **Save** after making changes.

## Domains

The Domains tab manages which hostnames and paths route to which containers in your compose stack.

When a Compose service is created, Easypanel automatically generates a default domain:

```
https://{project}-{service}.{server-id}.easypanel.host
```

Each domain entry in the list shows its source URL, the destination URL it forwards to, and controls to make it primary (star), open it, edit it, or remove it.

### Adding a Domain

Click **Add Domain** to open the Create Domain modal, which has three tabs.

**Details**

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| HTTPS | — | On | Enable or disable HTTPS for this domain |
| Host | Yes | — | The domain or subdomain (e.g. `myapp.example.com`) |
| Path | Yes | `/` | The path prefix on the host |
| Protocol | Yes | HTTP | HTTP or HTTPS for the destination |
| Port | Yes | 80 | Target port inside the container |
| Destination Path | Yes | `/` | Path inside the destination |
| Compose Service | Yes | — | The named service within your `docker-compose.yml` to route traffic to (e.g. `web`, `api`, `worker`) |

:::info
The **Compose Service** field is unique to the Compose Service. It refers to the service name as defined inside your `docker-compose.yml` — not the Easypanel service name. Use the wand button to auto-detect running services.
:::

:::tip Use Domains instead of ports
The **Port** field here targets the container's internal port directly — you do not need to publish it in your compose file. This is the correct way to expose web services in Easypanel. Keep the `ports` directive out of your `docker-compose.yml` entirely.
:::

**Middlewares**

Add one or more Traefik middleware names to apply to this domain. Each middleware entry has a remove button.

**SSL**

| Field | Default | Description |
|-------|---------|-------------|
| Certificate Resolver | `letsencrypt` | Name of the Traefik certificate resolver |
| Wildcard Domain | Off | Enable wildcard SSL certificate |

## Redirects

The Redirects tab lets you add URL redirect rules powered by Traefik. Click **Add Redirect** to open the Create Redirect modal:

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| Enabled | — | On | Enable or disable this redirect rule |
| Regex | Yes | — | Regular expression to match incoming request URLs |
| Replacement | Yes | — | Replacement URL (supports capture groups from the regex) |
| Permanent | — | Off | Send HTTP 301 (permanent) instead of HTTP 302 (temporary) |

The **Load Sample Config** dropdown provides four presets to get you started quickly:

- WWW to Non-WWW
- Non-WWW to WWW
- Old Domain to New Domain
- Old Path to New Path

## Security

The Security tab lets you protect your service with HTTP Basic Authentication. Click **Add Basic Auth** and provide a **Username** and **Password**. All routes on the service will require these credentials.

## Maintenance

The Maintenance tab lets you put your service into a maintenance mode that shows a custom page to visitors instead of the live service.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| Enabled | Toggle | Off | Enable or disable maintenance mode |
| Title | Text | — | Heading displayed on the maintenance page |
| Subtitle | Text | — | Subheading displayed on the maintenance page |
| Custom Logo | Textarea | — | SVG markup or HTML for a custom logo |
| Custom CSS | Textarea | — | CSS to style the maintenance page |
| Hide Logo | Toggle | Off | Hide the Easypanel logo on the maintenance page |
| Hide Links | Toggle | Off | Hide navigation links on the maintenance page |

Click **Save** to apply changes.

## Compose Service vs App Service

| Feature | App Service | Compose Service |
|---------|-------------|-----------------|
| Container model | Single container | Multiple containers (full `docker-compose.yml`) |
| Source | GitHub, custom Git, Docker image | Inline `docker-compose.yml` or Git |
| Networks & volumes | Managed by Easypanel | Defined in the compose file |
| Replicas / scale | Configurable in the UI | Defined in the compose file |
| Mounts | Configured per-service in the UI | Defined in the compose file |
| Ports | Configured per-service in the UI | Defined in the compose file |
| Domain routing | Routes to the service directly | Routes to a named service within the stack |
| Status | Stable | Stable |
Loading