Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pull but don't deploy, notification system #4

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
.gitignore
.cache
node_modules
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
'extends': 'standard',
'rules': {
'space-before-function-paren': 0,
'comma-dangle': 0
}
};
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/node_modules
.vscode
node_modules
78 changes: 68 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
FROM node:8-alpine
RUN apk update && apk add docker
RUN mkdir -p /usr/src/app
COPY index.js /usr/src/app
COPY config.json /usr/src/app
COPY package.json /usr/src/app
COPY npm-shrinkwrap.json /usr/src/app
WORKDIR /usr/src/app
RUN npm install
EXPOSE 80
CMD [ "npm", "start" ]

## To specify passwords/paths/etc
## -Set ENV values in this dockerfile, OR
## -Set the _FILE vars to read the values from Docker Secrets, etc
## -You can set the vars here, with the Docker run command, or in a Docker compose/stack file

# Port to run on
ENV PORT=3000
EXPOSE ${PORT}

# Which configuration in the config.json file to load
ARG CONFIG="production"
ENV CONFIG=${CONFIG}

# Location of config.json
ENV CONFIG_DIR=/usr/src/app/config/
ENV CONFIG_FILE=config.json

## Specify secrets as ENV vars
# A token used to restrict access to the webhook
# ENV TOKEN="123-456-ABC-DEF"

# Docker Hub account username
# ENV USERNAME="docker-hub-username"

# Docker Hub account password
# ENV PASSWORD="docker-hub-password"

## OR - specify files containing the secrets
# ENV TOKEN_FILE=/run/secrets/token
# ENV USERNAME_FILE=/run/secrets/username
# ENV PASSWORD_FILE=/run/secrets/password


## SSL Settings - optional
# ENV SSL_CERT_FILE=/path/to/ssl_cert_file
# ENV SSL_KEY_FILE=/path/to/ssl_key_file


## Github Settings - optionally used to pull the config file
# Don't add `https://` to the URL
# ENV GITHUB_TOKEN=abcdef12345678990abcdef1234567890abcdef1
# ENV GITHUB_URL=github.com/org/repo.git


## Mailgun Settings - optionally used to send email notifications
# ENV MAILGUN_KEY=key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ENV MAILGUN_DOMAIN=your-domain.com
# ENV MAILGUN_FROM_ADDRESS="YourOrg Deploy <[email protected]>"
## OR - specify files containing the settings
# ENV MAILGUN_KEY_FILE=/path/to/mailgun_apikey_file
# ENV MAILGUN_DOMAIN_FILE=/path/to/mailgun_domain_file
# ENV MAILGUN_FROM_ADDRESS_FILE=/path/to/mailgun_from_address_file


RUN apk update && apk add docker && apk add git

WORKDIR /usr/src/app/

# If GITHUB_TOKEN & GITHUB_URL are set, entrypoint script will pull config file
COPY scripts/fetchConfigFromGithub.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/fetchConfigFromGithub.sh

COPY . .
RUN npm install --unsafe-perm

ENTRYPOINT ["/usr/local/bin/fetchConfigFromGithub.sh"]
CMD [ "npm", "start" ]
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ Flow for automated deployment:
* Configure Docker Hub to build an image when a GitHub repository is updated.
* Configure Docker Hub to call this service via webhook when a new image is available.
* Configure and deploy this service to your Docker Swarm cluster.
* When a new image is built, it will update the Docker Service in the Swarm.
* When a new image is built, it will update the Docker Service in the Swarm.

This webhook is intended for use with private Docker Hub repositories and self hosted Docker Swarm instances.

To get started, clone this repository, add an image of it to your Docker Hub account, configure `config.json` and deploy it to your Docker Swarm as a service (see steps below).
To get started, clone this repository, add an image of it to your Docker Hub account, configure config.json and deploy it to your Docker Swarm as a service (see steps below).

