# Install plugins on a self-hosted site

**URL:** https://meta.discourse.org/t/install-plugins-on-a-self-hosted-site/19157
**Category:** Self-Hosting
**Tags:** how-to
**Created:** [August 22, 2014, 2:59am UTC](https://meta.discourse.org/t/install-plugins-on-a-self-hosted-site/19157 "2014-08-22T02:59:12Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [August 22, 2014, 2:59am UTC](https://meta.discourse.org/t/install-plugins-on-a-self-hosted-site/19157/1 "2014-08-22T02:59:12Z")

</div>

> ⚠ This guide assumes that you have a **self-hosted standard installation**. We _only_ support the standard method of install here, so these instructions assume you have a [standard install](https://meta.discourse.org/t/142537?silent=true).

> ⚠ This guide only applies to **self-hosted Discourse instances**. If you are using a managed hosting service, the available plugins are controlled by your hosting provider. For example, on our hosting [these specific plugins](https://www.discourse.org/plugins) are available by hosting tier.

> ℹ As of mid-2025, [many popular official plugins have been bundled into Discourse core](https://meta.discourse.org/t/373574). These plugins (including Solved, [Data Explorer](https://meta.discourse.org/t/32566?silent=true), AI, Assign, Reactions, and many more) no longer need to be installed separately — they ship with Discourse and can be enabled via site settings. If you try to rebuild with a bundled plugin still in your `app.yml`, you’ll see a `HINT` message telling you to remove it. This guide is for plugins that are **not** bundled with core.

In this tutorial, we’ll install the [Discourse Shared Edits](https://meta.discourse.org/t/discourse-shared-edits/167583?tl=en) plugin.

This tutorial requires an understanding of how to use GitHub repos, specifically, [how to get or copy the git clone URL](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) and how to edit YAML (`*.yml`) files via the terminal using nano, specifically [how to save and exit on nano](https://linuxize.com/post/how-to-use-nano-text-editor/#saving-and-exiting). YAML files strongly follow indentations, so be sure to respect these as you copy and paste and edit the necessary `*.yml` for your Discourse instance. Always use spaces to indent in .yml files, not tabs.

- Copy the plugin’s GitHub `git clone` url.

- Access your container’s `app.yml` file (present in ` /var/discourse/containers/`)

- Add the plugin’s repository URL to your container’s `app.yml` file:

- Rebuild the container:

* * *

### If your plugin is hosted in a private repository

You must use an OAuth token:

> **[Managing your personal access tokens - GitHub Docs](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)**
>
> You can use a personal access token in place of a password when authenticating to GitHub in the command line or with the API.

With the OAuth token, you can install your plugin in the same way as a public repo, and you don’t need to create a SSH key.

```plaintext
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
              - git clone https://<token>@github.com/owner/repo.git

```

We strongly advise you to use OAuth tokens for plugins in private repositories. However, if you cannot, see below.

> **SSH Key Private Install Steps**
>
> - Assuming that your private git repo is hosted on GitHub, you need to add your server’s user public SSH key to GitHub repo Deploy keys ([https://github.com/SecretOrg/secret-plugin/settings/keys](https://github.com/SecretOrg/secret-plugin/settings/keys)).
> 
> - Modify `app.yml` file as shown in below example:
> 
> ```plaintext
> run:
> - exec: echo "Beginning of custom commands"
>   
> - exec: cd /var/www/discourse && sudo -u discourse bundle install --deployment --without test --without development
> - exec: echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /user/.ssh/config
> - file:
> path: /user/.ssh/id_rsa
> chmod: 600
> contents: |
> -----BEGIN RSA PRIVATE KEY-----
> MIIEogIBAAKCAQEArCQG213utzqE5YVjTVF5exGRCkE9OuM7LCp/FOuPdoHrFUXk
> .... etc ....
> -----END RSA PRIVATE KEY-----
> - file:
> path: /user/.ssh/id_rsa.pub
> chmod: 600
> contents: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tj .... etc .... user@discourse
> - exec: cd $home/plugins && git clone git@github.com:SecretOrg/secret-plugin.git
> - exec: cd $home && sudo -E -u discourse bundle exec rake db:migrate
> - exec: cd $home && rm -fr tmp/cache
> - exec: cd $home && sudo -E -u discourse bundle exec rake assets:precompile
> - exec: rm /user/.ssh/id_rsa
> - exec: rm /user/.ssh/id_rsa.pub
> 
> - exec: echo "End of custom commands"
> 
> ```
> 
> - Rebuild the container:
> 
> ```plaintext
> cd /var/discourse
> ./launcher rebuild app
> 
> ```
> 
> Your private plugin should be installed on your Discourse instance.

### How to uninstall a plugin

To remove a plugin, simply remove the `- git clone https://github.com/...` line from your `app.yml` file and rebuild your site via

```plaintext
cd /var/discourse
./launcher rebuild app

```

> Last edited by @sam 2026-03-18T03:38:49Z
> 
> > **Check document**
> >
> > Perform check on document:

---

_[View the full topic](https://meta.discourse.org/t/install-plugins-on-a-self-hosted-site/19157)._
