An open API service indexing awesome lists of open source software.

https://github.com/andygrunwald/simple-webserver

A small webserver for testing various technologies, techniques and concepts written in Go.
https://github.com/andygrunwald/simple-webserver

Last synced: 9 months ago
JSON representation

A small webserver for testing various technologies, techniques and concepts written in Go.

Awesome Lists containing this project

README

          

# simple-webserver

[![Build Status](https://travis-ci.org/andygrunwald/simple-webserver.svg?branch=master)](https://travis-ci.org/andygrunwald/simple-webserver)
[![GoDoc](https://godoc.org/github.com/andygrunwald/simple-webserver?status.svg)](https://godoc.org/github.com/andygrunwald/simple-webserver)
[![Go Report Card](https://goreportcard.com/badge/github.com/andygrunwald/simple-webserver)](https://goreportcard.com/report/github.com/andygrunwald/simple-webserver)

A small webserver (written in [Go](http://golang.org/)) for testing various technologies, techniques and concepts like [Docker](https://www.docker.com/), [Marathon](https://mesosphere.github.io/marathon/) / [Apache Mesos](http://mesos.apache.org/), [Kubernetes](http://kubernetes.io/), [API Blueprint](https://apiblueprint.org/) and others.

All guides how to use, play and use a technique or concept are documented here. Feel free to play around and learn as much as i do.

---

## Table of Contents

1. [Batteries Included](#batteries-included)
2. [Why this project?](#why-this-project)
3. [Build instructions](#build-instructions)
1. [Native application](#native-application)
2. [Docker](#docker)
4. [Tryout everything](#tryout-everything)
1. [Native application](#native-application-1)
2. [Docker](#docker-1)
3. [Docker Compose](#docker-compose)
3. [Marathon (native application)](#marathon-native-application)
4. [Marathon (docker container)](#marathon-docker-container)
5. [Marathon incl. Redis backend (docker container)](#marathon-incl-redis-backend-docker-container)
6. [Kubernetes](#kubernetes)
7. [API Blueprint: Validating API description](#api-blueprint-validating-api-description)
8. [API Blueprint: Generating API docs](#api-blueprint-generating-api-docs)
5. [Things on the list to try](#things-on-the-list-to-try)
6. [Contact](#contact)
7. [License](#license)

## Batteries Included

Here you will find a list of tested technologies, techniques and concepts within this project:

* [Go](http://golang.org/): How to write a small webserver with a minimal [Redis](http://redis.io/) backend in this programming language (incl. [GoDoc](https://godoc.org/github.com/andygrunwald/simple-webserver) and [unit tests](./main_test.go))
* [12factor](https://12factor.net/config): Configure an application via environment variables
* [Travis CI](https://travis-ci.org/): Execute unit tests on every push and pull request
* [Docker](https://www.docker.com/): How to isolate a Go app in a docker container
* [Docker Compose](https://docs.docker.com/compose/): How to start a multi-container setup with one command
* [Marathon](https://mesosphere.github.io/marathon/) @ [Apache Mesos](http://mesos.apache.org/): How to deploy this app on a Marathon cluster (native and in a docker container)
* [Kubernetes](http://kubernetes.io/): How to deploy this app on a Kubernetes cluster
* [API Blueprint](https://apiblueprint.org/): API development based on markdown specifications inclusive API doc generation by [aglio](https://github.com/danielgtaylor/aglio) and validation by [dredd](https://github.com/apiaryio/dredd)

## Why this project?

The information technology and computer science world is getting crazy.
Every day new tooling will be released, new techniques comes up and some concepts are getting best practice.

**It is important to stay up to date and this is the really hard part here.**

This project is my personal playground to try out all the new things i am excited of.
I am aware that this project is not representative and comparable with a real products that solves problems of the world.
Those projects are much more complex and have several other dependencies.
But the simplicity of this projects is on purpose and enables me to get a first idea and feeling of the topic i want to try in a small amount of time.

## Build instructions

### Native application

For building the native webserver you need a running [Go installation](https://golang.org/doc/install).

```sh
$ go build -o simple-webserver .
```

To compile it for a different OS (e.g. linux) use

```sh
$ GOOS=linux go build -o simple-webserver .
```

Precompiled binaries for various operating systems can be found in our [releases](https://github.com/andygrunwald/simple-webserver/releases).

If you want to execute the unit tests, run

```sh
$ go test -v ./...
```

### Docker

For building the docker image you need a running [Docker engine](https://docs.docker.com/engine/installation/).

```sh
$ docker build -t andygrunwald/simple-webserver .
```

Or you use the existing images from [Docker Hub](https://hub.docker.com/r/andygrunwald/simple-webserver/).

## Tryout everything

### Native application

The general usage of *simple-webserver* is

```sh
$ ./simple-webserver -help
Usage of ./simple-webserver:
-listen string
Address + Port to listen on. Format ip:port. Environment variable: SIMPLE_WEBSERVER_LISTEN (default ":8082")
-redis string
Address + Port where a redis server is listening. Environment variable: SIMPLE_WEBSERVER_REDIS (default ":6379")
```

Start the webserver with

```sh
$ ./simple-webserver
2016/06/05 14:57:18 Starting webserver and listen on :8082
```

and send your first request

```sh
$ curl http://localhost:8082/version
simple webserver v1.1.1
```

If you have a Redis server available, you can apply it via command line flag:

```sh
$ ./simple-webserver -redis ":6379"
2016/06/05 14:57:18 Starting webserver and listen on :8082
```

and call a `/ping` request

```sh
$ curl http://localhost:8082/ping
PONG
```

### Docker

Start the container with

```sh
$ docker run -d -p 8082:8082 andygrunwald/simple-webserver
9b20babef443420bf1728583fbfba......
```

and send your first request

```sh
$ curl http://DOCKER-IP:8082/version
simple webserver v1.1.1
```

Or launch *simple-webserver* with a Redis backend

```sh
$ docker run --name simple-webserver-redis -d redis
$ docker run -d -p 8082:8082 \
--link simple-webserver-redis:redis \
andygrunwald/simple-webserver -redis "redis:6379"
```

For further information the docker image is available at [Docker Hub](https://hub.docker.com/r/andygrunwald/simple-webserver/).

### Docker Compose

Fire up *simple-webserver* with a Redis backend with

```sh
$ docker-compose up -d
```

and call a `/ping` request

```sh
$ curl http://DOCKER-IP:8082/ping
PONG
```

### Marathon (native application)

Start the native application on a [Marathon](https://github.com/mesosphere/marathon) cluster (scheduling framework for [Apache Mesos](http://mesos.apache.org/) with

```sh
$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/apps -d@marathon.json
{
"id": "/simple-webserver",
...
}
```

Please visit your Marathon UI at http://marathon:8080/ to see if the deployment works out.

If you use Marathon in combination with [haproxy-marathon-bridge](https://open.mesosphere.com/tutorials/service-discovery/) or another [service discovery](https://mesosphere.github.io/marathon/docs/service-discovery-load-balancing.html) solution your service is available via the **service port 11000**

```sh
$ curl http://marathon-node:11000/version
simple webserver v1.1.1
```

If you don`t have a Mesos / Marathon cluster, i highly recommend [bobrik/mesos-compose](https://github.com/bobrik/mesos-compose).

### Marathon (docker container)

Start the docker container on a [Marathon](https://github.com/mesosphere/marathon) cluster (scheduling framework for [Apache Mesos](http://mesos.apache.org/) with

```sh
$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/apps -d@marathon-docker.json
{
"id":"/simple-webserver-docker",
...
}
```

Please visit your Marathon UI at http://marathon:8080/ to see if the deployment works out.

If you use Marathon in combination with [haproxy-marathon-bridge](https://open.mesosphere.com/tutorials/service-discovery/) or another [service discovery](https://mesosphere.github.io/marathon/docs/service-discovery-load-balancing.html) solution your service is available via the **service port 11001**

```sh
$ curl http://marathon-node:11001/version
simple webserver v1.1.1
```

If you don`t have a Mesos / Marathon cluster, i highly recommend [bobrik/mesos-compose](https://github.com/bobrik/mesos-compose).

### Marathon incl. Redis backend (docker container)

Start the docker container with a Redis backend on a [Marathon](https://github.com/mesosphere/marathon) cluster (scheduling framework for [Apache Mesos](http://mesos.apache.org/) with

```sh
$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/groups -d@marathon-redis-docker.json
{
"version":"2016-06-18T16:01:45.739Z",
...
}
```

Please visit your Marathon UI at http://marathon:8080/ to see if the deployment works out.

If it doesn't work out, please check `constraints` value in [marathon-redis-docker.json](./marathon-redis-docker.json) if this is equal the IP of your Mesos slave. If not, adjust it accordingly.

If you use Marathon in combination with [haproxy-marathon-bridge](https://open.mesosphere.com/tutorials/service-discovery/) or another [service discovery](https://mesosphere.github.io/marathon/docs/service-discovery-load-balancing.html) solution your service is available via the **service port 11001**

```sh
$ curl http://marathon-node:11001/ping
PONG
```

If you don`t have a Mesos / Marathon cluster, i highly recommend [bobrik/mesos-compose](https://github.com/bobrik/mesos-compose).

### Kubernetes

In this section we assume you have already a running Kubernetes cluster incl. a configured [kubectl](http://kubernetes.io/docs/user-guide/prereqs/). Otherwise i recommend to read [Getting Started With A Local Kubernetes Environment](https://blog.giantswarm.io/getting-started-with-a-local-kubernetes-environment/) or [Installing/Setting Up Kubernetes @ Kubernetes Docs](http://kubernetes.io/docs/).

In the [kubernetes.yaml](./kubernetes.yaml) you will find definitions for [Deployments](http://kubernetes.io/docs/user-guide/deployments/), [Services](http://kubernetes.io/docs/user-guide/services/) and an [Ingress Resource](http://kubernetes.io/docs/user-guide/ingress/).
This definition will start the *simple-webserver* incl. a Redis instance.

So lets start.
Apply the definition:

```sh
$ kubectl apply --filename kubernetes.yaml
service "simple-webserver" created
deployment "simple-webserver" created
service "simple-webserver-redis" created
deployment "simple-webserver-redis" created
ingress "simple-webserver" created
```

Check if all deployments are there:

```sh
$ kubectl get deployment -l app=simple-webserver
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
simple-webserver 1 1 1 1 24s
simple-webserver-redis 1 1 1 1 24s
```

Check the services:

```sh
$ kubectl get svc -l app=simple-webserver
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
simple-webserver 172.31.0.20 8082:30658/TCP 51s
simple-webserver-redis 172.31.0.238 6379/TCP 50s
```

And have a look at your [pods](http://kubernetes.io/docs/user-guide/pods/):

```
$ kubectl get pods -l app=simple-webserver
NAME READY STATUS RESTARTS AGE
simple-webserver-494066648-8dkhm 1/1 Running 0 1m
simple-webserver-redis-1815988752-09qog 1/1 Running 0 1m
```

Depending on your configuration *simple-webserver* should be accessible under your public ip / address via the Ingress resource.

To clean it up and delete it, fire:

```sh
$ kubectl delete service,deployment,ingress simple-webserver
service "simple-webserver" deleted
deployment "simple-webserver" deleted
ingress "simple-webserver" deleted
$ kubectl delete service,deployment simple-webserver-redis
service "simple-webserver-redis" deleted
deployment "simple-webserver-redis" deleted
```

### API Blueprint: Validating API description

[API Blueprint](https://apiblueprint.org/) is a powerful high-level API description language for web APIs.
Based on out definition file [api-blueprint.apib](./api-blueprint.apib) we are able to ...

... validate our API implementation (in *simple-webserver*) based on our API description / apib file with [dredd](https://github.com/apiaryio/dredd).
dredd will analyze the description and generate HTTP tests and fire them against a running instance of *simple-webserver*.

At first start an instance of simple-webserver. You can choose your favorite way. Native, Docker, Marathon, etc. Doesn't matter.

After this, run *dredd* tests in a docker container:

```sh
$ docker run -it --rm \
--net host \
-v /HOST/PATH/TO/simple-webserver:/simple-webserver \
apiaryio/dredd \
dredd simple-webserver/api-blueprint.apib http://INSTANCE:8082
info: Beginning Dredd testing...
pass: HEAD / duration: 30ms
...
```

Please replace

* `/HOST/PATH/TO/simple-webserver` with an absolute path to a local copy of *simple-webserver* on your machine
* `http://INSTANCE:8082` with IP:Port of a running instance of *simple-webserver*

### API Blueprint: Generating API docs

[API Blueprint](https://apiblueprint.org/) is a powerful high-level API description language for web APIs.
Based on out definition file [api-blueprint.apib](./api-blueprint.apib) we are able to ...

... generate our API documentation with [aglio](https://github.com/danielgtaylor/aglio).

```sh
$ docker run -ti --rm \
-v `pwd`:/docs \
humangeo/aglio -i api-blueprint.apib -o /docs/output.html
```

After this you can will find a new file `output.html` in the current directory.
Open it and you should see you API documentation.

## Things on the list to try

* [Blue-Green Deployment with Marathon](https://mesosphere.github.io/marathon/docs/blue-green-deploy.html)

## Contact

You are more than welcome to [open issues](https://github.com/andygrunwald/simple-webserver/issues) and / or [send pull requests](https://github.com/andygrunwald/simple-webserver/pulls) if you found a typo, a bug, need help to try something or want to request a new feature.

**If you appreciate this project please feel free to drop me a line and tell me!*
It's always nice to hear from people who have benefitted from this work and pushes the motivation again.**

* Twitter: [@andygrunwald](https://twitter.com/andygrunwald)
* Email: Checkout the mail at [my github profile](https://github.com/andygrunwald)

## License

This project is released under the terms of the [MIT license](http://en.wikipedia.org/wiki/MIT_License).