All Projects → andygrunwald → simple-webserver

andygrunwald / simple-webserver

Licence: MIT license
A small webserver for testing various technologies, techniques and concepts written in Go.

Programming Languages

go
31211 projects - #10 most used programming language
API Blueprint
66 projects
shell
77523 projects
Dockerfile
14818 projects

simple-webserver

Build Status GoDoc Go Report Card

A small webserver (written in Go) for testing various technologies, techniques and concepts like Docker, Marathon / Apache Mesos, Kubernetes, API Blueprint 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
  2. Why this project?
  3. Build instructions
    1. Native application
    2. Docker
  4. Tryout everything
    1. Native application
    2. Docker
    3. Docker Compose
    4. Marathon (native application)
    5. Marathon (docker container)
    6. Marathon incl. Redis backend (docker container)
    7. Kubernetes
    8. API Blueprint: Validating API description
    9. API Blueprint: Generating API docs
  5. Things on the list to try
  6. Contact
  7. License

Batteries Included

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

  • Go: How to write a small webserver with a minimal Redis backend in this programming language (incl. GoDoc and unit tests)
  • 12factor: Configure an application via environment variables
  • Travis CI: Execute unit tests on every push and pull request
  • Docker: How to isolate a Go app in a docker container
  • Docker Compose: How to start a multi-container setup with one command
  • Marathon @ Apache Mesos: How to deploy this app on a Marathon cluster (native and in a docker container)
  • Kubernetes: How to deploy this app on a Kubernetes cluster
  • API Blueprint: API development based on markdown specifications inclusive API doc generation by aglio and validation by 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.

$ go build -o simple-webserver .

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

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

Precompiled binaries for various operating systems can be found in our releases.

If you want to execute the unit tests, run

$ go test -v ./...

Docker

For building the docker image you need a running Docker engine.

$ docker build -t andygrunwald/simple-webserver .

Or you use the existing images from Docker Hub.

Tryout everything

Native application

The general usage of simple-webserver is

$ ./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

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

and send your first request

$ 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:

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

and call a /ping request

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

Docker

Start the container with

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

and send your first request

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

Or launch simple-webserver with a Redis backend

$ 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.

Docker Compose

Fire up simple-webserver with a Redis backend with

$ docker-compose up -d

and call a /ping request

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

Marathon (native application)

Start the native application on a Marathon cluster (scheduling framework for Apache Mesos with

$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/apps [email protected]
{
    "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 or another service discovery solution your service is available via the service port 11000

$ 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.

Marathon (docker container)

Start the docker container on a Marathon cluster (scheduling framework for Apache Mesos with

$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/apps [email protected]
{
    "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 or another service discovery solution your service is available via the service port 11001

$ 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.

Marathon incl. Redis backend (docker container)

Start the docker container with a Redis backend on a Marathon cluster (scheduling framework for Apache Mesos with

$ curl -X POST -H "Content-Type: application/json" http://marathon:8080/v2/groups [email protected]
{
    "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 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 or another service discovery solution your service is available via the service port 11001

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

If you don`t have a Mesos / Marathon cluster, i highly recommend bobrik/mesos-compose.

Kubernetes

In this section we assume you have already a running Kubernetes cluster incl. a configured kubectl. Otherwise i recommend to read Getting Started With A Local Kubernetes Environment or Installing/Setting Up Kubernetes @ Kubernetes Docs.

In the kubernetes.yaml you will find definitions for Deployments, Services and an Ingress Resource. This definition will start the simple-webserver incl. a Redis instance.

So lets start. Apply the definition:

$ 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:

$ 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:

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

And have a look at your 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:

$ 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 is a powerful high-level API description language for web APIs. Based on out definition file api-blueprint.apib we are able to ...

... validate our API implementation (in simple-webserver) based on our API description / apib file with 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:

$ 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 is a powerful high-level API description language for web APIs. Based on out definition file api-blueprint.apib we are able to ...

... generate our API documentation with aglio.

$ 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

Contact

You are more than welcome to open issues and / or send pull requests 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.*

License

This project is released under the terms of the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].