[Read more about this service in this blog post.](https://medium.com/@iaincollins/docker-swarm-automated-deployment-cb477767dfcf)

Expand All @@ -27,6 +27,14 @@ Supported environment variables:
USERNAME="docker-hub-username" // A Docker Hub account username
PASSWORD="docker-hub-password" // A Docker Hub account password

**note:** the value for `CONFIG` environment variable can be passed in at image build time:

```
docker build \
--build-arg CONFIG=part-of-config-dot-json-file-to-load \
-t docker-hub-username/docker-deploy-webhook .
```

The `config.json` file defines each environment:

{
Expand All @@ -53,6 +61,10 @@ You can use the `CONFIG` environment variable to tell `docker-deploy-webhook` wh

You use the same callback URL for all services, when `docker-deploy-webhook` receives an update for an image and tag is it is configured for it will push that release to the service associated with it in `config.json`.

### Notifications Configuration (Optional)

See the `README.md` file in `/config`

## Deploy to Docker Swarm

swarm-manager000000> docker login
Expand Down
19 changes: 0 additions & 19 deletions config.json

This file was deleted.

194 changes: 194 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# README

## Configurations

You can specify multiple configs in one file. Specify which config to use by settting env.CONFIG to the config name.

```JSON
{
"production": {},
"development": {}
}
```

## Repos / Services

Within each config, you can specify multiple Docker Hub repos to monitor. The repo name should match `org/name:tag`.

Each repo config must also specify the following:

- `nickName` - an arbitrary string that's used for logging / notifications purposes
- `service` - name of the swarm service that should be updated when a new build of the repo is available

```JSON
"production": {
"my-org/my-repo:tag": {
"nickName": "my-repo:tag",
"service": "my-docker-service-name"
},
"my-org/my-other-repo:tag": {
"nickName": "Production App Server",
"service": "my-other-docker-service-name",
}
```

## Per Repo Options

Each repo config can specify the following `options`

- `pullButDontDeploy` - Setting this option to `true` will allow the application to pull updated images that can be manually deployed later. The default value is `false`
- `notify` - Container for per repo notification options

```JSON
"my-org/my-repo:tag": {
"nickName": "my-repo:tag",
"service": "my-docker-service",
"options": {
"pullButDontDeploy": false,
"notify": {}
}
}
```

## Notification Options

### Notification Option Types

You can configure the application to send notifications for certain kinds of actions, triggered on specific action statuses (i.e. success or failure), and/or for different catch-all categories.

Each notification type has two properties:

- `notify` - when set to `true`, the application will send notifications for events matching the option type. The default value is `false`
- `methods` - container for configuring which notification methods to use and the notification targets for each method (e.g. list of email addresses)

### Catch-alls

There are three catch-all categories

- `all` - any action, with any status
- `allSuccess` - all successful actions
- `allFailure` - all failed actions

### Action types

There are currently two types of actions

- `deploy` - matches deploy actions (where `pullButDontDeploy` is `false`)
- `pull` - matches pull actions (where `pullButDontDeploy` is `true`)

#### Action Type Statuses

- `success` - matches when `action` was successful
- `failure` - matches when `action` failed

Each action type status option can specify separate `notify` and `methods` values under `sucess` and `failure`

```JSON
"notify": {
"deploy": {
"success": {
"notify": false,
"methods": {}
},
"failure": {
"notify": true,
"methods": {}
}
},
"pull": {
"success": {
"notify": false,
"methods": {}
},
"failure": {
"notify": false,
"methods": {}
}
}
```

### Notification Methods

You must provide implementations for enabled notification methods as a plugin. An email plugin for [Mailgun](https://www.mailgun.com) has been provided.

Each enabled notification type must specify at least one notification method. Currently there are two notification method stubs provided, and more could be added.

#### Notification Method Types

- `email` - send email notifications
- `webhook` - send webhook notifications
- Additional notification types can be configured by:
- extending the `notificationMethodHandlers` method in `/lib/notify/index.js`
- adding a matching `require` function in `/plugins/index.js`, and
- providing the implementation in `/plugins/${type}/`

#### Notification Targets

Each enabled notification method type should specify an array of targets (e.g. email addresses for `email`)

```JSON
"notify": {
"all": {
"notify": true,
"methods": {
"email": [
"[email protected]",
"[email protected]"
],
"webhook": [
"https://www.example.com/webhook",
"https://www.example2.com/webhook"
]
}
}
}
```

## Default Notification Options

An additional configuration option, `defaultNotificationOptions`, can be added under a configuration to specify notification options that will apply to all repos under that configuration.

Any repo-specific notification options take precedence over the default options.

In this example, email notifications for the first service will be sent only to [email protected], but to [email protected] for the other two services:

```JSON
"production": {
"my-org/first:tag": {
"nickName": "my-repo:tag",
"service": "my-first-service",
"notify": {
"all": {
"notify": true,
"methods": {
"email": [
"[email protected]"
]
}
}
}
},
"my-org/my-other-repo:tag": {
"nickName": "Production App Server",
"service": "my-other-docker-service-name",
},
"my-org/my-third-repo:tag": {
"nickName": "Some Other Service",
"service": "my-third-docker-service-name",
},
"defaultNotificationOptions": {
"all": {
"notify": true,
"methods": {
"email": [
"[email protected]"
]
}
}
}
}
```

## Example `config.json`

A full `config.json` example file has be provided in `/config`
Loading