2020-01-20 13:08:44 -05:00
---
2022-07-04 17:09:58 -04:00
stage: Systems
2020-06-10 11:08:07 -04:00
group: Gitaly
2020-11-26 01:09:20 -05:00
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
2020-01-20 13:08:44 -05:00
disqus_identifier: 'https://docs.gitlab.com/ee/administration/custom_hooks.html'
---
2021-01-28 01:08:59 -05:00
# Server hooks **(FREE SELF)**
2020-01-20 13:08:44 -05:00
2020-07-16 14:09:35 -04:00
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196051) in GitLab 12.8 replacing Custom Hooks.
2022-02-11 16:12:17 -05:00
Server hooks run custom logic on the GitLab server. Users can use them to run Git-related tasks such as:
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
- Enforcing specific commit policies.
- Performing tasks based on the state of the repository.
2020-07-16 14:09:35 -04:00
2022-02-14 13:13:23 -05:00
Server hooks use `pre-receive` , `post-receive` , and `update`
2022-02-11 16:12:17 -05:00
[Git server-side hooks ](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_server_side_hooks ).
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
GitLab administrators configure server hooks on the file system of the GitLab server. If you don't have file system access,
alternatives to server hooks include:
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
- [Webhooks ](../user/project/integrations/webhooks.md ).
- [GitLab CI/CD ](../ci/index.md ).
2022-05-18 14:08:05 -04:00
- [Push rules ](../user/project/repository/push_rules.md ), for a user-configurable Git hook interface.
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
[Geo ](geo/index.md ) doesn't replicate server hooks to secondary nodes.
2020-07-16 14:09:35 -04:00
2022-06-29 08:09:26 -04:00
## Create server hooks for a repository
2020-07-16 14:09:35 -04:00
2022-06-29 08:09:26 -04:00
To create server hooks for a repository:
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
1. On the top bar, select **Menu > Admin** .
1. Go to **Overview > Projects** and select the project you want to add a server hook to.
1. On the page that appears, locate the value of **Gitaly relative path** . This path is where server hooks must be located.
- If you are using [hashed storage ](repository_storage_types.md#hashed-storage ), see
[Translate hashed storage paths ](repository_storage_types.md#translate-hashed-storage-paths ) for information on
interpreting the relative path.
- If you are not using [hashed storage ](repository_storage_types.md#hashed-storage ):
- For Omnibus GitLab installations, the path is usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git` .
- For an installation from source, the path is usually `/home/git/repositories/<group>/<project>.git` .
1. On the file system, create a new directory in the correct location called `custom_hooks` .
2022-06-29 08:09:26 -04:00
1. In the new `custom_hooks` directory:
- To create a single server hook, create a file with a name that matches the hook type. For example, for a
`pre-receive` server hook, the filename should be `pre-receive` with no extension.
- To create many server hooks, create a directory for the hooks that matches the hook type. For example, for a
`pre-receive` server hook, the directory name should be `pre-receive.d` . Put the files for the hook in that directory.
1. Make the server hook files executable and ensure that they are owned by the Git user.
2022-02-11 16:12:17 -05:00
1. Write the code to make the server hook function as expected. Server hooks can be in any programming language. Ensure
the [shebang ](https://en.wikipedia.org/wiki/Shebang_(Unix )) at the top reflects the language type. For
example, if the script is in Ruby the shebang is probably `#!/usr/bin/env ruby` .
2022-06-29 08:09:26 -04:00
1. Make the hook file executable, ensure that it's owned by the Git user, and ensure it does not match the backup file
pattern (`*~`).
2020-04-28 05:09:34 -04:00
2022-02-11 16:12:17 -05:00
If the server hook code is properly implemented, it should execute when the Git hook is next triggered.
2020-07-16 14:09:35 -04:00
2022-06-29 08:09:26 -04:00
## Create global server hooks for all repositories
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
To create a Git hook that applies to all repositories, set a global server hook. The default global server hook directory
is in the GitLab Shell directory. Any server hook added there applies to all repositories, including:
- [Project and group wiki ](../user/project/wiki/index.md ) repositories. Their storage directory names are in the format
`<id>.wiki.git` .
- [Design management ](../user/project/issues/design_management.md ) repositories under a project. Their storage directory
names are in the format `<id>.design.git` .
2021-04-20 20:11:06 -04:00
2022-02-11 16:12:17 -05:00
### Choose a server hook directory
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
Before creating a global server hook, you must choose a directory for it. The default global server hook directory:
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
- For Omnibus GitLab installations is usually `/opt/gitlab/embedded/service/gitlab-shell/hooks` .
2020-07-16 14:09:35 -04:00
- For an installation from source is usually `/home/git/gitlab-shell/hooks` .
2022-02-11 16:12:17 -05:00
To use a different directory for global server hooks, set `custom_hooks_dir` in Gitaly configuration:
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
- For Omnibus installations, set in `gitlab.rb` .
2020-07-16 14:09:35 -04:00
- For source installations, the configuration location depends on the GitLab version. For:
2022-02-11 16:12:17 -05:00
- GitLab 13.0 and earlier, set in `gitlab-shell/config.yml` .
- GitLab 13.1 and later, set in `gitaly/config.toml` under the `[hooks]` section. However, GitLab honors the
`custom_hooks_dir` value in `gitlab-shell/config.yml` if the value in `gitaly/config.toml` is blank or non-existent.
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
### Create the global server hook
2020-07-16 14:09:35 -04:00
2022-02-11 16:12:17 -05:00
To create a global server hook for all repositories:
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
1. On the GitLab server, go to the configured global server hook directory.
2022-06-29 08:09:26 -04:00
1. In the configured global server hook directory:
- To create a single server hook, create a file with a name that matches the hook type. For example, for a
`pre-receive` server hook, the filename should be `pre-receive` with no extension.
- To create many server hooks, create a directory for the hooks that matches the hook type. For example, for a
`pre-receive` server hook, the directory name should be `pre-receive.d` . Put the files for the hook in that directory.
2022-02-11 16:12:17 -05:00
1. Inside this new directory, add your server hook. Server hooks can be in any programming language. Ensure the
[shebang ](https://en.wikipedia.org/wiki/Shebang_(Unix )) at the top reflects the language type. For example, if the
script is in Ruby the shebang is probably `#!/usr/bin/env ruby` .
1. Make the hook file executable, ensure that it's owned by the Git user, and ensure it does not match the backup file
pattern (`*~`).
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
If the server hook code is properly implemented, it should execute when the Git hook is next triggered.
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
## Chained server hooks
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
GitLab can execute server hooks in a chain. GitLab searches for and executes server hooks in the following order:
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
- Built-in GitLab server hooks. These server hooks are not customizable by users.
- `<project>.git/custom_hooks/<hook_name>` : Per-project hooks. This location is kept for backwards compatibility.
2020-07-16 14:09:35 -04:00
- `<project>.git/custom_hooks/<hook_name>.d/*` : Location for per-project hooks.
2022-02-11 16:12:17 -05:00
- `<custom_hooks_dir>/<hook_name>.d/*` : Location for all executable global hook files except editor backup files.
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
Within a server hooks directory, hooks:
2020-01-20 13:08:44 -05:00
2020-07-16 14:09:35 -04:00
- Are executed in alphabetical order.
- Stop executing when a hook exits with a non-zero value.
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
## Environment variables available to server hooks
2020-01-20 13:08:44 -05:00
2022-02-11 16:12:17 -05:00
You can pass any environment variable to server hooks, but you should only rely on supported environment variables.
2020-12-15 22:09:46 -05:00
2022-02-11 16:12:17 -05:00
The following GitLab environment variables are supported for all server hooks:
2020-03-20 05:09:22 -04:00
2022-02-11 16:12:17 -05:00
| Environment variable | Description |
|:---------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `GL_ID` | GitLab identifier of user that initiated the push. For example, `user-2234` . |
| `GL_PROJECT_PATH` | (GitLab 13.2 and later) GitLab project path. |
| `GL_PROTOCOL` | (GitLab 13.2 and later) Protocol used for this change. One of: `http` (Git `push` using HTTP), `ssh` (Git `push` using SSH), or `web` (all other actions). |
| `GL_REPOSITORY` | `project-<id>` where `id` is the ID of the project. |
| `GL_USERNAME` | GitLab username of the user that initiated the push. |
2020-07-13 20:09:46 -04:00
2022-02-11 16:12:17 -05:00
The following Git environment variables are supported for `pre-receive` and `post-receive` server hooks:
2020-07-13 20:09:46 -04:00
| Environment variable | Description |
|:-----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `GIT_ALTERNATE_OBJECT_DIRECTORIES` | Alternate object directories in the quarantine environment. See [Git `receive-pack` documentation ](https://git-scm.com/docs/git-receive-pack#_quarantine_environment ). |
| `GIT_OBJECT_DIRECTORY` | GitLab project path in the quarantine environment. See [Git `receive-pack` documentation ](https://git-scm.com/docs/git-receive-pack#_quarantine_environment ). |
2022-02-14 13:13:23 -05:00
| `GIT_PUSH_OPTION_COUNT` | Number of [push options ](../user/project/push_options.md ). See [Git `pre-receive` documentation ](https://git-scm.com/docs/githooks#pre-receive ). |
| `GIT_PUSH_OPTION_<i>` | Value of [push options ](../user/project/push_options.md ) where `i` is from `0` to `GIT_PUSH_OPTION_COUNT - 1` . See [Git `pre-receive` documentation ](https://git-scm.com/docs/githooks#pre-receive ). |
2020-07-13 20:09:46 -04:00
2020-01-20 13:08:44 -05:00
## Custom error messages
2022-02-11 16:12:17 -05:00
You can have custom error messages appear in the GitLab UI when a commit is declined or an error occurs during the Git
hook. To display a custom error message, your script must:
2020-01-20 13:08:44 -05:00
- Send the custom error messages to either the script's `stdout` or `stderr` .
- Prefix each message with `GL-HOOK-ERR:` with no characters appearing before the prefix.
2022-02-11 16:12:17 -05:00
For example:
2020-01-20 13:08:44 -05:00
2020-01-30 10:09:15 -05:00
```shell
2020-01-20 13:08:44 -05:00
#!/bin/sh
echo "GL-HOOK-ERR: My custom error message.";
exit 1
```