├── .github └── workflows │ ├── publish-ansible-image.yml │ ├── publish-devopstools-image.yml │ ├── publish-docker-image.yml │ ├── publish-terraform-image.yml │ └── publish-waypoint-image.yml ├── README.md ├── ansible ├── 2-10.Dockerfile └── Dockerfile ├── aws-metadata-flask ├── Dockerfile ├── Dockerfile.cpu ├── README.md ├── app.py └── cpu-app.py ├── awscli ├── Dockerfile ├── Dockerfile.pip └── README.md ├── build-tools ├── Dockerfile └── Dockerfile.slim ├── busybox-logger ├── Dockerfile ├── README.md └── run.sh ├── cargo └── Dockerfile ├── civocli └── Dockerfile ├── containers ├── README.md ├── curl.Dockerfile ├── devops.Dockerfile ├── mysql.Dockerfile └── nginx.Dockerfile ├── cpp-hello-world ├── CMakeLists.txt ├── Dockerfile └── main.cpp ├── curl-ares └── Dockerfile ├── curl └── Dockerfile ├── devopstools └── Dockerfile ├── docker-remote-tools └── Dockerfile ├── docker ├── Dockerfile └── README.md ├── dockerd ├── Dockerfile └── entrypoint.sh ├── drone-gitea ├── docker-compose.yml └── docker-compose_mysql-minio.yml ├── drone-gogs ├── README.md └── docker-compose.yml ├── drone ├── agent │ ├── Dockerfile │ └── build.sh └── server │ ├── Dockerfile │ └── build.sh ├── dynamodb-ui ├── Dockerfile └── docker-compose.yml ├── dynamodb ├── Dockerfile ├── Dockerfile.local ├── README.md └── example_boto3.md ├── envsubst └── Dockerfile ├── filebeat-mysql ├── Dockerfile ├── filebeat.yml └── mysql.yml ├── flask-message ├── Dockerfile └── app.py ├── fluentd-influxdb ├── Dockerfile ├── README.md └── fluent.conf ├── fluentd-loki ├── Dockerfile ├── fluent.conf └── resources.md ├── gitbook ├── Dockerfile ├── README.md ├── book.json └── copyPluginAssets.js ├── gitlab-runners └── docker-compose.yaml ├── golang-basic-api ├── Dockerfile ├── README.md ├── go.mod └── main.go ├── golang-basic-rest-api ├── Dockerfile └── app.go ├── golang-build └── Dockerfile ├── golang-echo ├── Dockerfile ├── README.md ├── go.mod └── main.go ├── golang-logger ├── Dockerfile ├── go.mod ├── go.sum └── main.go ├── golang └── Dockerfile ├── hackerslides └── docker-compose.yml ├── hostname-go-json ├── Dockerfile ├── README.md ├── app.go ├── docker-compose.yml ├── go.mod └── go.sum ├── hostname-go ├── Dockerfile ├── app.go └── busybox.Dockerfile ├── hostname-rpi ├── Dockerfile └── app.go ├── hugo ├── Dockerfile ├── Dockerfile.app ├── Makefile ├── README.md ├── boot.sh ├── config.env └── deploy.env ├── jekyll ├── Dockerfile └── docker-compose.yml ├── jenkins-docker └── Dockerfile ├── jenkins └── docker-compose.yml ├── keep-me-running └── Dockerfile ├── kinesis ├── Dockerfile ├── README.md ├── consumer.py └── producer.py ├── kubectl └── Dockerfile ├── kubernetes-elasticsearch-cluster ├── Dockerfile.curator └── Dockerfile.elasticsearch ├── ldap └── README.md ├── load-generator └── cpu │ ├── Dockerfile │ ├── README.md │ └── app.py ├── logstash ├── Dockerfile ├── Dockerfile.2 ├── config │ └── logstash.yml └── pipeline │ └── logstash.conf ├── metricbeat-mysql ├── Dockerfile └── metricbeat.yml ├── minica ├── Dockerfile └── README.md ├── mongodb ├── Dockerfile ├── Dockerfile.python └── docker-compose.yml ├── motd ├── Dockerfile ├── README.md ├── boot.sh └── content ├── mtail ├── Dockerfile ├── README.md ├── example_nginx.conf ├── nginx.mtail └── setup_geoip_nginx.md ├── mysql-client ├── Dockerfile └── README.md ├── mysql-cluster ├── README.md └── docker-compose.yml ├── mysql └── docker-compose.yml ├── nginx-json ├── Dockerfile ├── README.md ├── index.html └── nginx.conf ├── nodejs-hostname ├── Dockerfile ├── README.md └── app.js ├── opencart ├── Dockerfile └── README.md ├── openvpn-client └── Dockerfile ├── openvpn-server └── README.md ├── passwordless-ssh ├── Dockerfile ├── README.md ├── boot.sh ├── motd-generator.sh └── sshd_config ├── php-composer └── 7.3.19 │ └── Dockerfile ├── php-fpm └── 7.3.19 │ └── Dockerfile ├── postfix-exporter ├── Dockerfile ├── README.md └── build_binary.sh ├── redis └── docker-compose.yml ├── retrowave ├── Dockerfile ├── README.md ├── index.html └── static │ ├── css │ └── style.css │ └── images │ ├── retrowave-blue-pink.gif │ └── retrowave.gif ├── ruby ├── Dockerfile └── docker-entrypoint.sh ├── sendgrid ├── Dockerfile ├── config.js ├── credits.md ├── package.json ├── server.js └── utils.js ├── sns └── README.md ├── sqs ├── README.md └── docker-compose.yml ├── stress-half-cpu ├── Dockerfile ├── docker-compose.yaml └── start.sh ├── supervisord-app ├── Dockerfile ├── app-colors │ ├── README.md │ └── main.go ├── app-messages │ ├── README.md │ └── main.go └── supervisord.conf ├── terraform └── Dockerfile ├── twitter-retweetbot ├── Dockerfile ├── main.go └── twitter.env ├── vscode ├── Dockerfile.docker ├── Dockerfile.python ├── README.md ├── docker-entrypoint.sh ├── docker-entrypoint_docker.sh └── packages │ └── requirements.txt ├── waypoint └── Dockerfile ├── web-center-name-v2 ├── Dockerfile ├── README.md ├── app.py └── templates │ └── index.html ├── web-center-name ├── Dockerfile ├── README.md ├── app.py └── templates │ └── index.html ├── webhook-basic ├── Dockerfile ├── README.md └── app.py └── whoami ├── Dockerfile ├── README.md └── app.go /.github/workflows/publish-ansible-image.yml: -------------------------------------------------------------------------------- 1 | name: publish-ansible-image 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'ansible/*' 8 | 9 | jobs: 10 | build: 11 | name: build 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKER_USERNAME }} 24 | password: ${{ secrets.DOCKER_PASSWORD }} 25 | 26 | - name: build and push docker images 27 | uses: docker/build-push-action@v2 28 | with: 29 | context: ./ansible 30 | file: ./ansible/Dockerfile 31 | platforms: linux/amd64 32 | push: true 33 | tags: ruanbekker/ansible:latest 34 | -------------------------------------------------------------------------------- /.github/workflows/publish-devopstools-image.yml: -------------------------------------------------------------------------------- 1 | name: publish-devopstools-image 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'devopstools/*' 8 | 9 | jobs: 10 | build: 11 | name: build 12 | runs-on: self-hosted 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKER_USERNAME }} 24 | password: ${{ secrets.DOCKER_PASSWORD }} 25 | 26 | - name: build and push docker images 27 | uses: docker/build-push-action@v2 28 | with: 29 | context: ./devopstools 30 | file: ./devopstools/Dockerfile 31 | platforms: linux/amd64 32 | push: true 33 | tags: ruanbekker/devopstools:latest 34 | -------------------------------------------------------------------------------- /.github/workflows/publish-docker-image.yml: -------------------------------------------------------------------------------- 1 | name: publish-docker-image 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'docker/*' 8 | 9 | jobs: 10 | build: 11 | name: build 12 | runs-on: self-hosted 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKER_USERNAME }} 24 | password: ${{ secrets.DOCKER_PASSWORD }} 25 | 26 | - name: build and push docker images 27 | uses: docker/build-push-action@v2 28 | with: 29 | context: ./docker 30 | file: ./docker/Dockerfile 31 | platforms: linux/amd64 32 | push: true 33 | tags: ruanbekker/docker:latest 34 | -------------------------------------------------------------------------------- /.github/workflows/publish-terraform-image.yml: -------------------------------------------------------------------------------- 1 | name: publish-terraform-image 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'terraform/*' 8 | 9 | jobs: 10 | build: 11 | name: build 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKER_USERNAME }} 24 | password: ${{ secrets.DOCKER_PASSWORD }} 25 | 26 | - name: build and push docker images 27 | uses: docker/build-push-action@v2 28 | with: 29 | context: ./terraform 30 | file: ./terraform/Dockerfile 31 | platforms: linux/amd64 32 | push: true 33 | tags: ruanbekker/terraform:latest 34 | -------------------------------------------------------------------------------- /.github/workflows/publish-waypoint-image.yml: -------------------------------------------------------------------------------- 1 | name: publish-waypoint-image 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'waypoint/*' 8 | 9 | jobs: 10 | build: 11 | name: build 12 | runs-on: self-hosted 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: Login to DockerHub 21 | uses: docker/login-action@v1 22 | with: 23 | username: ${{ secrets.DOCKER_USERNAME }} 24 | password: ${{ secrets.DOCKER_PASSWORD }} 25 | 26 | - name: build and push docker images 27 | uses: docker/build-push-action@v2 28 | with: 29 | context: ./waypoint 30 | file: ./waypoint/Dockerfile 31 | platforms: linux/amd64 32 | push: true 33 | tags: ruanbekker/waypoint:latest 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dockerfiles 2 | Dockerfiles Repo 3 | 4 | ## External Repos 5 | 6 | - [vimagick](https://github.com/vimagick/dockerfiles) 7 | - [jessfraz](https://github.com/jessfraz/dockerfiles) 8 | - [kiwicom](https://github.com/kiwicom/dockerfiles) 9 | - [voxxit](https://github.com/voxxit/dockerfiles) 10 | - [tianon](https://github.com/tianon/dockerfiles) 11 | - [crosbymichael](https://github.com/crosbymichael/Dockerfiles) 12 | 13 | ## GUI Based 14 | 15 | - [firefox](https://hub.docker.com/r/jlesage/firefox/) 16 | 17 | ## Stargazers over time 18 | 19 | [![Stargazers over time](https://starchart.cc/ruanbekker/dockerfiles.svg)](https://starchart.cc/ruanbekker/dockerfiles) 20 | -------------------------------------------------------------------------------- /ansible/2-10.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV ANSIBLE_VERSION=2.10.0 4 | 5 | RUN apk add --no-cache --virtual=.build-deps libffi-dev openssl-dev build-base \ 6 | && apk add --no-cache --virtual=.run-deps openssh-client ca-certificates openssl \ 7 | && pip install --no-cache-dir cffi==1.14.3 ansible==${ANSIBLE_VERSION} \ 8 | && apk del .build-deps \ 9 | && ln -s /usr/local/bin/python /usr/bin/python 10 | 11 | CMD ["ansible-playbook", "--version"] 12 | -------------------------------------------------------------------------------- /ansible/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-alpine 2 | 3 | ENV ANSIBLE_VERSION 4.4.0 4 | 5 | RUN apk add --no-cache --virtual .build-deps musl-dev python3-dev libffi-dev openssl-dev cargo gcc \ 6 | && pip install ansible==$ANSIBLE_VERSION \ 7 | && apk del .build-deps musl-dev python3-dev libffi-dev openssl-dev cargo gcc 8 | 9 | CMD ["sh"] 10 | -------------------------------------------------------------------------------- /aws-metadata-flask/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | RUN pip install flask requests 3 | COPY app.py /app.py 4 | CMD ["python", "/app.py"] 5 | -------------------------------------------------------------------------------- /aws-metadata-flask/Dockerfile.cpu: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | RUN apk add autoconf automake g++ make --no-cache 3 | RUN pip install flask requests py-bcrypt 4 | COPY cpu-app.py /app.py 5 | CMD ["python", "/app.py"] 6 | -------------------------------------------------------------------------------- /aws-metadata-flask/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### Non CPU Intensive 3 | 4 | On a EC2 Instance: 5 | 6 | ``` 7 | $ docker run -it -p 5000:5000 ruanbekker/aws-metadata-container:latest 8 | ``` 9 | 10 | Test: 11 | 12 | ``` 13 | $ curl -s http://ec2-ip-address:5000 | jq . 14 | { 15 | "availability_zone": "eu-west-1c", 16 | "container_hostname": "83cad2586360", 17 | "instance_hostname": "ip-172-31-84-235", 18 | "instance_lifecycle": "on-demand", 19 | "instance_id": "i-00000000000000000" 20 | } 21 | ``` 22 | 23 | ### CPU Intensive 24 | 25 | On a EC2 Instance: 26 | 27 | ``` 28 | $ docker run -it -p 5000:5000 ruanbekker/aws-metadata-container:cpu 29 | ``` 30 | 31 | Test: 32 | 33 | ``` 34 | $ curl -s http://ec2-ip-address:5000/cpu | jq . 35 | { 36 | "availability_zone": "eu-west-1c", 37 | "container_hostname": "83cad2586360", 38 | "instance_hostname": "ip-172-31-84-235", 39 | "instance_lifecycle": "on-demand", 40 | "instance_id": "i-00000000000000000" 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /aws-metadata-flask/app.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import requests 3 | from flask import Flask, jsonify 4 | 5 | app = Flask(__name__) 6 | 7 | def get_instance_details(): 8 | data = {} 9 | instance_id = requests.get('http://169.254.169.254/latest/meta-data/instance-id').content 10 | availability_zone = requests.get('http://169.254.169.254/latest/meta-data/placement/availability-zone').content 11 | instance_hostname = requests.get('http://169.254.169.254/latest/meta-data/hostname').content 12 | instance_lifecycle = requests.get('http://169.254.169.254/latest/meta-data/instance-life-cycle').content 13 | container_hostname = socket.gethostname() 14 | 15 | data['instance_id'] = instance_id.decode('utf-8') 16 | data['availability_zone'] = availability_zone.decode('utf-8') 17 | data['instance_hostname'] = instance_hostname.decode('utf-8').split('.')[0] 18 | data['instance_lifecycle'] = instance_lifecycle.decode('utf-8') 19 | data['container_hostname'] = container_hostname 20 | 21 | return data 22 | 23 | @app.route('/') 24 | def get(): 25 | instance_details = get_instance_details() 26 | return jsonify(instance_details) 27 | 28 | @app.route('/health') 29 | def health(): 30 | return jsonify({'message': 'ok'}) 31 | 32 | if __name__ == '__main__': 33 | app.run(host='0.0.0.0', port=5000) 34 | -------------------------------------------------------------------------------- /aws-metadata-flask/cpu-app.py: -------------------------------------------------------------------------------- 1 | from random import choice, randint 2 | from string import ascii_letters, punctuation, digits 3 | from flask import Flask, jsonify 4 | import bcrypt 5 | import time 6 | import os 7 | import logging 8 | import socket 9 | import requests 10 | 11 | app = Flask(__name__) 12 | 13 | LOG_ROUNDS = os.environ.get('LOG_ROUNDS', 10) 14 | 15 | def generate_hash(log_rounds): 16 | string_format = ascii_letters + punctuation + digits 17 | generated_string = "".join(choice(string_format) for x in range(randint(5, 20))) 18 | bcrypt_hash = bcrypt.hashpw(generated_string, bcrypt.gensalt(log_rounds)) 19 | return bcrypt_hash 20 | 21 | def get_instance_details(instruction): 22 | data = {} 23 | instance_id = requests.get('http://169.254.169.254/latest/meta-data/instance-id').content 24 | availability_zone = requests.get('http://169.254.169.254/latest/meta-data/placement/availability-zone').content 25 | instance_hostname = requests.get('http://169.254.169.254/latest/meta-data/hostname').content 26 | instance_lifecycle = requests.get('http://169.254.169.254/latest/meta-data/instance-life-cycle').content 27 | container_hostname = socket.gethostname() 28 | 29 | data['instance_id'] = instance_id.decode('utf-8') 30 | data['availability_zone'] = availability_zone.decode('utf-8') 31 | data['instance_hostname'] = instance_hostname.decode('utf-8').split('.')[0] 32 | data['instance_lifecycle'] = instance_lifecycle.decode('utf-8') 33 | data['container_hostname'] = container_hostname 34 | 35 | # generate cpu load 36 | if instruction == 'cpuload': 37 | generate_hash(int(LOG_ROUNDS)) 38 | 39 | return data 40 | 41 | @app.route('/') 42 | def get(): 43 | instance_details = get_instance_details('noload') 44 | return jsonify(instance_details) 45 | 46 | @app.route('/cpu') 47 | def get_cpu(): 48 | instance_details = get_instance_details('cpuload') 49 | return jsonify(instance_details) 50 | 51 | @app.route('/health') 52 | def health(): 53 | return jsonify({'message': 'ok'}) 54 | 55 | if __name__ == '__main__': 56 | app.run(host='0.0.0.0', port=5000) 57 | -------------------------------------------------------------------------------- /awscli/Dockerfile: -------------------------------------------------------------------------------- 1 | # Source: https://github.com/aws/aws-cli/blob/v2/docker/Dockerfile 2 | FROM public.ecr.aws/amazonlinux/amazonlinux:2 as installer 3 | ARG AWS_CLI_VERSION=2.15.19 4 | ENV AWS_CLI_VERSION=$AWS_CLI_VERSION 5 | ARG EXE_FILENAME=awscliv2.zip 6 | 7 | RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWS_CLI_VERSION}.zip" -o "awscliv2.zip" 8 | 9 | RUN yum update -y \ 10 | && yum install -y unzip \ 11 | && unzip $EXE_FILENAME \ 12 | && ./aws/install --bin-dir /aws-cli-bin/ 13 | 14 | FROM mcr.microsoft.com/dotnet/runtime-deps:6.0-jammy 15 | RUN apt update && \ 16 | apt install less groff -y && \ 17 | rm -rf /var/lib/apt/lists/* 18 | COPY --from=installer /usr/local/aws-cli/ /usr/local/aws-cli/ 19 | COPY --from=installer /aws-cli-bin/ /usr/local/bin/ 20 | 21 | WORKDIR /aws 22 | ENTRYPOINT ["/usr/local/bin/aws"] 23 | -------------------------------------------------------------------------------- /awscli/Dockerfile.pip: -------------------------------------------------------------------------------- 1 | FROM python:3.8-alpine 2 | 3 | ENV AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 4 | ENV AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 5 | ENV AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" 6 | ENV AWS_CLI_VERSION=1.20.33 7 | 8 | RUN pip install awscli==$AWS_CLI_VERSION 9 | 10 | ENTRYPOINT [ "aws" ] 11 | -------------------------------------------------------------------------------- /awscli/README.md: -------------------------------------------------------------------------------- 1 | ## Dockerhub 2 | 3 | The dockerhub image can be found at: 4 | - https://hub.docker.com/r/ruanbekker/awscli 5 | 6 | ## Usage 7 | 8 | Example 9 | 10 | ``` 11 | $ docker run -it --rm \ 12 | -e AWS_ACCESS_KEY_ID=123 \ 13 | -e AWS_SECRET_ACCESS_KEY=xyz \ 14 | -e AWS_DEFAULT_REGION: eu-west-1 \ 15 | ruanbekker/awscli s3 ls / 16 | ``` 17 | 18 | Or using functions: 19 | 20 | ``` 21 | aws(){ 22 | docker run --rm -it -v ~/.aws/credentials:/root/.aws/credentials:ro ruanbekker/awscli "$@" 23 | } 24 | ``` 25 | 26 | Or alias: 27 | 28 | ``` 29 | alias aws="docker run --rm -it -v ~/.aws/credentials:/root/.aws/credentials:ro ruanbekker/awscli" 30 | ``` 31 | 32 | ## Dockerhub Images 33 | 34 | - [ruanbekker/awscli:latest](https://hub.docker.com/r/ruanbekker/awscli/tags?page=1&ordering=last_updated) 35 | - [ruanbekker/awscli:1.20.33](https://hub.docker.com/r/ruanbekker/awscli/tags?page=1&ordering=last_updated) 36 | -------------------------------------------------------------------------------- /build-tools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.13 2 | 3 | ENV AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 4 | ENV AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 5 | ENV AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" 6 | ENV TERRAFORM_VERSION=0.12.15 7 | 8 | RUN apk update \ 9 | && apk add curl jq python bash ca-certificates git openssl ncurses unzip wget py2-pip docker \ 10 | && pip install awscli \ 11 | && cd /tmp \ 12 | && wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ 13 | && unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/bin \ 14 | && curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \ 15 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx \ 16 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens \ 17 | && chmod +x ./kube* \ 18 | && mv ./kube* /usr/local/bin/ \ 19 | && rm -rf /tmp/* /var/cache/apk/* rm -rf /var/tmp/* 20 | 21 | #ENTRYPOINT [ "/bin/sh" ] 22 | -------------------------------------------------------------------------------- /build-tools/Dockerfile.slim: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add --no-cache curl mysql-client 3 | -------------------------------------------------------------------------------- /busybox-logger/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM busybox 2 | 3 | ARG version=v1 4 | ENV version=$version 5 | 6 | COPY run.sh /run.sh 7 | RUN chmod +x /run.sh 8 | 9 | CMD ["/run.sh"] 10 | -------------------------------------------------------------------------------- /busybox-logger/README.md: -------------------------------------------------------------------------------- 1 | # busybox-logger 2 | 3 | This is a basic logger that I use to test deployment rollouts. 4 | 5 | ## Image Versions 6 | 7 | The tags can be found on my dockerhub page: 8 | - https://hub.docker.com/r/ruanbekker/busybox-logger 9 | 10 | | Version | Image | 11 | |----------|---------------------------------| 12 | | v1 | `ruanbekker/busybox-logger:v1` | 13 | | v2 | `ruanbekker/busybox-logger:v2` | 14 | | v3 | `ruanbekker/busybox-logger:v3` | 15 | | v4 | `ruanbekker/busybox-logger:v4` | 16 | | v5 | `ruanbekker/busybox-logger:v5` | 17 | | v6 | `ruanbekker/busybox-logger:v6` | 18 | | v7 | `ruanbekker/busybox-logger:v7` | 19 | | v8 | `ruanbekker/busybox-logger:v8` | 20 | | v9 | `ruanbekker/busybox-logger:v9` | 21 | | v10 | `ruanbekker/busybox-logger:v10` | 22 | | v11 | `ruanbekker/busybox-logger:v11` | 23 | | v12 | `ruanbekker/busybox-logger:v12` | 24 | | v13 | `ruanbekker/busybox-logger:v13` | 25 | | v14 | `ruanbekker/busybox-logger:v14` | 26 | | v15 | `ruanbekker/busybox-logger:v15` | 27 | | v16 | `ruanbekker/busybox-logger:v16` | 28 | | v17 | `ruanbekker/busybox-logger:v17` | 29 | | v18 | `ruanbekker/busybox-logger:v18` | 30 | | v19 | `ruanbekker/busybox-logger:v19` | 31 | | v20 | `ruanbekker/busybox-logger:v20` | 32 | 33 | ## Running a container 34 | 35 | To run the container: 36 | 37 | ```bash 38 | docker run -it ruanbekker/busybox-logger:v12 39 | 40 | [2023-09-01T17:45:27] level=info version=v12 message="this is the v12 container running with random id of 25387" 41 | [2023-09-01T17:45:28] level=info version=v12 message="this is the v12 container running with random id of 26780" 42 | [2023-09-01T17:45:30] level=info version=v12 message="this is the v12 container running with random id of 32132" 43 | [2023-09-01T17:45:31] level=info version=v12 message="this is the v12 container running with random id of 12910" 44 | ``` 45 | -------------------------------------------------------------------------------- /busybox-logger/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | while true 4 | do 5 | sleep 1 6 | echo "[$(date +%FT%T)] level=info version=$version message=\"this is the $version container running with random id of $RANDOM\"" 7 | done 8 | -------------------------------------------------------------------------------- /cargo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stretch-slim 2 | ENV PATH ${HOME}/.cargo/bin:${PATH} 3 | 4 | RUN apt-get update && apt-get install curl build-essential libssl-dev pkg-config -y 5 | RUN curl https://sh.rustup.rs -sSf | sh 6 | # cargo install --features=ssl websocat 7 | CMD ["/bin/bash"] 8 | -------------------------------------------------------------------------------- /civocli/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruanbekker/ruby:2.5.1 2 | RUN gem install civo_cli --no-rdoc --no-ri 3 | -------------------------------------------------------------------------------- /containers/README.md: -------------------------------------------------------------------------------- 1 | # containers 2 | 3 | Usefule container images for debug scenarios and ci pipelines 4 | 5 | ## Image Registry 6 | 7 | Container images are hosted on Docker Hub and can be viewed: 8 | - [hub.docker.com/r/ruanbekker/containers](https://hub.docker.com/r/ruanbekker/containers) 9 | 10 | ## Buildx 11 | 12 | Docker Buildx is a CLI plugin that extends the docker command with the full support of the features provided by Moby BuildKit builder toolkit. 13 | 14 | ```bash 15 | docker buildx create --name multi-arch --platform "linux/arm64,linux/amd64,linux/arm/v7" --driver "docker-container" 16 | docker buildx use multi-arch 17 | ``` 18 | 19 | Building: 20 | 21 | ```bash 22 | docker buildx build \ 23 | --platform "linux/amd64,linux/arm64,linux/arm/v7" \ 24 | -f curl.Dockerfile \ 25 | --build-arg timestamp=$(date +%F) \ 26 | -t ruanbekker/containers:curl \ 27 | --push . 28 | ``` 29 | 30 | ## Images 31 | 32 | The following tags are available 33 | 34 | | Name | Container Image | Docker Hub | 35 | | ------ |:-----------------------------:| ----------------------------------------------------------------------------------------------------:| 36 | | curl | `ruanbekker/containers:curl` | [ruanbekker/containers:curl](https://hub.docker.com/r/ruanbekker/containers/tags?page=1&name=curl) | 37 | | echo | `ruanbekker/containers:echo` | [ruanbekker/containers:echo](https://hub.docker.com/r/ruanbekker/containers/tags?page=1&name=echo) | 38 | | mysql | `ruanbekker/containers:mysql` | [ruanbekker/containers:mysql](https://hub.docker.com/r/ruanbekker/containers/tags?page=1&name=mysql) | 39 | | nginx | `ruanbekker/containers:nginx` | [ruanbekker/containers:nginx](https://hub.docker.com/r/ruanbekker/containers/tags?page=1&name=nginx) | 40 | 41 | 42 | -------------------------------------------------------------------------------- /containers/curl.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | ARG timestamp 3 | LABEL built_date=$timestamp 4 | RUN apk --no-cache add curl bind-tools 5 | 6 | -------------------------------------------------------------------------------- /containers/devops.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM amazon/aws-cli:2.7.30 2 | 3 | ENV TERRAFORM_VERSION 0.13.5 4 | ENV HELM_VERSION 3.9.4 5 | 6 | RUN yum install jq gzip vim tar git unzip wget -y 7 | 8 | RUN cd /tmp/ && wget https://releases.hashicorp.com/terraform/$TERRAFORM_VERSION/terraform_"$TERRAFORM_VERSION"_linux_amd64.zip \ 9 | && unzip terraform_"$TERRAFORM_VERSION"_linux_amd64.zip \ 10 | && chmod +x terraform && mv terraform /usr/local/bin/terraform \ 11 | && wget https://get.helm.sh/helm-v$HELM_VERSION-linux-amd64.tar.gz \ 12 | && tar -xf helm-v$HELM_VERSION-linux-amd64.tar.gz \ 13 | && mv linux-amd64/helm /usr/bin/helm \ 14 | && rm -rf linux-amd64 \ 15 | && curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl \ 16 | && chmod +x ./kubectl \ 17 | && mv ./kubectl /usr/local/bin/kubectl \ 18 | && yum clean all \ 19 | && rm -rf /var/cache/yum 20 | 21 | ENTRYPOINT ["sh"] 22 | -------------------------------------------------------------------------------- /containers/mysql.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | ARG timestamp 3 | LABEL built_date=$timestamp 4 | RUN apk --no-cache add mysql-client 5 | 6 | -------------------------------------------------------------------------------- /containers/nginx.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:stable 2 | ARG timestamp 3 | LABEL built_date=$timestamp 4 | 5 | 6 | -------------------------------------------------------------------------------- /cpp-hello-world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(helloworld) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | add_executable(hello main.cpp) 7 | -------------------------------------------------------------------------------- /cpp-hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:focal 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | ENV TZ=Africa/Johannesburg 5 | 6 | WORKDIR /app 7 | 8 | RUN apt update && \ 9 | apt install build-essential git cmake autoconf libtool pkg-config -y 10 | 11 | ADD main.cpp . 12 | ADD CMakeLists.txt . 13 | 14 | RUN cmake . && make 15 | 16 | CMD ["/app/hello"] 17 | -------------------------------------------------------------------------------- /cpp-hello-world/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::cout << "hello, world!" << std::endl; 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /curl-ares/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | WORKDIR /tmp 4 | 5 | RUN apt update && \ 6 | # Install build dependencies 7 | apt install -y build-essential autoconf automake libtool pkg-config git libssl-dev libc-ares-dev && \ 8 | 9 | # Build and install curl 10 | git clone --depth 1 https://github.com/curl/curl.git && \ 11 | cd curl && \ 12 | autoreconf -fi && \ 13 | ./configure --enable-ares --with-openssl && \ 14 | make && \ 15 | make install && \ 16 | ldconfig && \ 17 | 18 | # Remove build dependencies and cleanup 19 | apt purge -y build-essential autoconf automake libtool pkg-config git libssl-dev libc-ares-dev && \ 20 | apt clean autoclean && \ 21 | apt autoremove -y && \ 22 | rm -rf /var/lib/{apt,dpkg,cache,log}/ && \ 23 | rm -rf /tmp/* 24 | 25 | ENTRYPOINT ["/usr/local/bin/curl"] 26 | 27 | # Usage: 28 | # curl --dns-servers 10.10.200.2 --location 'http://some-endpoint.lan' 29 | -------------------------------------------------------------------------------- /curl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM apline 2 | RUN apk --no-cache add curl jq 3 | -------------------------------------------------------------------------------- /devopstools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV TERRAFORM_VERSION=0.13.3 4 | ENV ANSIBLE_VERSION=2.10.0 5 | ENV AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 6 | ENV AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 7 | ENV AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" 8 | 9 | RUN apk add --no-cache --virtual=.build-deps libffi-dev openssl-dev build-base \ 10 | && apk add --no-cache --virtual=.run-deps openssh-client ca-certificates openssl \ 11 | && pip install --no-cache-dir cffi==1.14.3 ansible==${ANSIBLE_VERSION} \ 12 | && apk del .build-deps \ 13 | && ln -s /usr/local/bin/python /usr/bin/python 14 | 15 | RUN apk add --no-cache curl jq bash ca-certificates git openssl ncurses unzip wget iptables git mysql-client \ 16 | && pip install awscli \ 17 | && cd /tmp \ 18 | && wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ 19 | && unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/bin \ 20 | && curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \ 21 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx \ 22 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens \ 23 | && chmod +x ./kube* \ 24 | && mv ./kube* /usr/local/bin/ \ 25 | && rm -rf /tmp/* \ 26 | && rm -rf /var/cache/apk/* \ 27 | && rm -rf /var/tmp/* 28 | 29 | RUN wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.10.tgz \ 30 | && tar -xf docker-19.03.10.tgz \ 31 | && rm -rf docker-19.03.10.tgz \ 32 | && mv docker/* /usr/local/bin/ \ 33 | && rm -rf docker 34 | 35 | # ansible galaxy 36 | RUN pip install --upgrade --user openshift && ansible-galaxy collection install community.kubernetes 37 | 38 | ENV WAYPOINT_VERSION 0.1.4 39 | ENV WAYPOINT_OS linux 40 | ENV WAYPOINT_ARCH amd64 41 | 42 | RUN wget https://releases.hashicorp.com/waypoint/${WAYPOINT_VERSION}/waypoint_${WAYPOINT_VERSION}_${WAYPOINT_OS}_${WAYPOINT_ARCH}.zip \ 43 | && unzip waypoint_${WAYPOINT_VERSION}_${WAYPOINT_OS}_${WAYPOINT_ARCH}.zip \ 44 | && mv waypoint /usr/local/bin/waypoint \ 45 | && chmod +x /usr/local/bin/waypoint \ 46 | && rm -rf waypoint_${WAYPOINT_VERSION}_${WAYPOINT_OS}_${WAYPOINT_ARCH}.zip 47 | 48 | RUN echo Terraform: ${TERRAFORM_VERSION} > /root/devopstools_info.txt && \ 49 | echo Ansible: ${ANSIBLE_VERSION} >> /root/devopstools_info.txt && \ 50 | echo Kubectl: $(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) >> /root/devopstools_info.txt 51 | 52 | ENV PS1 "\h > " 53 | CMD ["/bin/bash"] 54 | 55 | -------------------------------------------------------------------------------- /docker-remote-tools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add --no-cache openssh docker 3 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine AS builder 2 | ENV DOCKER_VERSION 19.03.10 3 | ENV DOCKER_ARCH x86_64 4 | 5 | RUN apk add --no-cache wget openssl \ 6 | && wget https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \ 7 | && tar -xf docker-${DOCKER_VERSION}.tgz && mv docker/docker /opt/docker 8 | 9 | FROM busybox 10 | COPY --from=builder /opt/docker /bin/docker 11 | 12 | CMD ["/bin/sh"] 13 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | ![publish-docker-image](https://github.com/ruanbekker/dockerfiles/workflows/publish-docker-image/badge.svg?branch=master) 2 | -------------------------------------------------------------------------------- /dockerd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add wget iptables lxc tar curl 4 | 5 | RUN wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.10.tgz \ 6 | && tar -xf docker-19.03.10.tgz \ 7 | && rm -rf docker-19.03.10.tgz \ 8 | && mv docker/* /usr/local/bin/ \ 9 | && rm -rf docker 10 | 11 | ADD entrypoint.sh /bin/entrypoint.sh 12 | RUN chmod +x /bin/entrypoint.sh 13 | 14 | ENTRYPOINT ["/bin/entrypoint.sh"] 15 | CMD ["/bin/sh"] 16 | -------------------------------------------------------------------------------- /dockerd/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 &> /dev/null & 4 | exec "$@" 5 | -------------------------------------------------------------------------------- /drone-gitea/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | gitea: 5 | image: gitea/gitea:1.7.4 6 | container_name: gitea 7 | environment: 8 | - USER_UID=1000 9 | - USER_GID=1000 10 | - ROOT_URL=http://gitea.localhost:3000 11 | - SSH_DOMAIN=gitea.localhost 12 | - APP_NAME=Gitea 13 | - SSH_PORT=2222 14 | - HTTP_PORT=3000 15 | - DB_TYPE=postgres 16 | - DB_HOST=postgres:5432 17 | - DB_NAME=gitea 18 | - DB_USER=postgres 19 | - DB_PASSWD=postgres 20 | restart: always 21 | volumes: 22 | - gitea-app:/data 23 | ports: 24 | - "3000:3000" 25 | - "2222:22" 26 | networks: 27 | - appnet 28 | 29 | postgres: 30 | image: postgres:alpine 31 | container_name: postgres 32 | ports: 33 | - 5440:5432 34 | restart: always 35 | volumes: 36 | - postgres:/var/lib/postgresql/data 37 | environment: 38 | - POSTGRES_USER=postgres 39 | - POSTGRES_PASSWORD=postgres 40 | - POSTGRES_DB=gitea 41 | - PGDATA=/var/lib/postgresql/data 42 | networks: 43 | - appnet 44 | 45 | drone-server: 46 | image: drone/drone:0.8 47 | container_name: drone-server 48 | ports: 49 | - "8001:8000" 50 | - "9000:9000" 51 | volumes: 52 | - drone-server:/var/lib/drone/ 53 | restart: always 54 | depends_on: 55 | - gitea 56 | environment: 57 | - DRONE_OPEN=true 58 | - DRONE_GITEA=true 59 | - DRONE_ADMIN=rbekker87 60 | - DRONE_USER_CREATE=username:rbekker87,admin:true 61 | - DRONE_SERVER_PORT=:8000 62 | - DRONE_GITEA_URL=http://gitea:3000 63 | - DRONE_SECRET=secret 64 | - DRONE_NETWORK=appnet 65 | - DRONE_HOST=http://drone-server:80 66 | - DRONE_DATABASE_DRIVER=postgres 67 | - DRONE_DATABASE_DATASOURCE=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable 68 | depends_on: 69 | - postgres 70 | networks: 71 | - appnet 72 | 73 | drone-agent: 74 | image: drone/agent:1 75 | container_name: drone-agent 76 | command: agent 77 | restart: always 78 | depends_on: 79 | - drone-server 80 | volumes: 81 | - /var/run/docker.sock:/var/run/docker.sock 82 | environment: 83 | - DRONE_SERVER=drone-server:9000 84 | - DRONE_SECRET=secret 85 | networks: 86 | - appnet 87 | 88 | volumes: 89 | gitea-app: 90 | postgres: 91 | drone-server: 92 | 93 | networks: 94 | appnet: 95 | -------------------------------------------------------------------------------- /drone-gitea/docker-compose_mysql-minio.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | traefik: 5 | image: traefik:1.7.14 6 | ports: 7 | - 80:80 8 | labels: 9 | - traefik.frontend.rule=Host:traefik.${DOMAIN:-localhost} 10 | - traefik.enable=true 11 | - traefik.port=8080 12 | - traefik.tags=public 13 | - traefik.docker.network=public 14 | - traefik.redirectorservice.frontend.entryPoints=http 15 | volumes: 16 | - /var/run/docker.sock:/var/run/docker.sock 17 | command: > 18 | --docker 19 | --docker.watch 20 | --docker.exposedbydefault=false 21 | --entrypoints='Name:http Address::80' 22 | --logLevel=INFO 23 | --accessLog 24 | --api 25 | --metrics 26 | --metrics.prometheus 27 | networks: 28 | - public 29 | - private 30 | gitea: 31 | image: gitea/gitea:latest 32 | ports: 33 | - 3000:3000 34 | environment: 35 | - APP_NAME=Gitea 36 | - USER_UID=1000 37 | - USER_GID=1000 38 | - ROOT_URL=http://gitea:3000 39 | - SSH_DOMAIN=gitea 40 | - SSH_PORT=2222 41 | - HTTP_PORT=3000 42 | - DB_TYPE=postgres 43 | - DB_HOST=gitea-db:5432 44 | - DB_NAME=gitea 45 | - DB_USER=postgres 46 | - DB_PASSWD=postgres 47 | volumes: 48 | - gitea_app:/data 49 | ports: 50 | - 2222:2222 51 | networks: 52 | - public 53 | - private 54 | labels: 55 | - "traefik.docker.network=public" 56 | - "traefik.port=3000" 57 | - "traefik.backend=gitea" 58 | - "traefik.enable=true" 59 | - "traefik.frontend.rule=Host:gitea" 60 | - "traefik.frontend.entryPoints=http" 61 | 62 | gitea-db: 63 | image: postgres:alpine 64 | volumes: 65 | - gitea_db:/var/lib/postgresql/data 66 | environment: 67 | - POSTGRES_USER=postgres 68 | - POSTGRES_PASSWORD=postgres 69 | - POSTGRES_DB=gitea 70 | networks: 71 | - private 72 | 73 | drone-server: 74 | image: drone/drone:1.2.1 75 | volumes: 76 | - drone:/var/lib/drone 77 | - /var/run/docker.sock:/var/run/docker.sock 78 | environment: 79 | - DRONE_DEBUG=true 80 | - DRONE_ADMIN=rbekker87 81 | - DRONE_USER_CREATE=username:rbekker87,admin:true 82 | - DRONE_SERVER_PORT=:80 83 | - DRONE_DATABASE_DRIVER=sqlite3 84 | - DRONE_GIT_ALWAYS_AUTH=false 85 | - DRONE_GITEA_SERVER=http://gitea:3000 86 | - DRONE_RPC_SECRET=9c3921e3e748aff725d2e16ef31fbc42 87 | - DRONE_SERVER_HOST=drone-server:80 88 | - DRONE_HOST=http://drone-server:80 89 | - DRONE_SERVER_PROTO=http 90 | - DRONE_TLS_AUTOCERT=false 91 | - DRONE_AGENTS_ENABLED=true 92 | # minio: need to create bucket first 93 | - DRONE_S3_ENDPOINT=http://minio:9000 94 | - DRONE_S3_BUCKET=drone 95 | - DRONE_S3_SKIP_VERIFY=true 96 | - DRONE_S3_PATH_STYLE=true 97 | - DRONE_LOGS_PRETTY=true 98 | - DRONE_LOGS_COLOR=true 99 | - AWS_ACCESS_KEY_ID=foo1234567 100 | - AWS_SECRET_ACCESS_KEY=bar1234567 101 | - AWS_DEFAULT_REGION=us-east-1 102 | - AWS_REGION=us-east-1 103 | networks: 104 | - public 105 | - private 106 | labels: 107 | - "traefik.docker.network=public" 108 | - "traefik.port=80" 109 | - "traefik.backend=drone-server" 110 | - "traefik.enable=true" 111 | - "traefik.frontend.rule=Host:drone" 112 | - "traefik.frontend.entryPoints=http" 113 | depends_on: 114 | - traefik 115 | - gitea-db 116 | drone-agent: 117 | image: drone/agent:1.2.1 118 | command: agent 119 | volumes: 120 | - /var/run/docker.sock:/var/run/docker.sock 121 | environment: 122 | - DRONE_RPC_SERVER=http://drone-server:80 123 | - DRONE_RPC_SECRET=9c3921e3e748aff725d2e16ef31fbc42 124 | - DRONE_RUNNER_CAPACITY=2 125 | - DRONE_RUNNER_NETWORKS=private 126 | networks: 127 | - private 128 | - public 129 | depends_on: 130 | - drone-server 131 | 132 | minio: 133 | image: minio/minio:RELEASE.2019-03-27T22-35-21Z 134 | container_name: minio 135 | volumes: 136 | - minio:/data 137 | ports: 138 | - "8003:9000" 139 | environment: 140 | - MINIO_ACCESS_KEY=foo1234567 141 | - MINIO_SECRET_KEY=bar1234567 142 | command: server /data 143 | labels: 144 | - "traefik.docker.network=public" 145 | - "traefik.port=9000" 146 | - "traefik.backend=minio" 147 | - "traefik.enable=true" 148 | - "traefik.frontend.rule=Host:minio" 149 | - "traefik.frontend.entryPoints=http" 150 | networks: 151 | - public 152 | - private 153 | 154 | volumes: 155 | gitea_app: {} 156 | gitea_db: {} 157 | drone: {} 158 | minio: {} 159 | 160 | networks: 161 | public: 162 | name: public 163 | private: 164 | name: private 165 | -------------------------------------------------------------------------------- /drone-gogs/README.md: -------------------------------------------------------------------------------- 1 | Golang Example: 2 | - https://github.com/katacoda/golang-http-server 3 | -------------------------------------------------------------------------------- /drone-gogs/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | postgres: 5 | image: postgres:9.5 6 | restart: always 7 | environment: 8 | - "POSTGRES_USER=gogsuser" 9 | - "POSTGRES_PASSWORD=gogspassword" 10 | - "POSTGRES_DB=gogs" 11 | volumes: 12 | - "db-data:/var/lib/postgresql/data" 13 | gogs: 14 | image: gogs/gogs:latest 15 | restart: always 16 | ports: 17 | - "10022:22" 18 | - "3000:3000" 19 | links: 20 | - postgres 21 | environment: 22 | - "RUN_CROND=true" 23 | volumes: 24 | - "gogs-data:/data" 25 | depends_on: 26 | - postgres 27 | drone-server: 28 | image: drone/drone:0.8 29 | ports: 30 | - 80:8000 31 | - 9000 32 | volumes: 33 | - /var/lib/drone:/var/lib/drone/ 34 | restart: always 35 | links: 36 | - gogs 37 | environment: 38 | - DRONE_OPEN=true 39 | - DRONE_GOGS=true 40 | - DRONE_GOGS_URL=http://gogs:3000 41 | - DRONE_HOST=${DRONE_HOST:-http://localhost:80} 42 | - DRONE_SECRET=SOME_RANDOM_STRING 43 | drone-agent: 44 | image: drone/agent:0.8 45 | command: agent 46 | restart: always 47 | depends_on: 48 | - drone-server 49 | volumes: 50 | - /var/run/docker.sock:/var/run/docker.sock 51 | environment: 52 | - DRONE_SERVER=drone-server:9000 53 | - DRONE_SECRET=SOME_RANDOM_STRING 54 | 55 | volumes: 56 | db-data: 57 | driver: local 58 | gogs-data: 59 | driver: local 60 | -------------------------------------------------------------------------------- /drone/agent/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ENV GODEBUG=netdns=go 3 | ENV DRONE_PLATFORM=linux/amd64 4 | ADD release/linux/amd64/drone-agent /bin/ 5 | 6 | ENTRYPOINT ["/bin/drone-agent"] 7 | -------------------------------------------------------------------------------- /drone/agent/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DRONE_BUILD_NUMBER=1.2.3 4 | wget https://github.com/drone/drone/archive/v${DRONE_BUILD_NUMBER}.zip 5 | unzip v$DRONE_BUILD_NUMBER.zip 6 | cd drone-$DRONE_BUILD_NUMBER/cmd/drone-agent/ 7 | go get 8 | GOOS=linux GOARCH=amd64 go build -ldflags '-X github.com/drone/drone/version.VersionDev=build.'${DRONE_BUILD_NUMBER} -o release/linux/amd64/drone-agent github.com/drone/drone/cmd/drone-agent 9 | mv release ../../../ 10 | cd ../../.. 11 | -------------------------------------------------------------------------------- /drone/server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.10.1 as alpine 2 | RUN apk add -U --no-cache ca-certificates 3 | 4 | FROM pistacks/alpine:3.10.1 5 | ENV GODEBUG netdns=go 6 | ENV XDG_CACHE_HOME /data 7 | ENV DRONE_DATABASE_DRIVER sqlite3 8 | ENV DRONE_DATABASE_DATASOURCE /data/database.sqlite 9 | ENV DRONE_RUNNER_OS=linux 10 | ENV DRONE_RUNNER_ARCH=amd64 11 | ENV DRONE_SERVER_PORT=:80 12 | ENV DRONE_SERVER_HOST=localhost 13 | COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 14 | 15 | ADD release/linux/amd64/drone-server /bin/ 16 | 17 | ENTRYPOINT ["/bin/drone-server"] 18 | -------------------------------------------------------------------------------- /drone/server/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DRONE_BUILD_NUMBER=1.2.3 4 | wget https://github.com/drone/drone/archive/v${DRONE_BUILD_NUMBER}.zip 5 | unzip v$DRONE_BUILD_NUMBER.zip 6 | cd drone-$DRONE_BUILD_NUMBER/cmd/drone-server/ 7 | go get 8 | GOOS=linux GOARCH=amd64 go build -ldflags '-X github.com/drone/drone/version.VersionDev=build.'${DRONE_BUILD_NUMBER} -o release/linux/amd64/drone-server github.com/drone/drone/cmd/drone-server 9 | mv release ../../../ 10 | cd ../../.. 11 | -------------------------------------------------------------------------------- /dynamodb-ui/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.16.0-stretch 2 | 3 | ENV DYNAMO_ENDPOINT=${DYNAMO_ENDPOINT} 4 | 5 | RUN npm install dynamodb-admin -g 6 | 7 | CMD ["dynamodb-admin", "--port", "8000"] 8 | -------------------------------------------------------------------------------- /dynamodb-ui/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | dynamodb-ui: 5 | image: ruanbekker/dynamodb 6 | networks: 7 | - dynamodb 8 | 9 | dynamodb-svc: 10 | image: ruanbekker/dynamodb-ui:latest 11 | ports: 12 | - 8082:8000 13 | environment: 14 | - DYNAMO_ENDPOINT=http://dynamodb-ui:4567 15 | networks: 16 | - dynamodb 17 | 18 | networks: 19 | dynamodb: {} 20 | -------------------------------------------------------------------------------- /dynamodb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.16.0-stretch-slim 2 | 3 | RUN apt update && apt install build-essential python-minimal -y && mkdir /data 4 | RUN npm install --unsafe-perm -g dynalite 5 | RUN apt-get clean 6 | 7 | CMD ["dynalite", "--port", "8000", "--path", "/data", "--maxItemSizeKb", "400"] 8 | -------------------------------------------------------------------------------- /dynamodb/Dockerfile.local: -------------------------------------------------------------------------------- 1 | FROM openjdk:11.0-jre-slim 2 | 3 | WORKDIR /usr/local/dynamodb 4 | ADD https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.tar.gz . 5 | RUN tar -xf dynamodb_local_latest.tar.gz \ 6 | && rm -rf dynamodb_local_latest.tar.gz 7 | 8 | EXPOSE 8000 9 | ENTRYPOINT ["/usr/bin/java", "-Djava.library.path=.", "-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"] 10 | CMD ["-port", "8000"] 11 | -------------------------------------------------------------------------------- /dynamodb/README.md: -------------------------------------------------------------------------------- 1 | # dynamodb-on-docker 2 | DynamoDB Local on Docker 3 | 4 | ## Docker Hub 5 | 6 | ``` 7 | $ docker run -it -p 8000:4567 ruanbekker/dynamodb 8 | ``` 9 | -------------------------------------------------------------------------------- /dynamodb/example_boto3.md: -------------------------------------------------------------------------------- 1 | ``` 2 | import boto3 3 | dynamodb = boto3.resource('dynamodb', endpoint_url='http://localhost:8000') 4 | table = dynamodb.create_table(TableName='staffs',KeySchema=[{'AttributeName': 'username', 'KeyType': 'HASH'}, {'AttributeName': 'last_name', 'KeyType': 'RANGE'}],AttributeDefinitions=[{'AttributeName': 'username','AttributeType': 'S'},{'AttributeName': 'last_name', 'AttributeType': 'S'}], ProvisionedThroughput={'ReadCapacityUnits': 1,'WriteCapacityUnits': 1}) 5 | table.item_count 6 | table.put_item(Item={'username': 'ruanb','first_name': 'ruan','last_name': 'bekker','age': 30,'account_type': 'administrator'}) 7 | table.scan() 8 | ``` 9 | 10 | More examples: https://sysadmins.co.za/interfacing-amazon-dynamodb-with-python-using-boto3/ 11 | -------------------------------------------------------------------------------- /envsubst/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk --no-cache add libintl gettext vim 3 | RUN echo 'set mouse-=a' > /root/.vimrc 4 | -------------------------------------------------------------------------------- /filebeat-mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.elastic.co/beats/filebeat:6.3.1 2 | 3 | ENV ES_HOST elasticsearch 4 | ENV ES_PORT 9200 5 | ENV ES_PROT "http" 6 | ENV ES_USER elastic 7 | ENV ES_PASS changeme 8 | ENV ES_INDEX "filebeat-%{+yyyy.MM.dd}" 9 | ENV LOGGING_LEVEL "warning" 10 | 11 | RUN filebeat modules enable mysql 12 | USER root 13 | 14 | COPY filebeat.yml /usr/share/filebeat/filebeat.yml 15 | COPY mysql.yml /usr/share/filebeat/modules.d/mysql.yml 16 | RUN chmod go-w /usr/share/filebeat/filebeat.yml 17 | 18 | RUN filebeat test config -c /usr/share/filebeat/filebeat.yml 19 | 20 | ENTRYPOINT ["filebeat"] 21 | -------------------------------------------------------------------------------- /filebeat-mysql/filebeat.yml: -------------------------------------------------------------------------------- 1 | filebeat.config: 2 | prospectors: 3 | path: ${path.config}/prospectors.d/*.yml 4 | reload.enabled: false 5 | modules: 6 | path: ${path.config}/modules.d/*.yml 7 | reload.enabled: false 8 | 9 | processors: 10 | - add_cloud_metadata: 11 | 12 | output.elasticsearch: 13 | enabled: true 14 | hosts: ["${ES_HOST}:${ES_PORT}"] 15 | protocol: "${ES_PROT}" 16 | username: "${ES_USER}" 17 | password: "${ES_PASS}" 18 | index: "${ES_INDEX}" 19 | 20 | setup.template.name: "filebeat" 21 | setup.template.pattern: "filebeat-*" 22 | -------------------------------------------------------------------------------- /filebeat-mysql/mysql.yml: -------------------------------------------------------------------------------- 1 | - module: mysql 2 | error: 3 | enabled: true 4 | var.paths: 5 | - /var/log/mysql/error.log 6 | 7 | slowlog: 8 | enabled: true 9 | var.paths: 10 | - /var/log/mysql/slow.log 11 | -------------------------------------------------------------------------------- /flask-message/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/x86_64 python:3.8-alpine 2 | 3 | RUN pip install flask 4 | COPY app.py /app.py 5 | 6 | CMD ["python", "app.py"] 7 | -------------------------------------------------------------------------------- /flask-message/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, request 2 | import os, socket, json 3 | 4 | app = Flask(__name__) 5 | 6 | @app.route('/', defaults={'path': ''}) 7 | @app.route('/') 8 | def catch_all(path): 9 | HOSTNAME = socket.gethostname() 10 | MESSAGE = os.environ['APP_MESSAGE'] 11 | NAMESPACE = os.environ['NAMESPACE'] 12 | IP = request.environ.get('HTTP_X_REAL_IP', request.remote_addr) 13 | 14 | return jsonify({ 15 | 'message': MESSAGE, 16 | 'hostname': HOSTNAME, 17 | 'namespace': NAMESPACE, 18 | 'ip-address': IP, 19 | 'request-path': path, 20 | 'headers': json.loads(json.dumps({k:v for k, v in request.headers})) 21 | }) 22 | 23 | if __name__ == '__main__': 24 | app.run(host='0.0.0.0') 25 | -------------------------------------------------------------------------------- /fluentd-influxdb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fluent/fluentd 2 | USER root 3 | ENV FLUENTD_CONF=fluent.conf 4 | RUN ["gem", "install", "fluent-plugin-influxdb"] 5 | USER fluent 6 | ENTRYPOINT ["fluentd", "-c", "/fluentd/etc/fluent.conf"] 7 | -------------------------------------------------------------------------------- /fluentd-influxdb/README.md: -------------------------------------------------------------------------------- 1 | # fluentd-influxdb 2 | 3 | Push docker logs to InfluxDB with FluentD, example at: 4 | - https://github.com/bekkerstacks/logging-tigf 5 | -------------------------------------------------------------------------------- /fluentd-influxdb/fluent.conf: -------------------------------------------------------------------------------- 1 | 2 | @type forward 3 | port 24224 4 | bind 0.0.0.0 5 | 6 | 7 | 8 | @type record_transformer 9 | 10 | hostname "#{Socket.gethostname}" 11 | tag ${tag} 12 | stack_name ${tag_parts[1]} 13 | service_name ${tag_parts[2]} 14 | fluentd_hostname "#{ENV['FLUENTD_HOSTNAME']}" 15 | 16 | 17 | 18 | 19 | @type influxdb 20 | host influxdb 21 | port 8086 22 | dbname logs 23 | user admin 24 | password admin 25 | use_ssl false 26 | time_precision ms 27 | 28 | @type memory 29 | flush_interval 5 30 | 31 | 32 | -------------------------------------------------------------------------------- /fluentd-loki/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fluent/fluentd 2 | USER root 3 | ENV FLUENTD_CONF=fluent.conf 4 | RUN ["gem", "install", "fluent-plugin-loki"] 5 | USER fluent 6 | ENTRYPOINT ["fluentd", "-c", "/fluentd/etc/fluent.conf"] 7 | -------------------------------------------------------------------------------- /fluentd-loki/fluent.conf: -------------------------------------------------------------------------------- 1 | 2 | @type forward 3 | port 24224 4 | bind 0.0.0.0 5 | 6 | 7 | 8 | @type record_transformer 9 | 10 | hostname "#{Socket.gethostname}" 11 | tag ${tag} 12 | stack_name ${tag_parts[1]} 13 | service_name ${tag_parts[2]} 14 | fluentd_hostname "#{ENV['FLUENTD_HOSTNAME']}" 15 | 16 | 17 | 18 | # https://github.com/eeddaann/fluent-plugin-loki 19 | 20 | @type loki 21 | url "#{ENV['LOKI_URL']}" 22 | endpoint_url "#{ENV['LOKI_URL']}" 23 | username "#{ENV['LOKI_USERNAME']}" 24 | password "#{ENV['LOKI_PASSWORD']}" 25 | extra_labels {"env":"test", "foo": "bar"} 26 | flush_interval 10s 27 | flush_at_shutdown true 28 | buffer_chunk_limit 1m 29 | 30 | @type memory 31 | flush_interval 5 32 | 33 | 34 | -------------------------------------------------------------------------------- /fluentd-loki/resources.md: -------------------------------------------------------------------------------- 1 | - https://blog.giantswarm.io/grafana-logging-using-loki/ 2 | - https://medium.com/@Oskarr3/feeding-loki-with-fluentd-4e9647d23ab9 3 | - https://github.com/eeddaann/fluent-plugin-loki 4 | -------------------------------------------------------------------------------- /gitbook/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.4.0-alpine 2 | 3 | ARG GITBOOK_VERSION=3.2.3 4 | LABEL version=$GITBOOK_VERSION 5 | 6 | RUN npm install --global gitbook-cli \ 7 | && gitbook fetch ${GITBOOK_VERSION} \ 8 | && npm cache verify \ 9 | && rm -rf /tmp/* 10 | 11 | WORKDIR /srv/gitbook 12 | VOLUME /srv/gitbook 13 | 14 | EXPOSE 4000 35729 15 | 16 | # https://github.com/GitbookIO/gitbook-cli/issues/55 17 | COPY copyPluginAssets.js /root/.gitbook/versions/${GITBOOK_VERSION}/lib/output/website/copyPluginAssets.js 18 | 19 | CMD ["gitbook", "--help"] 20 | -------------------------------------------------------------------------------- /gitbook/README.md: -------------------------------------------------------------------------------- 1 | ## Theme: Default 2 | 3 | Make sure that `book.json` is not in your current working directory, as it's meant for installing the FAQ theme. 4 | 5 | File structure: 6 | 7 | ``` 8 | $ find . 9 | . 10 | ./docker/install-docker.md 11 | ./SUMMARY.md 12 | ./README.md 13 | ./aws/deploy-docker-swarm-on-aws.md 14 | ./aws/how-to-debug-a-lambda-function.md 15 | ``` 16 | 17 | Summary Page: 18 | 19 | ``` 20 | $ cat SUMMARY.md 21 | # Summary 22 | 23 | * [Docker](docker/README.md) 24 | * [Docker Swarm on AWS](aws/deploy-docker-swarm-on-aws.md) 25 | * [Install Docker](docker/install-docker.md) 26 | * [AWS](aws/README.md) 27 | * [Debug Lambda on AWS](aws/how-to-debug-a-lambda-function.md) 28 | ``` 29 | 30 | Initialize: 31 | 32 | ``` 33 | $ docker run --rm -v "$PWD:/srv/gitbook" -p 4000:4000 ruanbekker/gitbook:3.2.3 gitbook init 34 | ``` 35 | 36 | Serve: 37 | 38 | ``` 39 | $ docker run --rm -v "$PWD:/srv/gitbook" -p 4000:4000 ruanbekker/gitbook:3.2.3 gitbook serve 40 | ``` 41 | 42 | Home Page: 43 | 44 | image 45 | 46 | 47 | ## Theme: FAQ 48 | 49 | File structure: 50 | 51 | ``` 52 | $ find . | grep -v _book | grep -v node_modules 53 | . 54 | ./docker/install-docker.md 55 | ./SUMMARY.md 56 | ./book.json 57 | ./README.md 58 | ./aws/deploy-docker-swarm-on-aws.md 59 | ./aws/how-to-debug-a-lambda-function.md 60 | ``` 61 | 62 | Summary Page: 63 | 64 | ``` 65 | $ cat SUMMARY.md 66 | # Summary 67 | 68 | * [Introduction](README.md) 69 | * [Docker Swarm on AWS](aws/deploy-docker-swarm-on-aws.md) 70 | * [Debug Lambda on AWS](aws/how-to-debug-a-lambda-function.md) 71 | * [Install Docker](docker/install-docker.md) 72 | ``` 73 | 74 | Support for related pages: 75 | 76 | ``` 77 | $ cat aws/deploy-docker-swarm-on-aws.md 78 | --- 79 | related: 80 | - docker/install-docker.md 81 | 82 | --- 83 | # Deploy Docker on AWS 84 | 85 | Tutorial showing you how to deploy docker on aws 86 | ``` 87 | 88 | Initialize: 89 | 90 | ``` 91 | $ docker run --rm -v "$PWD:/srv/gitbook" -p 4000:4000 ruanbekker/gitbook:3.2.3 gitbook init 92 | ``` 93 | 94 | Install Plugin: 95 | 96 | ``` 97 | $ docker run --rm -v "$PWD:/srv/gitbook" -p 4000:4000 ruanbekker/gitbook:3.2.3 gitbook install 98 | ``` 99 | 100 | Serve: 101 | 102 | ``` 103 | $ docker run --rm -v "$PWD:/srv/gitbook" -p 4000:4000 ruanbekker/gitbook:3.2.3 gitbook serve 104 | ``` 105 | 106 | FAQ Home Page: 107 | 108 | image 109 | 110 | Search Result: 111 | 112 | image 113 | 114 | Related Docs: 115 | 116 | image 117 | 118 | ## Resources: 119 | - https://github.com/GitbookIO?utf8=%E2%9C%93&q=faq&type=&language= 120 | - https://github.com/GitbookIO/theme-faq 121 | - https://github.com/billryan/algorithm-exercise/tree/master/en 122 | -------------------------------------------------------------------------------- /gitbook/book.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "GitBook Help Center", 3 | "plugins": [ "theme-faq", "search", "lunr", "-fontsettings", "-sharing" ] 4 | } 5 | -------------------------------------------------------------------------------- /gitbook/copyPluginAssets.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var ASSET_FOLDER = require('../../constants/pluginAssetsFolder'); 4 | var Promise = require('../../utils/promise'); 5 | var fs = require('../../utils/fs'); 6 | 7 | /** 8 | Copy all assets from plugins. 9 | Assets are files stored in "_assets" 10 | nd resources declared in the plugin itself. 11 | 12 | @param {Output} 13 | @return {Promise} 14 | */ 15 | function copyPluginAssets(output) { 16 | var book = output.getBook(); 17 | 18 | // Don't copy plugins assets for language book 19 | // It'll be resolved to the parent folder 20 | if (book.isLanguageBook()) { 21 | return Promise(output); 22 | } 23 | 24 | var plugins = output.getPlugins() 25 | 26 | // We reverse the order of plugins to copy 27 | // so that first plugins can replace assets from other plugins. 28 | .reverse(); 29 | 30 | return Promise.forEach(plugins, function(plugin) { 31 | return copyAssets(output, plugin) 32 | .then(function() { 33 | return copyResources(output, plugin); 34 | }); 35 | }) 36 | .thenResolve(output); 37 | } 38 | 39 | /** 40 | Copy assets from a plugin 41 | 42 | @param {Plugin} 43 | @return {Promise} 44 | */ 45 | function copyAssets(output, plugin) { 46 | var logger = output.getLogger(); 47 | var pluginRoot = plugin.getPath(); 48 | var options = output.getOptions(); 49 | 50 | var outputRoot = options.get('root'); 51 | var assetOutputFolder = path.join(outputRoot, 'gitbook'); 52 | var prefix = options.get('prefix'); 53 | 54 | var assetFolder = path.join(pluginRoot, ASSET_FOLDER, prefix); 55 | 56 | if (!fs.existsSync(assetFolder)) { 57 | return Promise(); 58 | } 59 | 60 | logger.debug.ln('copy assets from theme', assetFolder); 61 | return fs.copyDir( 62 | assetFolder, 63 | assetOutputFolder, 64 | { 65 | deleteFirst: false, 66 | overwrite: true, 67 | // https://github.com/GitbookIO/gitbook-cli/issues/55 68 | // fix for ENOENT: no such file or directory issue 69 | confirm: false 70 | } 71 | ); 72 | } 73 | 74 | /** 75 | Copy resources from a plugin 76 | 77 | @param {Plugin} 78 | @return {Promise} 79 | */ 80 | function copyResources(output, plugin) { 81 | var logger = output.getLogger(); 82 | 83 | var options = output.getOptions(); 84 | var outputRoot = options.get('root'); 85 | 86 | var state = output.getState(); 87 | var resources = state.getResources(); 88 | 89 | var pluginRoot = plugin.getPath(); 90 | var pluginResources = resources.get(plugin.getName()); 91 | 92 | var assetsFolder = pluginResources.get('assets'); 93 | var assetOutputFolder = path.join(outputRoot, 'gitbook', plugin.getNpmID()); 94 | 95 | if (!assetsFolder) { 96 | return Promise(); 97 | } 98 | 99 | // Resolve assets folder 100 | assetsFolder = path.resolve(pluginRoot, assetsFolder); 101 | if (!fs.existsSync(assetsFolder)) { 102 | logger.warn.ln('assets folder for plugin "' + plugin.getName() + '" doesn\'t exist'); 103 | return Promise(); 104 | } 105 | 106 | logger.debug.ln('copy resources from plugin', assetsFolder); 107 | 108 | return fs.copyDir( 109 | assetsFolder, 110 | assetOutputFolder, 111 | { 112 | deleteFirst: false, 113 | overwrite: true, 114 | // https://github.com/GitbookIO/gitbook-cli/issues/55 115 | // fix for ENOENT: no such file or directory issue 116 | confirm: false 117 | } 118 | ); 119 | } 120 | 121 | module.exports = copyPluginAssets; 122 | -------------------------------------------------------------------------------- /gitlab-runners/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | # credit: https://gitlab.com/TyIsI/gitlab-runner-docker-compose/-/tree/main/ 2 | version: '3.7' 3 | 4 | services: 5 | dind: 6 | image: docker:20-dind 7 | container_name: "dind" 8 | hostname: dind 9 | privileged: true 10 | restart: unless-stopped 11 | volumes: 12 | - docker-dind:/var/lib/docker 13 | - certs:/certs/client 14 | command: 15 | - --tlsverify=false 16 | networks: 17 | - public 18 | environment: 19 | DOCKER_TLS_CERTDIR: "/certs" 20 | logging: 21 | driver: "json-file" 22 | options: 23 | max-size: "1m" 24 | 25 | runner: 26 | image: gitlab/gitlab-runner:alpine3.15-v15.8.1 27 | container_name: "runner" 28 | hostname: runner 29 | restart: unless-stopped 30 | volumes: 31 | - ./config:/etc/gitlab-runner:z 32 | - ./data/runner/cache:/cache 33 | - certs:/certs/client 34 | environment: 35 | DOCKER_HOST: "tcp://dind:2376" 36 | DOCKER_TLS_CERTDIR: "/certs/client" 37 | DOCKER_TLS_VERIFY: "1" 38 | DOCKER_MACHINE_NAME: "dind" 39 | DOCKER_CERT_PATH: "/certs/client" 40 | networks: 41 | - public 42 | logging: 43 | driver: "json-file" 44 | options: 45 | max-size: "1m" 46 | 47 | runner-registration: 48 | image: gitlab/gitlab-runner:alpine3.15-v15.8.1 49 | container_name: "runner-registration" 50 | hostname: runner-registration 51 | restart: "no" 52 | depends_on: 53 | - dind 54 | environment: 55 | CI_SERVER_URL: ${CI_SERVER_URL} 56 | REGISTRATION_TOKEN: ${REGISTRATION_TOKEN} 57 | command: 58 | - register 59 | - --non-interactive 60 | - --locked=false 61 | - --name=${RUNNER_NAME} 62 | - --executor=docker 63 | - --docker-image=docker:20-dind 64 | - --docker-volumes=/var/run/docker.sock:/var/run/docker.sock 65 | volumes: 66 | - ./config:/etc/gitlab-runner:z 67 | - ./data/dind/docker:/var/lib/docker 68 | networks: 69 | - public 70 | logging: 71 | driver: "json-file" 72 | options: 73 | max-size: "1m" 74 | 75 | volumes: 76 | docker-dind: {} 77 | certs: {} 78 | 79 | networks: 80 | public: 81 | name: public 82 | -------------------------------------------------------------------------------- /golang-basic-api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.17 as builder 2 | 3 | WORKDIR /app 4 | COPY . . 5 | RUN CGO_ENABLED=0 GOOS=linux go build -o myapp . 6 | 7 | FROM gcr.io/distroless/base-debian10 8 | 9 | COPY --from=builder /app/myapp /myapp 10 | 11 | ENV API_VERSION=v3 12 | 13 | CMD ["/myapp"] 14 | -------------------------------------------------------------------------------- /golang-basic-api/README.md: -------------------------------------------------------------------------------- 1 | # basic-api 2 | 3 | Basic web application for testing 4 | 5 | ## Usage 6 | 7 | Using environment variables to control the output: 8 | 9 | ```bash 10 | docker run -it -p 8080:8080 -e API_VERSION=v2 ruanbekker/basic-api:latest 11 | ``` 12 | 13 | Using tags for the version: 14 | 15 | ```bash 16 | docker run -it -p 8080:8080 ruanbekker/basic-api:v1 17 | ``` 18 | 19 | Available tags: 20 | 21 | - `ruanbekker/basic-api:v1` 22 | - `ruanbekker/basic-api:v2` 23 | - `ruanbekker/basic-api:v3` 24 | -------------------------------------------------------------------------------- /golang-basic-api/go.mod: -------------------------------------------------------------------------------- 1 | module myapp 2 | 3 | go 1.17 4 | -------------------------------------------------------------------------------- /golang-basic-api/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | "os" 8 | ) 9 | 10 | // VersionResponse represents the JSON structure for our response. 11 | type VersionResponse struct { 12 | Version string `json:"version"` 13 | } 14 | 15 | func main() { 16 | // Set the log output to standard output (default is standard error) 17 | log.SetOutput(os.Stdout) 18 | 19 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 20 | log.Printf("Received request from %s", r.RemoteAddr) 21 | if r.Method != http.MethodGet { 22 | http.Error(w, "Only GET method is supported", http.StatusMethodNotAllowed) 23 | log.Printf("Method not allowed from %s", r.RemoteAddr) 24 | return 25 | } 26 | 27 | version := os.Getenv("API_VERSION") 28 | if version == "" { 29 | version = "v0" // Default value if not set 30 | } 31 | 32 | resp := VersionResponse{ 33 | Version: version, 34 | } 35 | w.Header().Set("Content-Type", "application/json") 36 | json.NewEncoder(w).Encode(resp) 37 | 38 | log.Printf("Responded to %s with version: %s", r.RemoteAddr, version) 39 | }) 40 | 41 | log.Printf("Starting server on :8080") 42 | log.Fatal(http.ListenAndServe(":8080", nil)) 43 | } 44 | -------------------------------------------------------------------------------- /golang-basic-rest-api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine as builder 2 | ENV GOBIN ${GOPATH}/bin 3 | RUN apk add git 4 | COPY app.go /go/app.go 5 | WORKDIR /go 6 | RUN go get && go build -tags=netgo -o /go/app 7 | 8 | FROM scratch 9 | COPY --from=builder /go/app /app 10 | CMD ["/app"] 11 | -------------------------------------------------------------------------------- /golang-basic-rest-api/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | "github.com/gorilla/mux" 9 | "github.com/rs/xid" 10 | ) 11 | 12 | type Beer struct { 13 | ID string `json:"id,omitempty"` 14 | Name string `json:"name,omitempty"` 15 | Category string `json:"category,omitempty"` 16 | Brewer string `json:"brewer,omitempty"` 17 | Country `json:"country,omitempty"` 18 | } 19 | 20 | type Location struct { 21 | Country string `json:"country,omitempty"` 22 | City string `json:"city,omitempty"` 23 | } 24 | 25 | var beer []Beer 26 | 27 | func CreateBeerEndpoint(w http.ResponseWriter, r *http.Request) { 28 | var beer Beer 29 | _ = json.NewDecoder(r.Body).Decode(&beer) 30 | beer = append(beer, beer) 31 | json.NewEncoder(w).Encode(beer) 32 | } 33 | 34 | func GetBeerEndpoint(w http.ResponseWriter, r *http.Request) { 35 | json.NewEncoder(w).Encode(beer) 36 | } 37 | 38 | func GetBeerEndpoint(w http.ResponseWriter, r *http.Request) { 39 | params := mux.Vars(r) 40 | for _, p := range beer { 41 | if p.ID == params["id"] { 42 | json.NewEncoder(w).Encode(p) 43 | return 44 | } 45 | } 46 | json.NewEncoder(w).Encode("Beer Not Found") 47 | } 48 | 49 | func UpdateBeerEndpoint(w http.ResponseWriter, r *http.Request) { 50 | var beer Beer 51 | _ = json.NewDecoder(r.Body).Decode(&beer) 52 | params := mux.Vars(r) 53 | for i, p := range beer { 54 | if p.ID == params["id"] { 55 | beer[i] = beer 56 | json.NewEncoder(w).Encode(beer) 57 | break 58 | } 59 | } 60 | } 61 | 62 | func DeleteBeerEndpoint(w http.ResponseWriter, r *http.Request) { 63 | params := mux.Vars(r) 64 | for i, p := range beer { 65 | if p.ID == params["id"] { 66 | copy(beer[i:], beer[i+1:]) 67 | beer = beer[:len(beer)-1] 68 | break 69 | } 70 | } 71 | json.NewEncoder(w).Encode(beer) 72 | } 73 | 74 | func main() { 75 | 76 | router := mux.NewRouter() 77 | beer = append(beer, Beer{ID: xid.New().String(), Name: "CBC Pale Ale", Category: "IPA", Brewer: "CBC", Location: Location{Country: "South Africa", City: "Paarl"}}) 78 | beer = append(beer, Beer{ID: xid.New().String(), Name: "Heineken", Category: "Lager", Brewer: "Heineken", Location: Location{Country: "Netherlands", City: "Amsterdam"}}) 79 | beer = append(beer, Beer{ID: xid.New().String(), Name: "Jack Black Butchers Block", Category: "IPA", Brewer: "Devils Peak", Location: Location{Country: "South Africa", City: "Woodstock"}}) 80 | beer = append(beer, Beer{ID: xid.New().String(), Name: "CBC Amber Weiss", Category: "Weiss", Brewer: "CBC", Location: Location{Country: "South Africa", City: "Paarl"}}) 81 | 82 | router.HandleFunc("/beer", GetBeerEndpoint).Methods("GET") 83 | router.HandleFunc("/beer/{id}", GetBeerEndpoint).Methods("GET") 84 | router.HandleFunc("/beer", CreateBeerEndpoint).Methods("POST") 85 | router.HandleFunc("/beer/{id}", DeleteBeerEndpoint).Methods("DELETE") 86 | router.HandleFunc("/beer/{id}", UpdateBeerEndpoint).Methods("PUT") 87 | fmt.Println("Starting Server on Port 8000") 88 | log.Fatal(http.ListenAndServe(":8000", router)) 89 | 90 | } 91 | -------------------------------------------------------------------------------- /golang-build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV GO_VERSION 1.15.2 3 | RUN apk add --no-cache ca-certificates gcc musl-dev git && echo 'hosts: files dns' > /etc/nsswitch.conf 4 | RUN apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go 5 | ENV GOROOT_BOOTSTRAP="$(go env GOROOT)" 6 | #ENV GOOS="$(go env GOOS)" 7 | #ENV GOARCH="$(go env GOARCH)" 8 | #ENV GOHOSTOS="$(go env GOHOSTOS)" 9 | #ENV GOHOSTARCH="$(go env GOHOSTARCH)" 10 | RUN wget -O go.tgz "https://golang.org/dl/go$GO_VERSION.src.tar.gz" && \ 11 | tar -C /usr/local -xzf go.tgz && \ 12 | rm go.tgz && \ 13 | cd /usr/local/go/src && \ 14 | ./make.bash && \ 15 | rm -rf /usr/local/go/pkg/bootstrap /usr/local/go/pkg/obj && \ 16 | apk del .build-deps 17 | 18 | ENV PATH="/usr/local/go/bin:$PATH" 19 | ENV GOPATH=/go 20 | ENV export PATH=$GOPATH/bin:/usr/local/go/bin:$PATH 21 | RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" 22 | WORKDIR $GOPATH 23 | 24 | CMD ["/bin/sh"] 25 | -------------------------------------------------------------------------------- /golang-echo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | 3 | WORKDIR $GOPATH/src/echo/ 4 | COPY go.mod . 5 | COPY main.go . 6 | RUN go build -o /go/app 7 | 8 | FROM scratch 9 | 10 | COPY --from=builder /go/app /go/app 11 | 12 | CMD ["/go/app"] 13 | -------------------------------------------------------------------------------- /golang-echo/README.md: -------------------------------------------------------------------------------- 1 | # echo container 2 | 3 | Container for demonstrations, nothing fancy 4 | 5 | ## Build 6 | 7 | Multi-arch build: 8 | 9 | ```bash 10 | $ docker buildx build --platform "linux/amd64,linux/arm64" -f Dockerfile -t ruanbekker/containers:echo --push . 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```bash 16 | $ docker run -it ruanbekker/containers:echo 17 | 2022-09-15T09:09:49Z : ping from 62be534d632a : iteration 1 18 | 2022-09-15T09:09:54Z : ping from 62be534d632a : iteration 2 19 | ``` 20 | -------------------------------------------------------------------------------- /golang-echo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ruanbekker/dockerfiles 2 | 3 | go 1.19 4 | -------------------------------------------------------------------------------- /golang-echo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | hostname, err := os.Hostname() 12 | if err != nil { 13 | fmt.Println(err) 14 | os.Exit(1) 15 | } 16 | i := 0 17 | 18 | for { 19 | t := time.Now() 20 | i++ 21 | fmt.Printf("%s : ping from %s : iteration %d\n", t.Format(time.RFC3339), hostname, i) 22 | //fmt.Println(t.Format(time.RFC3339) + ": echo :", i) 23 | time.Sleep(time.Second * 5) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /golang-logger/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.16-buster AS builder 2 | WORKDIR /app 3 | COPY go.* ./ 4 | RUN go mod download 5 | COPY *.go ./ 6 | RUN go build -o /tmp/app 7 | 8 | FROM gcr.io/distroless/base-debian10 9 | WORKDIR / 10 | COPY --from=builder /tmp/app /app 11 | ENTRYPOINT ["/app"] 12 | -------------------------------------------------------------------------------- /golang-logger/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ruanbekker/logger 2 | 3 | go 1.19 4 | 5 | require github.com/rs/zerolog v1.29.0 6 | 7 | require ( 8 | github.com/mattn/go-colorable v0.1.12 // indirect 9 | github.com/mattn/go-isatty v0.0.14 // indirect 10 | golang.org/x/sys v0.1.0 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /golang-logger/go.sum: -------------------------------------------------------------------------------- 1 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 2 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 3 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 4 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 5 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 6 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 7 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 8 | github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 9 | github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= 10 | github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= 11 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 12 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= 14 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 15 | -------------------------------------------------------------------------------- /golang-logger/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "time" 8 | 9 | "github.com/rs/zerolog" 10 | "github.com/rs/zerolog/log" 11 | ) 12 | 13 | var ( 14 | HelloCounter = 1 15 | logger zerolog.Logger 16 | ) 17 | 18 | func main() { 19 | servicename := "service-name" 20 | if sn := os.Getenv("SERVICE_NAME"); sn != "" { 21 | servicename = sn 22 | } 23 | 24 | hostname, err := os.Hostname() 25 | if err != nil { 26 | fmt.Println(err) 27 | os.Exit(1) 28 | } 29 | 30 | // Build a logger with default fields 31 | logger = log.With().Str("service", servicename).Str("node", hostname).Logger() 32 | 33 | // Counter 34 | number := 1 35 | 36 | for number <= 604800 { 37 | 38 | // call function 39 | Hello() 40 | 41 | // calling sleep method with 1 second 42 | time.Sleep(1 * time.Second) 43 | 44 | // increment counter 45 | number++ 46 | } 47 | } 48 | 49 | func Name() string { 50 | rand.Seed(time.Now().Unix()) 51 | names := []string{ 52 | "ruan", 53 | "stefan", 54 | "frank", 55 | "peter", 56 | "samantha", 57 | "susan", 58 | "jeffrey", 59 | "adam", 60 | "juan", 61 | "james", 62 | "michelle", 63 | } 64 | n := rand.Int() % len(names) 65 | return names[n] 66 | } 67 | 68 | func Country() string { 69 | rand.Seed(time.Now().Unix()) 70 | countries := []string{ 71 | "south africa", 72 | "mexico", 73 | "new zealand", 74 | "australia", 75 | "germany", 76 | "italy", 77 | "spain", 78 | "france", 79 | } 80 | c := rand.Int() % len(countries) 81 | return countries[c] 82 | } 83 | 84 | func Age() int { 85 | rand.Seed(time.Now().Unix()) 86 | ages := []int{ 87 | 24, 28, 29, 30, 34, 36, 38, 88 | } 89 | a := rand.Int() % len(ages) 90 | return ages[a] 91 | } 92 | 93 | func JobTitle() string { 94 | rand.Seed(time.Now().Unix()) 95 | jobtitles := []string{ 96 | "software engineer", 97 | "database administrator", 98 | "teacher", 99 | "mechanical engineer", 100 | "photographer", 101 | "designer", 102 | "paramedic", 103 | "auto mechanic", 104 | "writer", 105 | "plumber", 106 | "receptionist", 107 | "carpenter", 108 | "truck driver", 109 | "lawyer", 110 | } 111 | c := rand.Int() % len(jobtitles) 112 | return jobtitles[c] 113 | } 114 | 115 | func Message() string { 116 | rand.Seed(time.Now().Unix()) 117 | messages := []string{ 118 | "a exception occured on /api", 119 | "inserted entry into database successfully", 120 | "high latency detected on /api", 121 | "high cpu utilization on server", 122 | "lookup returned successfully to the client", 123 | "cache has been cleared", 124 | "database has been initialized", 125 | "unable to connect to database", 126 | } 127 | m := rand.Int() % len(messages) 128 | return messages[m] 129 | } 130 | 131 | func RandomString() int { 132 | rand.Seed(time.Now().UnixNano()) 133 | upper := 9000 134 | lower := 1000 135 | number := rand.Intn(upper) + lower 136 | return number 137 | } 138 | 139 | func Hello() { 140 | country := Country() 141 | name := Name() 142 | age := Age() 143 | message := Message() 144 | jobtitle := JobTitle() 145 | randomstring := fmt.Sprintf("%d-%d-%d-%d", RandomString(), RandomString(), RandomString(), RandomString()) 146 | // Log with service name 147 | logger.Info().Int("count", HelloCounter).Str("name", name).Str("country", country).Int("age", age).Str("jobtitle", jobtitle).Str("creditcard", randomstring).Msg(message) 148 | HelloCounter++ 149 | } 150 | -------------------------------------------------------------------------------- /golang/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV GO_VERSION 1.15.2 3 | RUN apk add --no-cache ca-certificates && echo 'hosts: files dns' > /etc/nsswitch.conf 4 | RUN apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go 5 | ENV GOROOT_BOOTSTRAP="$(go env GOROOT)" 6 | #ENV GOOS="$(go env GOOS)" 7 | #ENV GOARCH="$(go env GOARCH)" 8 | #ENV GOHOSTOS="$(go env GOHOSTOS)" 9 | #ENV GOHOSTARCH="$(go env GOHOSTARCH)" 10 | RUN wget -O go.tgz "https://golang.org/dl/go$GO_VERSION.src.tar.gz" && \ 11 | tar -C /usr/local -xzf go.tgz && \ 12 | rm go.tgz && \ 13 | cd /usr/local/go/src && \ 14 | ./make.bash && \ 15 | rm -rf /usr/local/go/pkg/bootstrap /usr/local/go/pkg/obj && \ 16 | apk del .build-deps 17 | 18 | ENV PATH="/usr/local/go/bin:$PATH" 19 | ENV GOPATH=/go 20 | ENV export PATH=$GOPATH/bin:/usr/local/go/bin:$PATH 21 | RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" 22 | WORKDIR $GOPATH 23 | 24 | CMD ["/bin/sh"] 25 | -------------------------------------------------------------------------------- /hackerslides/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | hackerslides: 5 | image: msoedov/hacker-slides 6 | environment: 7 | - USER=demo 8 | - PASSWORD=demo 9 | volumes: 10 | - hackerslides:/app/slides 11 | networks: 12 | - appnet 13 | deploy: 14 | mode: replicated 15 | replicas: 1 16 | labels: 17 | - "traefik.backend.loadbalancer.sticky=false" 18 | - "traefik.backend.loadbalancer.swarm=true" 19 | - "traefik.backend=hackerslides" 20 | - "traefik.docker.network=appnet" 21 | - "traefik.entrypoints=https" 22 | - "traefik.frontend.passHostHeader=true" 23 | - "traefik.frontend.rule=Host:presentations.domain.com" 24 | - "traefik.port=8080" 25 | 26 | networks: 27 | appnet: 28 | external: true 29 | 30 | volumes: 31 | hackerslides: 32 | external: true 33 | -------------------------------------------------------------------------------- /hostname-go-json/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | WORKDIR /go/src/hello 3 | RUN apk add --no-cache gcc libc-dev 4 | ADD go.* /go/src/hello/ 5 | ADD app.go . 6 | RUN go mod download 7 | RUN GOOS=linux GOARCH=amd64 go build -tags=netgo app.go 8 | 9 | FROM scratch 10 | COPY --from=builder /go/src/hello/app /app 11 | CMD ["/app"] 12 | -------------------------------------------------------------------------------- /hostname-go-json/README.md: -------------------------------------------------------------------------------- 1 | # ruanbekker/hostname:json 2 | 3 | Image: `ruanbekker/hostname:json` 4 | Port: `8080` 5 | -------------------------------------------------------------------------------- /hostname-go-json/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "net/http" 7 | 8 | log "github.com/sirupsen/logrus" 9 | ) 10 | 11 | func main() { 12 | log.SetFormatter(&log.JSONFormatter{}) 13 | log.Info("starting server") 14 | http.HandleFunc("/", hostnameHandler) 15 | http.ListenAndServe("0.0.0.0:8080", nil) 16 | } 17 | 18 | func hostnameHandler(w http.ResponseWriter, r *http.Request) { 19 | myhostname, _ := os.Hostname() 20 | log.SetFormatter(&log.JSONFormatter{}) 21 | log.WithFields(log.Fields{"hostname": myhostname}).Info("fetched your hostname for you") 22 | fmt.Fprintln(w, "Hostname:", myhostname) 23 | } 24 | -------------------------------------------------------------------------------- /hostname-go-json/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | go-hostname-json: 5 | container_name: go-hostname-json 6 | build: . 7 | ports: 8 | - 8080:8080 9 | -------------------------------------------------------------------------------- /hostname-go-json/go.mod: -------------------------------------------------------------------------------- 1 | module hellologs 2 | 3 | go 1.16 4 | 5 | require github.com/sirupsen/logrus v1.8.1 // indirect 6 | -------------------------------------------------------------------------------- /hostname-go-json/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 3 | github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= 4 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 5 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 6 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= 7 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 8 | -------------------------------------------------------------------------------- /hostname-go/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | WORKDIR /go/src/hello 3 | RUN apk add --no-cache gcc libc-dev 4 | ADD app.go /go/src/hello/app.go 5 | RUN GOOS=linux go build -tags=netgo app.go 6 | #RUN GOOS=linux GOARCH=arm64 go build -tags=netgo app.go 7 | 8 | FROM scratch 9 | COPY --from=builder /go/src/hello/app /app 10 | CMD ["/app"] 11 | -------------------------------------------------------------------------------- /hostname-go/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | func hostnameHandler(w http.ResponseWriter, r *http.Request) { 11 | myhostname, _ := os.Hostname() 12 | log.Println("logging request for hostnameHandler on /") 13 | fmt.Fprintln(w, "Hostname:", myhostname) 14 | } 15 | 16 | func healthHandler(w http.ResponseWriter, r *http.Request) { 17 | fmt.Fprintln(w, "ok") 18 | } 19 | 20 | func main() { 21 | const port string = "8080" 22 | log.Println("Server listening on port", port) 23 | http.HandleFunc("/", hostnameHandler) 24 | http.HandleFunc("/health", healthHandler) 25 | http.ListenAndServe(":" + port, nil) 26 | } 27 | -------------------------------------------------------------------------------- /hostname-go/busybox.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | WORKDIR /go/src/hello 3 | RUN apk add --no-cache gcc libc-dev 4 | ADD app.go /go/src/hello/app.go 5 | RUN GOOS=linux GOARCH=amd64 go build -tags=netgo app.go 6 | 7 | FROM busybox 8 | COPY --from=builder /go/src/hello/app /app 9 | CMD ["/app"] 10 | -------------------------------------------------------------------------------- /hostname-rpi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM arm32v7/golang:alpine AS builder 2 | ADD app.go /go/src/hello/app.go 3 | WORKDIR /go/src/hello 4 | RUN apk add --no-cache gcc libc-dev 5 | RUN GOOS=linux GOARCH=arm GOARM=5 go build -tags=netgo app.go 6 | 7 | FROM hypriot/rpi-alpine-scratch 8 | COPY --from=builder /go/src/hello/app /app 9 | CMD ["/app"] 10 | -------------------------------------------------------------------------------- /hostname-rpi/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "net/http" 7 | ) 8 | 9 | func hostnameHandler(w http.ResponseWriter, r *http.Request) { 10 | myhostname, _ := os.Hostname() 11 | fmt.Fprintln(w, "Hostname:", myhostname) 12 | } 13 | 14 | func main() { 15 | const port string = "8000" 16 | fmt.Println("Server listening on port", port) 17 | http.HandleFunc("/", hostnameHandler) 18 | http.ListenAndServe(":" + port, nil) 19 | } 20 | -------------------------------------------------------------------------------- /hugo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | LABEL description="Hugo Static Site Generator for Docker" 4 | LABEL maintainer="Ruan Bekker " 5 | 6 | ENV HUGO_VERSION=0.69.0 7 | ENV HUGO_HOME=/usr/local/hugo 8 | ENV PROJECT_PATH=/app 9 | ENV PATH=${PATH}:${HUGO_HOME}/bin 10 | 11 | ADD https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz /tmp 12 | RUN apk add --no-cache ca-certificates git \ 13 | && tar -xf /tmp/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz -C /tmp \ 14 | && mkdir -p ${PROJECT_PATH} \ 15 | && mkdir -p ${HUGO_HOME}/bin \ 16 | && mv /tmp/hugo ${HUGO_HOME}/bin/hugo \ 17 | && rm -rf /tmp/hugo_* \ 18 | && rm -rf /tmp/*.md 19 | -------------------------------------------------------------------------------- /hugo/Dockerfile.app: -------------------------------------------------------------------------------- 1 | FROM ruanbekker/hugo:v0.69 2 | 3 | LABEL description="Hugo Static Site Generator in Docker" 4 | LABEL maintainer="Ruan Bekker " 5 | 6 | ADD boot.sh /boot.sh 7 | CMD ["sh", "/boot.sh"] 8 | -------------------------------------------------------------------------------- /hugo/Makefile: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/mpneuried/0594963ad38e68917ef189b4e6a269db 2 | 3 | cnf ?= config.env 4 | include $(cnf) 5 | export $(shell sed 's/=.*//' $(cnf)) 6 | 7 | dpl ?= deploy.env 8 | include $(dpl) 9 | export $(shell sed 's/=.*//' $(dpl)) 10 | 11 | .PHONY: help 12 | 13 | help: ## This help. 14 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) 15 | 16 | .DEFAULT_GOAL := help 17 | 18 | build: ## Build the container 19 | docker build -t $(DOCKER_REPO_USER)/$(APP_NAME):v$(VERSION) . 20 | docker build -t $(DOCKER_REPO_USER)/$(APP_NAME):latest . 21 | 22 | run: ## Run container on port configured in `config.env` 23 | docker run -i -t --rm --env-file=./config.env -p=$(PORT):$(PORT) --name="$(APP_NAME)" $(APP_NAME) 24 | 25 | up: build run 26 | 27 | stop: ## Stop and remove a running container 28 | docker stop $(APP_NAME); docker rm $(APP_NAME) 29 | 30 | release: build-nc publish 31 | 32 | publish: repo-login publish-latest publish-version 33 | 34 | publish-latest: tag-latest ## Publish the `latest` taged container to ECR 35 | @echo 'publish latest to $(DOCKER_REPO)' 36 | docker push $(DOCKER_REPO_USER)/$(APP_NAME):latest 37 | 38 | publish-version: tag-version ## Publish the `{version}` taged container to ECR 39 | @echo 'publish $(VERSION) to $(DOCKER_REPO)' 40 | docker push $(DOCKER_REPO_USER)/$(APP_NAME):v$(VERSION) 41 | 42 | repo-login: ## Logs in to dockerhub 43 | @echo 'logging into dockerhub' 44 | docker login 45 | 46 | tag-latest: ## Generate container `{version}` tag 47 | @echo 'create tag latest' 48 | docker tag $(DOCKER_REPO_USER)/$(APP_NAME) $(DOCKER_REPO_USER)/$(APP_NAME):latest 49 | 50 | tag-version: ## Generate container `latest` tag 51 | @echo 'create tag $(VERSION)' 52 | docker tag $(DOCKER_REPO_USER)/$(APP_NAME) $(DOCKER_REPO_USER)/$(APP_NAME):v$(VERSION) 53 | 54 | version: ## Output the current version 55 | @echo $(VERSION) 56 | -------------------------------------------------------------------------------- /hugo/README.md: -------------------------------------------------------------------------------- 1 | External: 2 | - https://hub.docker.com/r/jojomi/hugo/ 3 | -------------------------------------------------------------------------------- /hugo/boot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | HUGO_HOME=${HUGO_HOME:-/usr/local/hugo} 3 | HUGO_THEME=${HUGO_THEME:-introduction} 4 | PROJECT_PATH=${PROJECT_PATH:-/app} 5 | PROJECT_URL=${PROJECT_URL:-https://0.0.0.0} 6 | 7 | cd /app 8 | rm -rf /app/* 9 | git clone ${GITHUB_URL} . 10 | 11 | hugo server \ 12 | --themesDir=${PROJECT_PATH}/themes \ 13 | --theme=${HUGO_THEME} \ 14 | --bind=0.0.0.0 \ 15 | --baseUrl=${PROJECT_URL}/ \ 16 | --port=8080 \ 17 | --appendPort=false \ 18 | --buildDrafts \ 19 | --environment production 20 | -------------------------------------------------------------------------------- /hugo/config.env: -------------------------------------------------------------------------------- 1 | PORT=1337 2 | DOCKER_REPO_USER=ruanbekker 3 | VERSION=0.61 4 | -------------------------------------------------------------------------------- /hugo/deploy.env: -------------------------------------------------------------------------------- 1 | APP_NAME=hugo 2 | DOCKER_REPO=ruanbekker/hugo 3 | -------------------------------------------------------------------------------- /jekyll/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:2.5-alpine 2 | 3 | RUN apk add --no-cache build-base gcc bash cmake git 4 | WORKDIR /site 5 | 6 | RUN bundle init && \ 7 | bundle install --path vendor/bundle && \ 8 | bundle add jekyll jekyll-paginate kramdown pygments.rb && \ 9 | bundle exec jekyll new --force --skip-bundle . && \ 10 | bundle install 11 | 12 | CMD [ "bundle", "exec", "jekyll", "serve", "--force_polling", "-H", "0.0.0.0", "-P", "4000" ] 13 | -------------------------------------------------------------------------------- /jekyll/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | jekyll: 5 | image: jekyll/jekyll:latest 6 | command: jekyll serve --watch --force_polling --verbose 7 | ports: 8 | - 4000:4000 9 | volumes: 10 | # eg. https://github.com/Bloc/portfolio-iro/ 11 | - .:/srv/jekyll 12 | -------------------------------------------------------------------------------- /jenkins-docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # jenkins with docker client 2 | 3 | FROM jenkins/jenkins:lts 4 | USER root 5 | ENV DOCKER_VERSION 19.03.5 6 | 7 | RUN mkdir -p /tmp/download && \ 8 | curl -L https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz | tar -xz -C /tmp/download && \ 9 | rm -rf /tmp/download/docker/dockerd && \ 10 | mv /tmp/download/docker/docker* /usr/local/bin/ && \ 11 | rm -rf /tmp/download && \ 12 | groupadd -g 999 docker && \ 13 | usermod -aG staff,docker jenkins 14 | 15 | USER jenkins 16 | -------------------------------------------------------------------------------- /jenkins/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | jenkins: 5 | image: jenkins/jenkins:lts 6 | container_name: jenkins 7 | user: root 8 | privileged: true 9 | ports: 10 | - 8080:8080 11 | - 50000:50000 12 | volumes: 13 | - ./jenkins_home:/var/jenkins_home 14 | - /var/run/docker.sock:/var/run/docker.sock 15 | restart: unless-stopped 16 | networks: 17 | - docknet 18 | 19 | networks: 20 | docknet: 21 | name: docknet 22 | -------------------------------------------------------------------------------- /keep-me-running/Dockerfile: -------------------------------------------------------------------------------- 1 | # image: ruanbekker/keep-me-running 2 | FROM alpine 3 | CMD ["tail", "-f", "/dev/null"] 4 | -------------------------------------------------------------------------------- /kinesis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.16.0-stretch-slim 2 | 3 | RUN apt update && apt install build-essential python-minimal -y 4 | RUN npm install --unsafe-perm -g kinesalite 5 | RUN apt-get clean 6 | 7 | CMD ["kinesalite", "--port", "4567", "--createStreaMs", "5"] 8 | -------------------------------------------------------------------------------- /kinesis/README.md: -------------------------------------------------------------------------------- 1 | # Kinesis Local 2 | 3 | Kinesis Local with Docker using [kinesisalite](https://github.com/mhart/kinesalite) 4 | 5 | ## Blog 6 | 7 | Blog available at [https://blog.ruanbekker.com/blog/2019/06/22/play-with-kinesis-data-streams-for-free/](https://blog.ruanbekker.com/blog/2019/06/22/play-with-kinesis-data-streams-for-free/?referral=github) 8 | -------------------------------------------------------------------------------- /kinesis/consumer.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | import time 4 | import os 5 | 6 | client = boto3.Session(region_name='eu-west-1').client('kinesis', aws_access_key_id='', aws_secret_access_key='', endpoint_url='http://localhost:4567') 7 | stream_details = client.describe_stream(StreamName='mystream') 8 | shard_id = stream_details['StreamDescription']['Shards'][0]['ShardId'] 9 | 10 | response = client.get_shard_iterator(StreamName='mystream', ShardId=shard_id, ShardIteratorType='TRIM_HORIZON') 11 | shard_iterator = response['ShardIterator'] 12 | 13 | print("Starting Consuming at {}".format(time.strftime("%H:%m:%S"))) 14 | 15 | while True: 16 | response = client.get_records(ShardIterator=shard_iterator, Limit=5) 17 | if len(response['Records']) == 0: 18 | print("Finshed Consuming at {}".format(time.strftime("%H:%m:%S"))) 19 | break 20 | shard_iterator = response['NextShardIterator'] 21 | for record in response['Records']: 22 | if 'Data' in record and len(record['Data']) > 0: 23 | print(json.loads(record['Data'])) 24 | time.sleep(0.75) 25 | -------------------------------------------------------------------------------- /kinesis/producer.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import random 3 | import json 4 | import time 5 | 6 | names = ['james', 'stefan', 'pete', 'tom', 'frank', 'peter', 'ruan'] 7 | 8 | client = boto3.Session(region_name='eu-west-1').client('kinesis', aws_access_key_id='', aws_secret_access_key='', endpoint_url='http://localhost:4567') 9 | 10 | list_streams = client.list_streams() 11 | 12 | if 'mystream' not in list_streams['StreamNames']: 13 | client.create_stream(StreamName='mystream', ShardCount=1) 14 | time.sleep(1) 15 | 16 | count = 0 17 | print("Starting at {}".format(time.strftime("%H:%m:%S"))) 18 | 19 | while count != 25: 20 | count += 1 21 | response = client.put_record(StreamName='mystream', Data=json.dumps({"number": count, "name": random.choice(names), "age": random.randint(20,50)}), PartitionKey='a01') 22 | time.sleep(1) 23 | 24 | print("Finished at {}".format(time.strftime("%H:%m:%S"))) 25 | -------------------------------------------------------------------------------- /kubectl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add curl bash git openssl ncurses \ 4 | && curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \ 5 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx \ 6 | && curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens \ 7 | && chmod +x ./kube* \ 8 | && mv ./kube* /usr/local/bin/ 9 | -------------------------------------------------------------------------------- /kubernetes-elasticsearch-cluster/Dockerfile.curator: -------------------------------------------------------------------------------- 1 | FROM quay.io/pires/docker-elasticsearch-curator:5.5.1 2 | -------------------------------------------------------------------------------- /kubernetes-elasticsearch-cluster/Dockerfile.elasticsearch: -------------------------------------------------------------------------------- 1 | FROM quay.io/pires/docker-elasticsearch-kubernetes:6.3.2 2 | -------------------------------------------------------------------------------- /ldap/README.md: -------------------------------------------------------------------------------- 1 | Create the network: 2 | 3 | ``` 4 | $ docker network create container-net 5 | ``` 6 | 7 | Create the ldap server: 8 | 9 | ``` 10 | $ docker run --name ldap-service --network container-net --hostname ldap-service --detach osixia/openldap:1.1.8 11 | ``` 12 | 13 | Create the ldap ui: 14 | 15 | ``` 16 | $ docker run --name phpldapadmin-service --network container-net --publish 6443:443 --hostname phpldapadmin-service --link ldap-service:ldap-host --env PHPLDAPADMIN_LDAP_HOSTS=ldap-host --detach osixia/phpldapadmin:0.7.2 17 | ``` 18 | 19 | ## Using a different ldap service 20 | 21 | If you are using a different ldap backend: 22 | 23 | ``` 24 | $ docker run -d --name ldap --network container-net -p 389:389 -e SLAPD_PASSWORD=password -e SLAPD_DOMAIN=ldap.localhost.net dinkel/openldap 25 | ``` 26 | 27 | Provision the frontend: 28 | 29 | ``` 30 | $ docker run --network container-net -p 6443:443 --env PHPLDAPADMIN_LDAP_HOSTS=ldap --detach osixia/phpldapadmin:0.7.2 31 | ``` 32 | 33 | Login with this cn: 34 | 35 | ``` 36 | cn=admin,dc=ldap,dc=localhost,dc=net 37 | ``` 38 | 39 | ![image](https://user-images.githubusercontent.com/567298/55215659-33dcd200-5203-11e9-8a03-28fd260326fd.png) 40 | 41 | 42 | References: 43 | 44 | - https://github.com/osixia/docker-phpLDAPadmin 45 | - https://github.com/osixia/docker-openldap 46 | - https://github.com/dinkel/docker-openldap 47 | - https://github.com/admiralobvious/flask-simpleldap 48 | - https://github.com/openfrontier/docker-ldap-ssp 49 | - https://github.com/openfrontier/openldap-docker 50 | -------------------------------------------------------------------------------- /load-generator/cpu/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | RUN apk add autoconf automake g++ make --no-cache 3 | RUN pip install py-bcrypt 4 | ADD app.py /app.py 5 | CMD ["python", "app.py"] 6 | -------------------------------------------------------------------------------- /load-generator/cpu/README.md: -------------------------------------------------------------------------------- 1 | Docker Image: 2 | 3 | - ruanbekker/load-generator:cpu 4 | 5 | Usage: 6 | 7 | ``` 8 | $ docker run -it -e DELAY_TIME=1 ruanbekker/load-generator:cpu 9 | ``` 10 | -------------------------------------------------------------------------------- /load-generator/cpu/app.py: -------------------------------------------------------------------------------- 1 | import bcrypt 2 | import time 3 | import os 4 | import logging 5 | from random import choice, randint 6 | from string import ascii_letters, punctuation, digits 7 | 8 | logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO) 9 | 10 | delay_time = os.environ.get('DELAY_TIME', '0') 11 | 12 | def generate_hash(log_rounds): 13 | string_format = ascii_letters + punctuation + digits 14 | generated_string = "".join(choice(string_format) for x in range(randint(5, 20))) 15 | bcrypt_hash = bcrypt.hashpw(generated_string, bcrypt.gensalt(log_rounds)) 16 | return bcrypt_hash 17 | 18 | count = 0 19 | log_rounds = choice([12,14,15]) 20 | while True: 21 | try: 22 | if count != 20: 23 | count = count+1 24 | gen_hash = generate_hash(log_rounds) 25 | logging.info("Your hash with {0} log rounds: {1}".format(log_rounds, gen_hash)) 26 | else: 27 | logging.info("resetting") 28 | time.sleep(int(delay_time)) 29 | count = 0 30 | log_rounds = choice([12,14,15]) 31 | except: 32 | logging.error("something went wrong") 33 | time.sleep(10) 34 | -------------------------------------------------------------------------------- /logstash/Dockerfile: -------------------------------------------------------------------------------- 1 | ENV VERSION 2 | # https://github.com/elastic/logstash-docker 3 | FROM docker.elastic.co/logstash/logstash-oss:${VERSION:-6.3.1} 4 | RUN logstash-plugin install logstash-filter-json 5 | ADD logstash.conf /usr/share/logstash/pipeline/logstash.conf 6 | CMD ["logstash", "-f", "/usr/share/logstash/pipeline/logstash.conf"] 7 | -------------------------------------------------------------------------------- /logstash/Dockerfile.2: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV VERSION 6.7.1 3 | ENV BASE_URL https://artifacts.elastic.co/downloads/logstash 4 | ENV TARBALL "${BASE_URL}/logstash-${VERSION}.tar.gz" 5 | 6 | RUN apk add --no-cache openjdk8-jre bash 7 | 8 | RUN set -ex && \ 9 | cd /tmp && wget -O logstash.tar.gz "$TARBALL" && \ 10 | tar -xzf logstash.tar.gz && \ 11 | mv logstash-$VERSION /usr/share/logstash && \ 12 | rm -rf /tmp/* 13 | 14 | ENV PATH /usr/share/logstash/bin:/sbin:$PATH 15 | ENV LS_SETTINGS_DIR /usr/share/logstash/config 16 | ENV LANG='en_US.UTF-8' LC_ALL='en_US.UTF-8' 17 | -------------------------------------------------------------------------------- /logstash/config/logstash.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ## https://github.com/elastic/logstash-docker/blob/master/build/logstash/config/logstash-oss.yml 3 | http.host: "0.0.0.0" 4 | path.config: /usr/share/logstash/pipeline 5 | -------------------------------------------------------------------------------- /logstash/pipeline/logstash.conf: -------------------------------------------------------------------------------- 1 | input { 2 | tcp { 3 | port => 5000 4 | } 5 | } 6 | 7 | ## filters / logstash plugins 8 | 9 | output { 10 | elasticsearch { 11 | hosts => "elasticsearch:9200" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /metricbeat-mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | # Documentation: 2 | # https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-module-mysql.html 3 | FROM docker.elastic.co/beats/metricbeat:6.3.1 4 | 5 | ENV ES_HOST elasticsearch 6 | ENV ES_PORT 9200 7 | ENV ES_PROT "http" 8 | ENV ES_USER elastic 9 | ENV ES_PASS changeme 10 | ENV ES_INDEX "metricbeat-%{+yyyy.MM.dd}" 11 | ENV METRIC_PERIOD 1s 12 | ENV MYSQL_DSN "root:pass@tcp(mysql:3306)/" 13 | ENV LOGGING_LEVEL "warning" 14 | 15 | USER root 16 | COPY metricbeat.yml /usr/share/metricbeat/metricbeat.yml 17 | # RUN chown metricbeat /usr/share/metricbeat/metricbeat.yml 18 | # USER metricbeat 19 | RUN chmod go-w /usr/share/metricbeat/metricbeat.yml 20 | RUN metricbeat test config -c /usr/share/metricbeat/metricbeat.yml 21 | 22 | ENTRYPOINT ["metricbeat"] 23 | -------------------------------------------------------------------------------- /metricbeat-mysql/metricbeat.yml: -------------------------------------------------------------------------------- 1 | ########################## Metricbeat Configuration ########################### 2 | 3 | #========================== Modules configuration ============================ 4 | metricbeat.modules: 5 | 6 | #------------------------------- Mysql Module ------------------------------- 7 | - module: mysql 8 | metricsets: ["status"] 9 | enabled: true 10 | period: ${METRIC_PERIOD} 11 | 12 | # Host DSN should be defined as "user:pass@tcp(127.0.0.1:3306)/" 13 | # The username and password can either be set in the DSN or using the username 14 | # and password config options. Those specified in the DSN take precedence. 15 | hosts: ["${MYSQL_DSN}"] 16 | 17 | #================================ Processors =================================== 18 | 19 | #processors: 20 | #- include_fields: 21 | # fields: ["cpu"] 22 | #- drop_fields: 23 | # fields: ["cpu.user", "cpu.system"] 24 | # 25 | # The following example drops the events that have the HTTP response code 200: 26 | # 27 | #processors: 28 | #- drop_event: 29 | # when: 30 | # equals: 31 | # http.code: 200 32 | # 33 | processors: 34 | - add_cloud_metadata: ~ 35 | #processors: 36 | #- add_locale: 37 | # format: offset 38 | # 39 | # PS: `add_docker_metadata` is version 6 onwards (to consider adding, when its up) 40 | # 41 | # processors: 42 | # - add_docker_metadata: 43 | # host: "unix:///hostfs/var/run/docker.sock" 44 | # match_source: true 45 | # match_source_index: 4 46 | # match_fields: ["system.process.cgroup.id"] 47 | 48 | #================================ Outputs ====================================== 49 | 50 | # Configure what outputs to use when sending the data collected by the beat. 51 | # Multiple outputs may be used. 52 | 53 | #-------------------------- Elasticsearch output ------------------------------- 54 | output.elasticsearch: 55 | enabled: true 56 | hosts: ["${ES_HOST}:${ES_PORT}"] 57 | #compression_level: 0 58 | protocol: "${ES_PROT}" 59 | username: "${ES_USER}" 60 | password: "${ES_PASS}" 61 | 62 | # Dictionary of HTTP parameters to pass within the url with index operations. 63 | #parameters: 64 | #param1: value1 65 | #param2: value2 66 | 67 | #worker: 1 68 | index: "${ES_INDEX}" 69 | #pipeline: "" 70 | #headers: 71 | # X-My-Header: Contents of the header 72 | #bulk_max_size: 50 73 | #flush_interval: 1s 74 | 75 | setup.template.name: "metricbeat" 76 | setup.template.pattern: "metricbeat-*" 77 | 78 | #----------------------------- Console output --------------------------------- 79 | #output.console: 80 | #enabled: true 81 | #pretty: false 82 | 83 | #================================ Logging ====================================== 84 | 85 | 86 | -------------------------------------------------------------------------------- /minica/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS build 2 | RUN apk add --no-cache git 3 | RUN go get github.com/jsha/minica 4 | 5 | FROM alpine 6 | COPY --from=build /go/bin/minica /usr/bin/minica 7 | RUN mkdir /output 8 | WORKDIR /output 9 | ENTRYPOINT ["minica"] 10 | -------------------------------------------------------------------------------- /minica/README.md: -------------------------------------------------------------------------------- 1 | # minica 2 | 3 | 4 | ## About 5 | 6 | Project Info: 7 | - [jsha/minica](https://github.com/jsha/minica) 8 | 9 | ## Usage 10 | 11 | Run: 12 | 13 | ``` 14 | $ docker run --user "$(id -u):$(id -g)" -it -v $PWD/certs:/output ruanbekker/minica --domains 192.168.0.20.nip.io 15 | ``` 16 | 17 | View: 18 | 19 | ``` 20 | $ find ./certs -type f 21 | ./certs/minica-key.pem 22 | ./certs/192.168.0.20.nip.io/key.pem 23 | ./certs/192.168.0.20.nip.io/cert.pem 24 | ./certs/minica.pem 25 | ``` 26 | 27 | ## Cert Installation 28 | 29 | Follow [this guide](https://gist.github.com/mwidmann/115c2a7059dcce300b61f625d887e5dc) for cert installation 30 | -------------------------------------------------------------------------------- /mongodb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | MAINTAINER Ruan Bekker 3 | 4 | RUN apk add --no-cache mongodb mongodb-tools && mkdir -p /data/db 5 | EXPOSE 27017 6 | ENTRYPOINT ["mongod"] 7 | CMD ["mongod", "--syslog", "--nojournal", "--storageEngine", "wiredTiger", "--smallfiles", "--dbpath", "/data/db", "--bind_ip_all", "--port", "27017"] 8 | -------------------------------------------------------------------------------- /mongodb/Dockerfile.python: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | MAINTAINER Ruan Bekker 3 | 4 | RUN apk add --no-cache mongodb mongodb-tools && apk add --no-cache wget python py2-pip && pip install pymongo mongoengine && mkdir -p /data/db 5 | EXPOSE 27017 6 | ENTRYPOINT ["mongod"] 7 | CMD ["mongod", "--syslog", "--nojournal", "--storageEngine", "wiredTiger", "--smallfiles", "--dbpath", "/data/db", "--bind_ip_all", "--port", "27017"] 8 | -------------------------------------------------------------------------------- /mongodb/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | services: 3 | mongo: 4 | image: mongo 5 | command: --smallfiles 6 | restart: always 7 | environment: 8 | MONGO_INITDB_ROOT_USERNAME: root 9 | MONGO_INITDB_ROOT_PASSWORD: example 10 | 11 | mongo-express: 12 | image: mongo-express 13 | restart: always 14 | ports: 15 | - 8081:8081 16 | environment: 17 | ME_CONFIG_MONGODB_ADMINUSERNAME: root 18 | ME_CONFIG_MONGODB_ADMINPASSWORD: example 19 | -------------------------------------------------------------------------------- /motd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | MAINTAINER Ruan Bekker 3 | 4 | WORKDIR /motd 5 | ADD . . 6 | 7 | RUN apk --no-cache add bash && chmod +x boot.sh 8 | 9 | CMD ["/motd/boot.sh"] 10 | -------------------------------------------------------------------------------- /motd/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | $ docker run -it ruanbekker/motd 3 | 4 | Message of the Day: 5 | 'The average dog is a nicer person than the average person.' - Andy Rooney 6 | 7 | ``` 8 | -------------------------------------------------------------------------------- /motd/boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./content 4 | 5 | size=${#array[@]} 6 | echo "" 7 | echo "Message of the Day:" 8 | echo "${array[$(($RANDOM % $size))]}" 9 | echo "" 10 | -------------------------------------------------------------------------------- /motd/content: -------------------------------------------------------------------------------- 1 | # source: 2 | # https://www.keepinspiring.me/funny-quotes/ 3 | 4 | array[0]="'People say nothing is impossible, but I do nothing every day.' - A. A. Milne" 5 | array[1]="'The only mystery in life is why the kamikaze pilots wore helmets.' - Al McGuire" 6 | array[2]="'The average dog is a nicer person than the average person.' - Andy Rooney" 7 | array[3]="'We never really grow up, we only learn how to act in public.' - Bryan White" 8 | array[4]="'My favorite machine at the gym is the vending machine.' - Caroline Rhea" 9 | -------------------------------------------------------------------------------- /mtail/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | EXPOSE 9101 4 | 5 | ENV GOPATH /go 6 | ENV PATH /go/bin:$PATH 7 | 8 | RUN apk add --update musl go git bash make && \ 9 | mkdir /mtail && \ 10 | go get github.com/google/mtail/cmd/mtail && \ 11 | apk del --purge musl go git 12 | 13 | COPY nginx.mtail /opt/mtail/progs/nginx.mtail 14 | 15 | ENTRYPOINT ["/go/bin/mtail", "--address", "0.0.0.0", "--port", "9101", "--emit_prog_label=false", "--alsologtostderr", "--progs", "/opt/mtail/progs", "--logs"] 16 | -------------------------------------------------------------------------------- /mtail/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | $ docker run -itd --name nginx-log-exporter \ 3 | -p 9101:9101 \ 4 | -v /var/log/nginx:/var/log/nginx \ 5 | ruanbekker/mtail:nginx /var/log/nginx/access_prometheus.log 6 | ``` 7 | -------------------------------------------------------------------------------- /mtail/example_nginx.conf: -------------------------------------------------------------------------------- 1 | http { 2 | ... 3 | geoip_country /etc/nginx/geoip/GeoIP.dat; 4 | geoip_city /etc/nginx/geoip/GeoLiteCity.dat; 5 | 6 | log_format prometheus_log '$msec $host $request_method $uri ' 7 | '$status $request_length $bytes_sent ' 8 | '$body_bytes_sent $request_time $upstream_connect_time ' 9 | '$upstream_header_time $upstream_response_time "$http_referer" ' 10 | '"$http_user_agent" "$geoip_city_continent_code" "$geoip_city_country_name" "$geoip_city" "$http_x_forwarded_for"'; 11 | 12 | access_log /var/log/nginx/access.log; 13 | access_log /var/log/nginx/access_prometheus.log prometheus_log buffer=1k; 14 | open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; 15 | ... 16 | } 17 | -------------------------------------------------------------------------------- /mtail/nginx.mtail: -------------------------------------------------------------------------------- 1 | counter request_count by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_request_count" 2 | counter request_length_bytes by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_request_length_bytes" 3 | counter bytes_sent by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_bytes_sent" 4 | counter body_bytes_sent by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_body_bytes_sent" 5 | counter request_time by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_request_time" 6 | counter upstream_connect_time by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_upstream_connect_time" 7 | counter upstream_header_time by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_upstream_header_time" 8 | counter upstream_response_time by nginx_host, nginx_method, nginx_uri, nginx_status, nginx_referer, nginx_user_agent, nginx_continent_name, nginx_country_name, nginx_city_name, nginx_client_ip as "nginx_upstream_response_time" 9 | counter nginx_log_nomatch_count 10 | 11 | /^/ + 12 | /(?P\d+)\.\d+ / + # settime() needs just the seconds so we exclude the .milliseconds part 13 | /(?P\S+) / + 14 | /(?P\S+) / + 15 | /(?P\S+) / + 16 | /(?P\S+) / + 17 | /(?P\d+) / + 18 | /(?P\d+) / + 19 | /(?P\d+) / + 20 | /(?P\d+\.\d+) / + 21 | /(?P\S+) / + 22 | /(?P\S+) / + 23 | /(?P\S+) / + 24 | /"(?P\S+)" / + 25 | /"(?P(.*?))" / + 26 | /"(?P\S+)" / + 27 | /"(?P(.*?))" / + 28 | /"(?P(.*?))" / + 29 | /"(?P(.*?))"/ + 30 | /$/ { 31 | settime($msec) 32 | request_count[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for]++ 33 | request_length_bytes[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += $request_length 34 | bytes_sent[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += $bytes_sent 35 | body_bytes_sent[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += $body_bytes_sent 36 | request_time[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += $request_time 37 | 38 | $upstream_connect_time != "-" { 39 | upstream_connect_time[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += float($upstream_connect_time) 40 | } 41 | $upstream_header_time != "-" { 42 | upstream_header_time[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += float($upstream_header_time) 43 | } 44 | $upstream_response_time != "-" { 45 | upstream_response_time[$host][$request_method][$uri][$status][$http_referer][$http_user_agent][$geoip_city_continent_code][$geoip_city_country_name][$geoip_city][$http_x_forwarded_for] += float($upstream_response_time) 46 | } 47 | } else { 48 | nginx_log_nomatch_count++ 49 | } 50 | -------------------------------------------------------------------------------- /mtail/setup_geoip_nginx.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt install geoip-bin geoip-database-extra libgeoip1 libnginx-mod-http-geoip geoip-database-extra libgeoip1 libnginx-mod-http-geoip nginx-module-geoip -y 3 | find / -name ngx_http_geoip_module.so 4 | mkdir /etc/nginx/geoip 5 | cd /etc/nginx/geoip 6 | wget https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoIP.dat.gz 7 | wget https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.xz 8 | gunzip GeoIP.dat.gz 9 | unxz GeoLiteCity.dat.xz 10 | ``` 11 | -------------------------------------------------------------------------------- /mysql-client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add mysql-client 3 | ENTRYPOINT ["mysql"] 4 | -------------------------------------------------------------------------------- /mysql-client/README.md: -------------------------------------------------------------------------------- 1 | ### About 2 | 3 | MySQL Client on Docker 4 | 5 | ### MySQL Client as a Docker Container 6 | 7 | Helper function: 8 | 9 | ``` 10 | mysql(){ 11 | docker run -it ruanbekker/mysql-client "$@" 12 | } 13 | ``` 14 | 15 | ## Usage 16 | 17 | ``` 18 | $ source ~/.functions 19 | $ mysql -h example.com -u user -p dbname 20 | mysql> 21 | ``` 22 | -------------------------------------------------------------------------------- /mysql-cluster/README.md: -------------------------------------------------------------------------------- 1 | # mysql-cluster 2 | 3 | Resource: 4 | - https://github.com/toughIQ/docker-mariadb-cluster 5 | 6 | ## What does it do 7 | 8 | 1. MariaDB Cluster 9 | 2. DB Loadbalancer 10 | 3. MySQL Client that makes backups 11 | 12 | ## Demo 13 | 14 | ### Deploy 15 | 16 | ``` 17 | $ docker stack deploy -c docker-compose.yml galera 18 | Creating network dbnet 19 | Creating service galera_dbcluster 20 | Creating service galera_dblb 21 | Creating service galera_dbclient 22 | ``` 23 | 24 | Verify: 25 | 26 | ``` 27 | docker service ls 28 | ID NAME MODE REPLICAS IMAGE PORTS 29 | jm7p70qre72u galera_dbclient replicated 1/1 alpine:latest 30 | p8kcr5y7szte galera_dbcluster replicated 1/1 toughiq/mariadb-cluster:latest 31 | 1hu3oxhujgfm galera_dblb replicated 1/1 toughiq/maxscale:latest *:3306->3306/tcp 32 | ``` 33 | 34 | ### Backup Client 35 | 36 | 37 | ``` 38 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) find /data/ 39 | /data/ 40 | /data/2019-05-10 41 | /data/2019-05-10/db_backup-2019-05-10T10.05.sql.gz 42 | ``` 43 | 44 | ### Populate Data: 45 | 46 | ``` 47 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) mysql -uroot -ppassword -h dblb 48 | MySQL [(none)]> create table mydb.foo (name varchar(10)); 49 | MySQL [(none)]> insert into mydb.foo values('ruan'); 50 | MySQL [(none)]> exit 51 | ``` 52 | 53 | ### Scale the Cluster: 54 | 55 | ``` 56 | $ docker service scale galera_dbcluster=3 57 | galera_dbcluster scaled to 3 58 | overall progress: 3 out of 3 tasks 59 | 1/3: running [==================================================>] 60 | 2/3: running [==================================================>] 61 | 3/3: running [==================================================>] 62 | verify: Service converged 63 | ``` 64 | 65 | Verify: 66 | 67 | ``` 68 | $ docker service ls 69 | ID NAME MODE REPLICAS IMAGE PORTS 70 | jm7p70qre72u galera_dbclient replicated 1/1 alpine:latest 71 | p8kcr5y7szte galera_dbcluster replicated 3/3 toughiq/mariadb-cluster:latest 72 | 1hu3oxhujgfm galera_dblb replicated 1/1 toughiq/maxscale:latest *:3306->3306/tcp 73 | ``` 74 | 75 | Test: 76 | 77 | ``` 78 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 79 | +------+ 80 | | name | 81 | +------+ 82 | | ruan | 83 | +------+ 84 | ``` 85 | 86 | Simulate a node failure: 87 | 88 | ``` 89 | $ docker kill 9e336032ab52 90 | $ docker service ls 91 | ID NAME MODE REPLICAS IMAGE PORTS 92 | jm7p70qre72u galera_dbclient replicated 1/1 alpine:latest 93 | p8kcr5y7szte galera_dbcluster replicated 2/3 toughiq/mariadb-cluster:latest 94 | 1hu3oxhujgfm galera_dblb replicated 1/1 toughiq/maxscale:latest *:3306->3306/tcp 95 | ``` 96 | 97 | While the container is provisioning, as we have 2 out of 3 running containers, read the data 3 times so test that the round robin queries dont hit the affected container (the dblb wont route traffic to the affected container): 98 | 99 | ``` 100 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 101 | +------+ 102 | | name | 103 | +------+ 104 | | ruan | 105 | +------+ 106 | 107 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 108 | +------+ 109 | | name | 110 | +------+ 111 | | ruan | 112 | +------+ 113 | 114 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 115 | +------+ 116 | | name | 117 | +------+ 118 | | ruan | 119 | +------+ 120 | ``` 121 | 122 | Verify that the 3rd container has checked in: 123 | 124 | ``` 125 | $ docker service ls 126 | ID NAME MODE REPLICAS IMAGE PORTS 127 | jm7p70qre72u galera_dbclient replicated 1/1 alpine:latest 128 | p8kcr5y7szte galera_dbcluster replicated 3/3 toughiq/mariadb-cluster:latest 129 | 1hu3oxhujgfm galera_dblb replicated 1/1 toughiq/maxscale:latest *:3306->3306/tcp 130 | ``` 131 | 132 | ### How to restore? 133 | 134 | im deleting the db to simulate the scenario 135 | 136 | ``` 137 | $ docker exec -it $(docker ps -f name=galera_dbclient -q) sh 138 | > mysql -uroot -ppassword -h dblb -e'drop database mydb;' 139 | ``` 140 | 141 | ensure the db is not present: 142 | 143 | ``` 144 | > mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 145 | ERROR 1146 (42S02) at line 1: Table 'mydb.foo' doesn't exist 146 | ``` 147 | 148 | Find the archive and extract: 149 | 150 | ``` 151 | > find /data/ 152 | /data/ 153 | /data/2019-05-10 154 | /data/2019-05-10/db_backup-2019-05-10T10.05.sql.gz 155 | 156 | > gunzip /data/2019-05-10/db_backup-2019-05-10T10.05.sql.gz 157 | ``` 158 | 159 | Restore to mysql: 160 | 161 | ``` 162 | > mysql -uroot -ppassword -h dblb < /data/2019-05-10/db_backup-2019-05-10T10.05.sql 163 | ``` 164 | 165 | Test: 166 | 167 | ``` 168 | > mysql -uroot -ppassword -h dblb -e'select * from mydb.foo;' 169 | +------+ 170 | | name | 171 | +------+ 172 | | ruan | 173 | +------+ 174 | ``` 175 | -------------------------------------------------------------------------------- /mysql-cluster/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | dbclient: 4 | image: alpine 5 | environment: 6 | - BACKUP_ENABLED=1 7 | - BACKUP_INTERVAL=60 8 | - BACKUP_PATH=/data 9 | - BACKUP_FILENAME=db_backup 10 | networks: 11 | - dbnet 12 | entrypoint: | 13 | sh -c 'sh -s << EOF 14 | apk add --no-cache mysql-client 15 | while true 16 | do 17 | if [ $$BACKUP_ENABLED == 1 ] 18 | then 19 | sleep $$BACKUP_INTERVAL 20 | mkdir -p $$BACKUP_PATH/$$(date +%F) 21 | echo "$$(date +%FT%H.%m) - Making Backup to : $$BACKUP_PATH/$$(date +%F)/$$BACKUP_FILENAME-$$(date +%FT%H.%m).sql.gz" 22 | mysqldump -u root -ppassword -h dblb --all-databases | gzip > $$BACKUP_PATH/$$(date +%F)/$$BACKUP_FILENAME-$$(date +%FT%H.%m).sql.gz 23 | find $$BACKUP_PATH -mtime 7 -delete 24 | fi 25 | done 26 | EOF' 27 | volumes: 28 | - vol_dbclient:/data 29 | deploy: 30 | mode: replicated 31 | replicas: 1 32 | 33 | dbcluster: 34 | image: toughiq/mariadb-cluster 35 | networks: 36 | - dbnet 37 | environment: 38 | - DB_SERVICE_NAME=dbcluster 39 | - MYSQL_ROOT_PASSWORD=password 40 | - MYSQL_DATABASE=mydb 41 | - MYSQL_USER=mydbuser 42 | - MYSQL_PASSWORD=mydbpass 43 | deploy: 44 | mode: replicated 45 | replicas: 1 46 | 47 | dblb: 48 | image: toughiq/maxscale 49 | networks: 50 | - dbnet 51 | ports: 52 | - 3306:3306 53 | environment: 54 | - DB_SERVICE_NAME=dbcluster 55 | - ENABLE_ROOT_USER=1 56 | deploy: 57 | mode: replicated 58 | replicas: 1 59 | 60 | volumes: 61 | vol_dbclient: 62 | driver: local 63 | 64 | networks: 65 | dbnet: 66 | name: dbnet 67 | driver: overlay 68 | -------------------------------------------------------------------------------- /mysql/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | db: 3 | image: mysql:5.7 4 | restart: always 5 | ports: 6 | - 3306:3306 7 | environment: 8 | MYSQL_DATABASE: test 9 | MYSQL_ROOT_PASSWORD: password 10 | MYSQL_USER: demo 11 | MYSQL_PASSWORD: demo 12 | volumes: 13 | - mysql_data:/var/lib/mysql 14 | 15 | volumes: 16 | mysql_data: {} 17 | -------------------------------------------------------------------------------- /nginx-json/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | ADD nginx.conf /etc/nginx/nginx.conf 3 | ADD index.html /usr/share/nginx/html/index.html 4 | -------------------------------------------------------------------------------- /nginx-json/README.md: -------------------------------------------------------------------------------- 1 | Nginx that outputs json logs 2 | 3 | ## Usage 4 | 5 | Run a container: 6 | 7 | ``` 8 | $ docker run -itd -p 809:80 ruanbekker/nginx-demo:json 9 | ae9c1d183f12013c53121e3ee398ed64b264928120ebb33dfb4b964972743d85 10 | ``` 11 | 12 | Make a request: 13 | 14 | ``` 15 | $ curl -XGET -H "Host: foo.example.com" --referer "google.com" 'http://localhost:809/?foo=bar' 16 | ok 17 | ``` 18 | 19 | View the logs: 20 | 21 | ``` 22 | $ docker logs -f ae9c1d183f12013c53121e3ee398ed64b264928120ebb33dfb4b964972743d85 | jq . 23 | { 24 | "@timestamp": "2020-05-21T08:04:55+00:00", 25 | "host": "ae9c1d183f12", 26 | "server_ip": "172.17.0.2", 27 | "client_ip": "172.17.0.1", 28 | "xff": "-", 29 | "domain": "foo.example.com", 30 | "url": "/index.html", 31 | "referer": "google.com", 32 | "args": "foo=bar", 33 | "upstreamtime": "-", 34 | "responsetime": "0.000", 35 | "request_method": "GET", 36 | "status": "200", 37 | "size": "3", 38 | "request_body": "-", 39 | "request_length": "108", 40 | "protocol": "HTTP/1.1", 41 | "upstreamhost": "-", 42 | "file_dir": "/usr/share/nginx/html/index.html", 43 | "http_user_agent": "curl/7.64.1" 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /nginx-json/index.html: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /nginx-json/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes auto; 3 | pid /run/nginx.pid; 4 | 5 | events { 6 | worker_connections 768; 7 | } 8 | 9 | http { 10 | 11 | # Basic Settings 12 | sendfile on; 13 | tcp_nopush on; 14 | tcp_nodelay on; 15 | keepalive_timeout 65; 16 | types_hash_max_size 2048; 17 | server_names_hash_bucket_size 64; 18 | include /etc/nginx/mime.types; 19 | default_type application/octet-stream; 20 | 21 | # SSL Settings 22 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE 23 | ssl_prefer_server_ciphers on; 24 | 25 | # Logging Settings 26 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 27 | '$status $body_bytes_sent "$http_referer" ' 28 | '"$http_user_agent" "$http_x_forwarded_for"'; 29 | 30 | log_format json_logs '{"@timestamp":"$time_iso8601","host":"$hostname",' 31 | '"server_ip":"$server_addr","client_ip":"$remote_addr",' 32 | '"xff":"$http_x_forwarded_for","domain":"$host",' 33 | '"url":"$uri","referer":"$http_referer",' 34 | '"args":"$args","upstreamtime":"$upstream_response_time",' 35 | '"responsetime":"$request_time","request_method":"$request_method",' 36 | '"status":"$status","size":"$body_bytes_sent",' 37 | '"request_body":"$request_body","request_length":"$request_length",' 38 | '"protocol":"$server_protocol","upstreamhost":"$upstream_addr",' 39 | '"file_dir":"$request_filename","http_user_agent":"$http_user_agent"' 40 | '}'; 41 | 42 | access_log /var/log/nginx/access.log json_logs; 43 | error_log /var/log/nginx/error.log; 44 | 45 | # Gzip Settings 46 | gzip on; 47 | gzip_disable "msie6"; 48 | gzip_vary on; 49 | gzip_proxied any; 50 | gzip_comp_level 6; 51 | gzip_buffers 16 8k; 52 | gzip_http_version 1.1; 53 | gzip_min_length 256; 54 | gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; 55 | 56 | # Server Settings 57 | server { 58 | 59 | listen 80; 60 | 61 | location / { 62 | root /usr/share/nginx/html; 63 | index index.html; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /nodejs-hostname/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | ADD app.js /app.js 3 | CMD ["node", "/app.js"] 4 | -------------------------------------------------------------------------------- /nodejs-hostname/README.md: -------------------------------------------------------------------------------- 1 | Image: ruanbekker/hostname-nodejs 2 | -------------------------------------------------------------------------------- /nodejs-hostname/app.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var os = require('os'); 3 | 4 | http.createServer(function (req, res) { 5 | res.writeHead(200, {'Content-Type': 'text/html'}); 6 | res.end(`My Hostname: ${os.hostname()}\n`); 7 | }).listen(8080); 8 | 9 | console.log('Listening on :8080'); 10 | -------------------------------------------------------------------------------- /opencart/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.2-apache 2 | 3 | RUN a2enmod rewrite 4 | 5 | RUN set -xe \ 6 | && apt-get update \ 7 | && apt-get install -y libpng-dev libjpeg-dev libmcrypt-dev \ 8 | && rm -rf /var/lib/apt/lists/* \ 9 | && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ 10 | && docker-php-ext-install gd mbstring mysqli zip \ 11 | && pecl install mcrypt-1.0.1 \ 12 | && docker-php-ext-enable mcrypt 13 | 14 | WORKDIR /var/www/html 15 | 16 | ENV OPENCART_VER 3.0.3.2 17 | ENV OPENCART_URL https://github.com/opencart/opencart/archive/${OPENCART_VER}.tar.gz 18 | ENV OPENCART_FILE opencart.tar.gz 19 | 20 | RUN set -xe \ 21 | && curl -sSL ${OPENCART_URL} -o ${OPENCART_FILE} \ 22 | && tar xzf ${OPENCART_FILE} --strip 2 --wildcards '*/upload/' \ 23 | && mv config-dist.php config.php \ 24 | && mv admin/config-dist.php admin/config.php \ 25 | && rm ${OPENCART_FILE} \ 26 | && chown -R www-data:www-data /var/www 27 | -------------------------------------------------------------------------------- /opencart/README.md: -------------------------------------------------------------------------------- 1 | ## Versions 2 | 3 | - [ruanbekker/opencart:v3.0.3.2](https://hub.docker.com/layers/ruanbekker/opencart/v3.0.3.2/images/sha256-0df2e0a9b6ee25ff101645c5c0e41301d70ea7a8047aaf1f179e6ae9b981a93b?context=explore) 4 | -------------------------------------------------------------------------------- /openvpn-client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.7 2 | 3 | RUN apk --update add curl openvpn 4 | 5 | HEALTHCHECK --interval=60s --timeout=15s --start-period=120s \ 6 | CMD curl 'https://api.ipify.org' 7 | 8 | VOLUME [ "/vpn/config" ] 9 | CMD [ "openvpn", "--config", "/vpn/config/config.ovpn" ] 10 | -------------------------------------------------------------------------------- /openvpn-server/README.md: -------------------------------------------------------------------------------- 1 | - https://github.com/kylemanna/docker-openvpn.git 2 | -------------------------------------------------------------------------------- /passwordless-ssh/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add \ 4 | bash \ 5 | curl \ 6 | openssh \ 7 | openssl \ 8 | bind-tools \ 9 | && ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa 10 | 11 | COPY sshd_config /etc/ssh/sshd_config 12 | COPY boot.sh /boot.sh 13 | COPY motd-generator.sh /motd-generator.sh 14 | RUN chmod +x /boot.sh && addgroup ssh-users 15 | 16 | CMD ["/boot.sh"] 17 | -------------------------------------------------------------------------------- /passwordless-ssh/README.md: -------------------------------------------------------------------------------- 1 | # Passwordless SSH Container 2 | Container that grants SSH to normal user for no auth 3 | 4 | ## Why not auth 5 | purely for debugging / homelab purposes 6 | 7 | ### Auto Generated Usernames 8 | 9 | Running the container with generated usernames: 10 | 11 | ``` 12 | $ docker run -it -p 2222:22 ruanbekker/ssh-noauth 13 | SSH User is: user-c2ae30179dbd9f01be1a2b6c 14 | ``` 15 | 16 | SSH to the Container: 17 | 18 | ``` 19 | $ ssh -p 2222 user-c2ae30179dbd9f01be1a2b6c@localhost 130 ↵ 20 | 21 | + Container Info: 22 | 23 | Name: de276bd33aa2 24 | 25 | CPU: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz 26 | Memory: 1999M 27 | Disk: 58.4G 28 | Distro: Alpine:3.9.3 29 | 30 | CPU Load: 0.20, 0.16, 0.10 31 | Free Memory: 438M 32 | Free Disk: 58.4G 33 | 34 | Container Address: 172.17.0.3 35 | Public Address: x.x.x.x 36 | SSH User: user-c2ae30179dbd9f01be1a2b6c 37 | 38 | de276bd33aa2:~$ 39 | ``` 40 | 41 | ### Specifying your own username 42 | 43 | Running the container with your own username: 44 | 45 | ``` 46 | $ docker run -it -e SSH_USER=ruan -p 2222:22 ruanbekker/ssh-noauth 47 | SSH User is: ruan 48 | ``` 49 | 50 | SSH to the container: 51 | 52 | ``` 53 | $ ssh -p 2222 ruan@localhost 54 | 55 | + Container Info: 56 | 57 | Name: 9b9b20b498d0 58 | 59 | CPU: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz 60 | Memory: 1999M 61 | Disk: 58.4G 62 | Distro: Alpine:3.9.3 63 | 64 | CPU Load: 1.35, 0.42, 0.19 65 | Free Memory: 431M 66 | Free Disk: 58.4G 67 | 68 | Container Address: 172.17.0.3 69 | Public Address: xx.xx.xx.xx 70 | SSH User: ruan 71 | 72 | 9b9b20b498d0:~$ 73 | ``` 74 | -------------------------------------------------------------------------------- /passwordless-ssh/boot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | create_user() { 4 | SSH_USER="user-$(openssl rand -hex 12)" 5 | export SSH_USER=${SSH_USER} 6 | adduser -D -s /bin/bash -G ssh-users ${SSH_USER} 7 | echo -e "\n" | passwd ${SSH_USER} 8 | } 9 | 10 | add_user(){ 11 | adduser -D -s /bin/bash -G ssh-users ${SSH_USER} 12 | echo -e "\n" | passwd ${SSH_USER} 13 | } 14 | 15 | if [ -z ${SSH_USER} ] 16 | then 17 | create_user 18 | else 19 | add_user 20 | fi 21 | 22 | export SSH_USER=${SSH_USER} 23 | echo "SSH User is: ${SSH_USER}" 24 | 25 | bash /motd-generator.sh 26 | /usr/sbin/sshd -f /etc/ssh/sshd_config -D 27 | -------------------------------------------------------------------------------- /passwordless-ssh/motd-generator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cat > /etc/motd << EOF 3 | 4 | + Container Info: 5 | 6 | Name: $(hostname) 7 | 8 | CPU: `cat /proc/cpuinfo | grep 'model name' | head -1 | cut -d':' -f2` 9 | Memory: `free -m | head -n 2 | tail -n 1 | awk {'print $2'}`M 10 | Disk: `df -h / | awk '{ a = $2 } END { print a }'` 11 | Distro: Alpine:$(cat /etc/os-release | tr '\n' ' ' | awk '{print $4}' | cut -d '=' -f2) 12 | 13 | CPU Load: `cat /proc/loadavg | awk '{print $1 ", " $2 ", " $3}'` 14 | Free Memory: `free -m | head -n 2 | tail -n 1 | awk {'print $4'}`M 15 | Free Disk: `df -h / | awk '{ a = $2 } END { print a }'` 16 | 17 | Container Address: `ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` 18 | Public Address: $(curl -s ip.ruanbekker.com) 19 | SSH User: ${SSH_USER} 20 | 21 | EOF 22 | -------------------------------------------------------------------------------- /passwordless-ssh/sshd_config: -------------------------------------------------------------------------------- 1 | # $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ 2 | 3 | # This is the sshd server system-wide configuration file. See 4 | # sshd_config(5) for more information. 5 | 6 | # This sshd was compiled with PATH=/bin:/usr/bin:/sbin:/usr/sbin 7 | 8 | Port 22 9 | #AddressFamily any 10 | #ListenAddress 0.0.0.0 11 | #ListenAddress :: 12 | 13 | HostKey /etc/ssh/ssh_host_rsa_key 14 | 15 | # Ciphers and keying 16 | #AllowUsers user1 user2 17 | AllowGroups ssh-users 18 | # Logging 19 | #SyslogFacility AUTH 20 | #LogLevel INFO 21 | 22 | #LoginGraceTime 2m 23 | PermitRootLogin no 24 | MaxSessions 10 25 | AuthorizedKeysFile .ssh/authorized_keys 26 | PermitEmptyPasswords yes 27 | 28 | #AllowAgentForwarding yes 29 | AllowTcpForwarding no 30 | GatewayPorts no 31 | X11Forwarding no 32 | #PrintMotd yes 33 | #TCPKeepAlive yes 34 | UseDNS no 35 | #PermitTunnel no 36 | #Banner none 37 | Subsystem sftp /usr/lib/ssh/sftp-server 38 | -------------------------------------------------------------------------------- /php-composer/7.3.19/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.3.19-cli 2 | 3 | RUN apt-get update \ 4 | && apt-get install \ 5 | default-mysql-client \ 6 | default-libmysqlclient-dev \ 7 | curl git libfreetype6-dev \ 8 | libjpeg62-turbo-dev \ 9 | libmcrypt-dev libpng-dev \ 10 | libzip-dev libxml2 libxml2-dev libcurl4-gnutls-dev libssl-dev sqlite3 libsqlite3-dev libedit-dev libxslt1-dev -y 11 | 12 | RUN docker-php-ext-install iconv \ 13 | && pecl install mcrypt-1.0.3 \ 14 | && docker-php-ext-enable mcrypt \ 15 | && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ 16 | && docker-php-ext-install gd \ 17 | && docker-php-ext-install zip \ 18 | && docker-php-ext-install mysqli \ 19 | && docker-php-ext-install opcache \ 20 | && docker-php-ext-install mbstring \ 21 | && docker-php-ext-install bcmath \ 22 | && docker-php-ext-install pcntl \ 23 | && docker-php-ext-install calendar \ 24 | && docker-php-ext-install pdo \ 25 | && docker-php-ext-install curl \ 26 | && docker-php-ext-install exif \ 27 | && docker-php-ext-install gettext \ 28 | && docker-php-ext-install gmp \ 29 | && docker-php-ext-install exif \ 30 | && docker-php-ext-install intl \ 31 | && docker-php-ext-install pdo_mysql \ 32 | && docker-php-ext-install pdo_sqlite \ 33 | && docker-php-ext-install readline \ 34 | && pecl install -o -f redis \ 35 | && rm -rf /tmp/pear && docker-php-ext-enable redis \ 36 | && docker-php-ext-install shmop \ 37 | && docker-php-ext-install sockets \ 38 | && docker-php-ext-install sysvsem \ 39 | && docker-php-ext-install sysvshm \ 40 | && docker-php-ext-install wddx \ 41 | && docker-php-ext-install xsl \ 42 | && pecl install msgpack && docker-php-ext-enable msgpack \ 43 | && pecl install igbinary && docker-php-ext-enable igbinary \ 44 | && docker-php-ext-install sysvmsg 45 | 46 | #RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer 47 | RUN curl -O "https://getcomposer.org/download/1.10.21/composer.phar" \ 48 | && chmod a+x composer.phar \ 49 | && mv composer.phar /usr/bin/composer 50 | RUN composer global require phpunit/phpunit "^7.5" 51 | RUN composer global require mybuilder/phpunit-accelerator "^1.2" --dev 52 | 53 | ENV PATH /root/.composer/vendor/bin:$PATH 54 | RUN ln -s /root/.composer/vendor/bin/phpunit /usr/bin/phpunit 55 | -------------------------------------------------------------------------------- /php-fpm/7.3.19/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.3.19-fpm-alpine AS target 2 | 3 | WORKDIR /var/www/html 4 | 5 | RUN apk --no-cache add \ 6 | build-base \ 7 | freetype-dev \ 8 | libjpeg-turbo-dev \ 9 | libpng-dev \ 10 | libzip-dev \ 11 | libxml2-dev \ 12 | zip \ 13 | jpegoptim optipng pngquant gifsicle \ 14 | vim \ 15 | unzip \ 16 | git \ 17 | curl \ 18 | supervisor 19 | 20 | RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl bcmath json ctype fileinfo tokenizer 21 | RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ 22 | RUN docker-php-ext-install gd 23 | 24 | RUN apk add autoconf && pecl install -o -f redis \ 25 | && rm -rf /tmp/pear \ 26 | && docker-php-ext-enable redis && apk del autoconf 27 | -------------------------------------------------------------------------------- /postfix-exporter/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang 2 | ADD postfix_exporter /postfix_exporter 3 | 4 | ENTRYPOINT [ "/postfix_exporter" ] 5 | CMD [ "--web.listen-address=:9154", \ 6 | "--web.telemetry-path=/metrics", \ 7 | "--postfix.showq_path=/var/spool/postfix/public/showq", \ 8 | "--postfix.logfile_path=/var/log/maillog" ] 9 | -------------------------------------------------------------------------------- /postfix-exporter/README.md: -------------------------------------------------------------------------------- 1 | ### Usage 2 | 3 | Start the Postfix Exporter: 4 | 5 | ``` 6 | $ docker run -it -p 9154:9154 \ 7 | -v /var/log/mail.log:/var/log/maillog \ 8 | -v /var/spool/postfix/public/showq:/var/spool/postfix/public/showq \ 9 | ruanbekker/postfix-exporter 10 | ``` 11 | 12 | Example scrape: 13 | 14 | ``` 15 | $ curl http://x.x.x.x:9154/metrics 16 | # TYPE postfix_cleanup_messages_processed_total counter 17 | postfix_cleanup_messages_processed_total 0 18 | ``` 19 | -------------------------------------------------------------------------------- /postfix-exporter/build_binary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CDIR=$(pwd) 4 | cd /tmp 5 | 6 | git clone https://github.com/kumina/postfix_exporter 7 | cd postfix_exporter 8 | docker run -i -v `pwd`:/postfix_exporter golang:1.12 /bin/sh << 'EOF' 9 | set -ex 10 | 11 | # Install prerequisites for the build process. 12 | apt-get update -q 13 | apt-get install -yq libsystemd-dev 14 | 15 | cd /postfix_exporter 16 | 17 | go get -d ./... 18 | go build -a -tags nosystemd 19 | strip postfix_exporter 20 | EOF 21 | 22 | mv postfix_exporter $CDIR/postfix_exporter 23 | rm -rf /tmp/postfix_exporter 24 | -------------------------------------------------------------------------------- /redis/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | redis-server: 4 | image: redis:alpine 5 | container_name: redis-server 6 | networks: 7 | - public 8 | 9 | redis-client: 10 | image: redis:alpine 11 | container_name: redis-client 12 | entrypoint: | 13 | sh -c 'sh -s << EOF 14 | while true 15 | do 16 | sleep 5 17 | redis-cli -h redis-server -p 6379 ping 18 | redis-cli -h redis-server -p 6379 SET key `head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13` 19 | redis-cli -h redis-server -p 6379 GET key 20 | done 21 | EOF' 22 | networks: 23 | - public 24 | depends_on: 25 | - redis-server 26 | 27 | networks: 28 | public: {} 29 | -------------------------------------------------------------------------------- /retrowave/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:stable 2 | 3 | COPY static /usr/share/nginx/html/static 4 | COPY index.html /usr/share/nginx/html/index.html 5 | -------------------------------------------------------------------------------- /retrowave/README.md: -------------------------------------------------------------------------------- 1 | # retrowave 2 | 3 | Super simple html for demo's 4 | 5 | ## Usage 6 | 7 | Variant 1: 8 | 9 | ```bash 10 | docker run -it -p 8080:80 ruanbekker/retrowave 11 | ``` 12 | 13 | Variant 2: 14 | 15 | ```bash 16 | docker run -it -p 8080:80 ruanbekker/retrowave:v2 17 | ``` 18 | -------------------------------------------------------------------------------- /retrowave/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |

Demo Web Serivce

11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /retrowave/static/css/style.css: -------------------------------------------------------------------------------- 1 | .module { 2 | width: 100%; 3 | height: 100%; 4 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url("../images/retrowave-blue-pink.gif") no-repeat center; 5 | background-size: cover; 6 | position: relative; 7 | overflow: hidden; 8 | } 9 | 10 | .module > header { 11 | position: absolute; 12 | bottom: 15%; 13 | text-align: center; 14 | width: 100%; 15 | padding: 20px 10px; 16 | } 17 | 18 | .module > header > h1 { 19 | margin: 0; 20 | color: darkgray; 21 | text-shadow: 0 1px 0 black; 22 | } 23 | 24 | body { 25 | font-family: "Audiowide", sans-serif; 26 | } 27 | -------------------------------------------------------------------------------- /retrowave/static/images/retrowave-blue-pink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanbekker/dockerfiles/6ceee94d84d8807155614a0d6d9c5aac654a84dd/retrowave/static/images/retrowave-blue-pink.gif -------------------------------------------------------------------------------- /retrowave/static/images/retrowave.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanbekker/dockerfiles/6ceee94d84d8807155614a0d6d9c5aac654a84dd/retrowave/static/images/retrowave.gif -------------------------------------------------------------------------------- /ruby/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.9 2 | 3 | RUN apk add --no-cache bash git wget curl vim build-base readline-dev openssl-dev zlib-dev 4 | ENV PATH /usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH 5 | ENV RBENV_ROOT /usr/local/rbenv 6 | ENV RUBY_VERSION 2.5.1 7 | ENV CONFIGURE_OPTS --disable-install-doc 8 | 9 | RUN apk add --update linux-headers imagemagick-dev libffi-dev libffi-dev && rm -rf /var/cache/apk/* \ 10 | && git clone --depth 1 git://github.com/sstephenson/rbenv.git ${RBENV_ROOT} \ 11 | && git clone --depth 1 https://github.com/sstephenson/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build \ 12 | && git clone --depth 1 git://github.com/jf/rbenv-gemset.git ${RBENV_ROOT}/plugins/rbenv-gemset \ 13 | && ${RBENV_ROOT}/plugins/ruby-build/install.sh \ 14 | && echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh \ 15 | && rbenv install $RUBY_VERSION \ 16 | && rbenv global $RUBY_VERSION \ 17 | && rbenv rehash \ 18 | && gem install bundler 19 | 20 | COPY docker-entrypoint.sh / 21 | RUN chmod +x /docker-entrypoint.sh 22 | 23 | ENTRYPOINT ["/docker-entrypoint.sh"] 24 | -------------------------------------------------------------------------------- /ruby/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | USER_ID=${LOCAL_USER_ID:-9001} 4 | echo "Starting with UID : $USER_ID" 5 | addgroup -g $USER_ID user && adduser -D -G user -s /bin/false -u $USER_ID user 6 | export HOME=/home/user 7 | echo 'eval "$(rbenv init -)"' >> ${HOME}/.bashrc 8 | mkdir ${HOME}/git 9 | exec /bin/bash 10 | -------------------------------------------------------------------------------- /sendgrid/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD package.json /app/ 4 | ADD package-lock.json /app/ 5 | ADD config.js /app/ 6 | ADD utils.js /app/ 7 | ADD server.js /app/ 8 | 9 | WORKDIR /app/ 10 | 11 | RUN npm install 12 | EXPOSE 25 13 | 14 | CMD ["npm", "--silent", "start"] 15 | -------------------------------------------------------------------------------- /sendgrid/config.js: -------------------------------------------------------------------------------- 1 | module.exports = logger => 2 | require('common-env/withLogger')(logger) 3 | .on('env:fallback', function(fullKeyName, $default, $secure) { 4 | // see https://github.com/FGRibreau/common-env/issues/27 5 | if ($secure && !process.env[fullKeyName]) { 6 | throw new Error(`${fullKeyName} environment variable must be defined`); 7 | } 8 | }) 9 | .getOrElseAll({ 10 | smtp: { 11 | port: 25, 12 | }, 13 | sendgrid: { 14 | api: { 15 | $default: 'SENDGRID_API_KEY', 16 | $secure: true, 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /sendgrid/credits.md: -------------------------------------------------------------------------------- 1 | Credit to: https://github.com/FGRibreau/smtp-to-sendgrid-gateway 2 | 3 | ## Run 4 | 5 | ```shell 6 | docker run -it -p 25:25 -e SENDGRID_API=XXXXXXX fgribreau/smtp-to-sendgrid-gateway 7 | ``` 8 | 9 | ### Configuration - environment variables 10 | 11 | - `SENDGRID_API` (required): sendgrid API token 12 | - `SMTP_PORT` (optional) Port to listen (default: 25) 13 | 14 | -------------------------------------------------------------------------------- /sendgrid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smtp-to-sendgrid-gateway", 3 | "version": "1.1.1", 4 | "description": "Forward emails from SMTP requests to the Sendgrid API. Useful when the cloud provider does not allow outbound connections on ports 25, 465, 587.", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/FGRibreau/smtp-to-sendgrid-gateway.git" 12 | }, 13 | "keywords": [ 14 | "sendgrid", 15 | "smtp", 16 | "gateway" 17 | ], 18 | "author": "Francois-Guillaume Ribreau (http://fgribreau.com/)", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/FGRibreau/smtp-to-sendgrid-gateway/issues" 22 | }, 23 | "homepage": "https://github.com/FGRibreau/smtp-to-sendgrid-gateway#readme", 24 | "dependencies": { 25 | "@sendgrid/mail": "^6.1.2", 26 | "chai": "^4.1.0", 27 | "common-env": "^6.1.0", 28 | "debug": "^2.6.8", 29 | "mailparser": "^2.0.5", 30 | "smtp-server": "^3.1.0", 31 | "winston": "^2.3.1" 32 | }, 33 | "devDependencies": { 34 | "jest": "^20.0.4" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sendgrid/server.js: -------------------------------------------------------------------------------- 1 | const logger = require('winston'); 2 | const config = require('./config')(logger); 3 | 4 | const sgMail = require('@sendgrid/mail'); 5 | sgMail.setApiKey(config.sendgrid.api); 6 | 7 | const SMTPServer = require('smtp-server').SMTPServer; 8 | const { bufferToSendGridEmail } = require('./utils'); 9 | const debug = require('debug')('server'); 10 | 11 | // start-up the SMTP server (no auth) 12 | new SMTPServer({ 13 | secure: false, 14 | disabledCommands: ['AUTH'], 15 | onData: function(stream, session, callback) { 16 | let buffer = ''; 17 | let _mail; 18 | 19 | // parse a message as it is received 20 | stream.setEncoding('utf8'); 21 | stream.on('data', function(part) { 22 | buffer += part; 23 | }); 24 | 25 | // message fully received 26 | stream.on('end', function() { 27 | bufferToSendGridEmail(buffer, session) 28 | .then(mail => { 29 | _mail = mail; 30 | return sgMail.send(mail, false); 31 | }) 32 | .then(() => { 33 | logger.info('forwarded', JSON.stringify(_mail)); 34 | callback(); 35 | }) 36 | .catch(err => { 37 | debug('Error', err.message); 38 | debug('Error stack', err.stack); 39 | 40 | const { message, code, response } = err; 41 | 42 | logger.error( 43 | 'failed forwarding', 44 | JSON.stringify( 45 | { 46 | error: { message, code, response }, 47 | mail: _mail, 48 | }, 49 | null, 50 | 2 51 | ) 52 | ); 53 | 54 | callback(); 55 | }); 56 | }); 57 | }, 58 | }).listen(config.smtp.port); 59 | 60 | logger.info( 61 | 'SMTP Forward listening on port %s for SMTP traffic.', 62 | config.smtp.port 63 | ); 64 | -------------------------------------------------------------------------------- /sendgrid/utils.js: -------------------------------------------------------------------------------- 1 | const simpleParser = require('mailparser').simpleParser; 2 | const debugParser = require('debug')('parser'); 3 | const debugTransform = require('debug')('transform'); 4 | 5 | function parse(buffer) { 6 | debugParser('got buffer %s', buffer); 7 | return simpleParser(buffer); 8 | } 9 | 10 | const makeAddress = (address, name) => ({ 11 | name: name || address, 12 | email: address, 13 | }); 14 | 15 | function formatAddresses(addressObject) { 16 | return addressObject.value.map(({ address, name }) => 17 | makeAddress(address, name) 18 | ); 19 | } 20 | 21 | const toSendGridEmail = session => email => { 22 | debugParser('got parsed email %s', JSON.stringify(email)); 23 | 24 | const mail = { 25 | subject: email.subject, 26 | text: email.text ? email.text : undefined, 27 | html: email.html ? email.html : undefined, 28 | content: [], 29 | from: {}, 30 | to: [], 31 | }; 32 | 33 | ['cc', 'to', 'bcc'].forEach(part => { 34 | if (email[part]) { 35 | mail[part] = formatAddresses(email[part]); 36 | } 37 | }); 38 | 39 | if (email['reply-to']) { 40 | mail.replyTo = formatAddresses(email['reply-to'])[0]; 41 | } 42 | 43 | if (email.from) { 44 | mail.from = formatAddresses(email.from)[0]; 45 | } 46 | 47 | if (session.envelope.mailFrom && session.envelope.mailFrom.address) { 48 | mail.from = makeAddress(session.envelope.mailFrom.address); 49 | } 50 | 51 | if (session.envelope.rcptTo) { 52 | mail.to = session.envelope.rcptTo.map(({ address }) => 53 | makeAddress(address) 54 | ); 55 | } 56 | 57 | return mail; 58 | }; 59 | 60 | const bufferToSendGridEmail = (buffer, session) => 61 | parse(buffer).then(toSendGridEmail(session)); 62 | 63 | // parse -> toSendGridEmail 64 | module.exports = { 65 | bufferToSendGridEmail, 66 | }; 67 | -------------------------------------------------------------------------------- /sns/README.md: -------------------------------------------------------------------------------- 1 | - https://github.com/s12v/sns 2 | - https://kevinholditch.co.uk/2017/10/19/running-sns-sqs-locally-in-docker-containers-supporting-fan-out/ 3 | - https://gugsrs.com/localstack-sqs-sns/ 4 | -------------------------------------------------------------------------------- /sqs/README.md: -------------------------------------------------------------------------------- 1 | - https://github.com/vsouza/docker-SQS-local 2 | - https://github.com/roribio/alpine-sqs 3 | -------------------------------------------------------------------------------- /sqs/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | sqs: 4 | image: roribio16/alpine-sqs:latest 5 | container_name: sqs 6 | stdin_open: true 7 | tty: true 8 | networks: 9 | - public 10 | 11 | awscli: 12 | image: ruanbekker/awscli 13 | environment: 14 | - AWS_ACCESS_KEY_ID=123 15 | - AWS_SECRET_ACCESS_KEY=xyz 16 | - AWS_DEFAULT_REGION=eu-west-1 17 | entrypoint: | 18 | sh -c 'sh -s << EOF 19 | aws --endpoint-url=http://sqs:9324 sqs create-queue --queue-name test 20 | aws --endpoint-url http://sqs:9324 sqs list-queues 21 | aws --endpoint-url http://sqs:9324 sqs send-message --queue-url http://sqs:9324/queue/test --message-body "hello!" 22 | aws --endpoint-url http://sqs:9324 sqs receive-message --queue-url http://sqs:9324/queue/test --wait-time-seconds 10 23 | tail -f /dev/null 24 | EOF' 25 | networks: 26 | - public 27 | depends_on: 28 | - sqs 29 | 30 | networks: 31 | public: {} 32 | -------------------------------------------------------------------------------- /stress-half-cpu/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim 2 | ADD start.sh /start.sh 3 | CMD ["bash", "/start.sh"] 4 | -------------------------------------------------------------------------------- /stress-half-cpu/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # this uses half a cpu to reproduce a system being utilised 3 | version: "3.9" 4 | 5 | services: 6 | stress: 7 | container_name: "stress" 8 | build: . 9 | restart: unless-stopped 10 | cpus: 0.5 11 | mem_limit: 512m 12 | -------------------------------------------------------------------------------- /stress-half-cpu/start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "[$(date +%F)] starting" 3 | yes $RANDOM >/dev/null 4 | -------------------------------------------------------------------------------- /supervisord-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/ubuntu/ubuntu:22.04 2 | 3 | ENV SHARED_CONFIG_DIR=/opt/coder 4 | 5 | RUN apt update && apt install supervisor -y 6 | 7 | RUN useradd coder 8 | RUN mkdir -p /opt/coder 9 | RUN chown coder /opt/coder 10 | USER coder 11 | 12 | RUN mkdir -p $SHARED_CONFIG_DIR/etc/supervisor $SHARED_CONFIG_DIR/logs 13 | COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf 14 | 15 | COPY app-colors/colors /usr/bin/colors 16 | COPY app-messages/messages /usr/bin/messages 17 | 18 | WORKDIR /opt/coder 19 | 20 | CMD ["/usr/bin/supervisord"] 21 | -------------------------------------------------------------------------------- /supervisord-app/app-colors/README.md: -------------------------------------------------------------------------------- 1 | # app-colors 2 | 3 | ## build 4 | 5 | Build with: 6 | 7 | ```bash 8 | go build -o colors main.go 9 | ``` 10 | -------------------------------------------------------------------------------- /supervisord-app/app-colors/main.go: -------------------------------------------------------------------------------- 1 | func main() { 2 | // Seed the random number generator 3 | rand.Seed(time.Now().UnixNano()) 4 | 5 | // Define a slice of messages 6 | messages := []string{ 7 | "blue", 8 | "red", 9 | "green", 10 | "yellow", 11 | "silver", 12 | "black", 13 | "purple", 14 | "white", 15 | "gold", 16 | "pink", 17 | } 18 | 19 | // Get the pplication name from APP_NAME env var 20 | appName := os.Getenv("APP_NAME") 21 | if appName == "" { 22 | appName = "color-message" 23 | } 24 | 25 | // Infinite loop to print a message every second 26 | for { 27 | // Get a random index 28 | index := rand.Intn(len(messages)) 29 | // Print a random message 30 | fmt.Printf("app=%s message=\"%s\"\n", appName, messages[index]) 31 | // Wait for a second 32 | time.Sleep(1 * time.Second) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /supervisord-app/app-messages/README.md: -------------------------------------------------------------------------------- 1 | # app-messages 2 | 3 | ## build 4 | 5 | Build with: 6 | 7 | ```bash 8 | go build -o messages main.go 9 | ``` 10 | -------------------------------------------------------------------------------- /supervisord-app/app-messages/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | // Seed the random number generator 12 | rand.Seed(time.Now().UnixNano()) 13 | 14 | // Define a slice of messages 15 | messages := []string{ 16 | "Hello, world!", 17 | "How's it going?", 18 | "Another second passed!", 19 | "Keep smiling!", 20 | "Stay positive!", 21 | "Keep calm and code on!", 22 | "Believe in yourself!", 23 | "One moment at a time!", 24 | "Make every second count!", 25 | "Embrace the randomness!", 26 | } 27 | 28 | // Get the pplication name from APP_NAME env var 29 | appName := os.Getenv("APP_NAME") 30 | if appName == "" { 31 | appName = "random-message" 32 | } 33 | 34 | // Infinite loop to print a message every second 35 | for { 36 | // Get a random index 37 | index := rand.Intn(len(messages)) 38 | // Print a random message 39 | fmt.Printf("app=%s message=\"%s\"\n", appName, messages[index]) 40 | // Wait for a second 41 | time.Sleep(1 * time.Second) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /supervisord-app/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | logfile=/dev/null 4 | logfile_maxbytes=0 5 | loglevel=info 6 | pidfile=/opt/coder/etc/supervisor/supervisord.pid 7 | minfds=1024 8 | minprocs=200 9 | 10 | [unix_http_server] 11 | file=/opt/coder/etc/supervisor/supervisor.sock 12 | 13 | [supervisorctl] 14 | serverurl=unix:///opt/coder/etc/supervisor/supervisor.sock 15 | 16 | [program:colors] 17 | command=/usr/bin/colors 18 | user=coder 19 | autostart=true 20 | autorestart=true 21 | stdout_logfile=/dev/fd/1 22 | stdout_logfile_maxbytes=0 23 | redirect_stderr=true 24 | stopsignal=TERM 25 | stopwaitsecs=60 26 | 27 | [program:messages] 28 | command=/usr/bin/messages 29 | user=coder 30 | autostart=true 31 | autorestart=true 32 | stdout_logfile=/dev/fd/1 33 | stdout_logfile_maxbytes=0 34 | redirect_stderr=true 35 | stopsignal=TERM 36 | stopwaitsecs=60 37 | -------------------------------------------------------------------------------- /terraform/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.8 2 | 3 | ENV TERRAFORM_VERSION=0.13.3 4 | ENV AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}" 5 | ENV AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}" 6 | ENV AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" 7 | 8 | RUN apk update && \ 9 | apk add curl jq python bash ca-certificates git openssl unzip wget py2-pip && \ 10 | pip install awscli && \ 11 | cd /tmp && \ 12 | wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ 13 | unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/bin && \ 14 | rm -rf /tmp/* && \ 15 | rm -rf /var/cache/apk/* && \ 16 | rm -rf /var/tmp/* 17 | 18 | 19 | #ENTRYPOINT ["/usr/bin/terraform"] 20 | #CMD ["--help"] 21 | -------------------------------------------------------------------------------- /twitter-retweetbot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | ADD main.go /go/src/myapp/main.go 3 | RUN apk add --no-cache git 4 | WORKDIR /go/src/myapp/ 5 | RUN go get 6 | CMD ["go", "run", "main.go"] 7 | -------------------------------------------------------------------------------- /twitter-retweetbot/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/url" 5 | "os" 6 | 7 | "github.com/ChimeraCoder/anaconda" 8 | "github.com/sirupsen/logrus" 9 | ) 10 | 11 | var ( 12 | consumerKey = Getenv("TWITTER_CONSUMER_KEY") 13 | consumerSecret = Getenv("TWITTER_CONSUMER_SECRET") 14 | accessToken = Getenv("TWITTER_ACCESS_TOKEN") 15 | accessTokenSecret = Getenv("TWITTER_ACCESS_TOKEN_SECRET") 16 | keyword = Getenv("TWITTER_KEYWORD") 17 | ) 18 | 19 | func Getenv(name string) string { 20 | v := os.Getenv(name) 21 | if v == "" { 22 | panic("missing envvar " + name) 23 | } 24 | return v 25 | } 26 | 27 | func main() { 28 | anaconda.SetConsumerKey(consumerKey) 29 | anaconda.SetConsumerSecret(consumerSecret) 30 | api := anaconda.NewTwitterApi(accessToken, accessTokenSecret) 31 | 32 | stream := api.PublicStreamFilter(url.Values{ 33 | "track": []string{"#" + keyword}, 34 | }) 35 | 36 | defer stream.Stop() 37 | 38 | for v := range stream.C { 39 | t, ok := v.(anaconda.Tweet) 40 | if !ok { 41 | logrus.Warning("received unexpected error %T", v) 42 | continue 43 | } 44 | 45 | if t.RetweetedStatus != nil { 46 | continue 47 | } 48 | _, err := api.Retweet(t.Id, false) 49 | if err != nil { 50 | logrus.Errorf("could not retweet %d: %v", t.Id, err) 51 | continue 52 | } 53 | logrus.Infof("retweetedId: %d, Tweet: %v", t.Id, t.FullText) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /twitter-retweetbot/twitter.env: -------------------------------------------------------------------------------- 1 | TWITTER_CONSUMER_KEY= 2 | TWITTER_CONSUMER_SECRET= 3 | TWITTER_ACCESS_TOKEN= 4 | TWITTER_ACCESS_TOKEN_SECRET= 5 | TWITTER_KEYWORD= 6 | -------------------------------------------------------------------------------- /vscode/Dockerfile.docker: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | ENV VERSION 1.1156-vsc1.33.1 4 | ENV DOMAIN localhost 5 | ENV DOCKER_VERSION 18.09.2 6 | 7 | COPY docker-entrypoint_docker.sh /docker-entrypoint.sh 8 | 9 | RUN apt update \ 10 | && apt install iptables golang g++ make jq screen tmux nodejs bash ca-certificates openssl curl git zip unzip net-tools -y \ 11 | && update-ca-certificates \ 12 | && apt-get clean \ 13 | && wget https://github.com/cdr/code-server/releases/download/${VERSION}/code-server${VERSION}-linux-x64.tar.gz \ 14 | && tar -xzf code-server${VERSION}-linux-x64.tar.gz \ 15 | && mv code-server${VERSION}-linux-x64/code-server /usr/local/bin/code-server \ 16 | && chmod +x /usr/local/bin/code-server /docker-entrypoint.sh \ 17 | && rm -rf code-server${VERSION}-linux-x64.tar.gz \ 18 | && curl -sl https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz --output docker-${DOCKER_VERSION}.tgz \ 19 | && tar xzvf docker-${DOCKER_VERSION}.tgz && rm docker-${DOCKER_VERSION}.tgz && cp docker/* /usr/bin/ 20 | 21 | ADD ./code/ /code 22 | 23 | CMD ["/docker-entrypoint.sh"] 24 | -------------------------------------------------------------------------------- /vscode/Dockerfile.python: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | ENV VERSION 1.1156-vsc1.33.1 4 | ENV DOMAIN localhost 5 | 6 | COPY docker-entrypoint.sh / 7 | 8 | RUN apt update \ 9 | && apt install net-tools -y \ 10 | && apt-get clean \ 11 | && wget https://github.com/cdr/code-server/releases/download/${VERSION}/code-server${VERSION}-linux-x64.tar.gz \ 12 | && tar -xzf code-server${VERSION}-linux-x64.tar.gz \ 13 | && mv code-server${VERSION}-linux-x64/code-server /usr/local/bin/code-server \ 14 | && chmod +x /usr/local/bin/code-server /docker-entrypoint.sh \ 15 | && rm -rf code-server${VERSION}-linux-x64.tar.gz 16 | 17 | RUN mkdir /certs && cd /certs \ 18 | && export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo) \ 19 | && openssl genrsa -des3 -out $DOMAIN.key -passout env:PASSPHRASE 2048 \ 20 | && export subj='/C=ZA/ST=WC/O=Org/localityName=CT/commonName=localhost/organizationalUnitName=OrgUnit/emailAddress=root@localhost/' \ 21 | && openssl req -new -batch -subj "${subj}" -key $DOMAIN.key -out $DOMAIN.csr -passin env:PASSPHRASE \ 22 | && cp $DOMAIN.key $DOMAIN.key.org \ 23 | && openssl rsa -in $DOMAIN.key.org -out $DOMAIN.key -passin env:PASSPHRASE \ 24 | && openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt 25 | 26 | ADD ./code/ /code 27 | 28 | CMD ["/docker-entrypoint.sh"] 29 | -------------------------------------------------------------------------------- /vscode/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | $ mkdir code 3 | $ mkdir data 4 | 5 | $ docker run --rm --name vscode \ 6 | -it -p 8443:8443 -p 8888:8888 \ 7 | -v $(pwd)/data:/data -v $(pwd)/code:/code \ 8 | ruanbekker/vscode:python-3.7 9 | ``` 10 | 11 | Docker 12 | 13 | ``` 14 | $ docker run --privileged -it -p 8443:8443 ruanbekker/vscode:docker 15 | ``` 16 | -------------------------------------------------------------------------------- /vscode/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ $# -eq 0 ] 5 | then 6 | /usr/local/bin/code-server --cert=/certs/localhost.crt --cert-key=/certs/localhost.key --user-data-dir /data /code 7 | #/usr/local/bin/code-server --cert=~/certs/localhost.crt --cert-key=~/certs/localhost.key --allow-http --no-auth --data-dir /data /code 8 | else 9 | exec "$@" 10 | fi 11 | -------------------------------------------------------------------------------- /vscode/docker-entrypoint_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ $# -eq 0 ] 5 | then 6 | screen -S dockerd -m -d bash -c "dockerd" 7 | /usr/local/bin/code-server --allow-http --data-dir /data /code 8 | else 9 | exec "$@" 10 | fi 11 | -------------------------------------------------------------------------------- /vscode/packages/requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /waypoint/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine AS builder 2 | ENV WAYPOINT_VERSION 0.1.4 3 | ENV WAYPOINT_OS linux 4 | ENV WAYPOINT_ARCH amd64 5 | 6 | RUN apk add --no-cache wget openssl unzip \ 7 | && wget https://releases.hashicorp.com/waypoint/${WAYPOINT_VERSION}/waypoint_${WAYPOINT_VERSION}_${WAYPOINT_OS}_${WAYPOINT_ARCH}.zip \ 8 | && unzip waypoint_${WAYPOINT_VERSION}_${WAYPOINT_OS}_${WAYPOINT_ARCH}.zip \ 9 | && mv waypoint /opt/waypoint \ 10 | && chmod +x /opt/waypoint 11 | 12 | FROM busybox 13 | COPY --from=builder /opt/waypoint /bin/waypoint 14 | 15 | CMD ["/bin/sh"] 16 | -------------------------------------------------------------------------------- /web-center-name-v2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3-alpine 2 | 3 | ENV APP_TITLE Welcome 4 | ENV APP_URL https://google.com 5 | ENV APP_TEXT Visit our Website 6 | 7 | RUN pip install flask 8 | WORKDIR /app 9 | ADD . . 10 | 11 | CMD ["python", "app.py"] 12 | -------------------------------------------------------------------------------- /web-center-name-v2/README.md: -------------------------------------------------------------------------------- 1 | ## Docker Hub 2 | 3 | - [ruanbekker/web-center-name-v2](https://hub.docker.com/r/ruanbekker/web-center-name-v2) 4 | 5 | ## Usage 6 | 7 | Welcome text: 8 | 9 | ``` 10 | $ docker run -it \ 11 | -e APP_TITLE=Welcome \ 12 | -e APP_URL="https://google.com" \ 13 | -e APP_TEXT="Visit our Website" \ 14 | -p 5000:5000 ruanbekker/web-center-name-v2 15 | ``` 16 | 17 | ## Screenshots 18 | 19 | Welcome text: 20 | 21 | ![image](https://user-images.githubusercontent.com/567298/111804730-03533e80-88d9-11eb-912f-3ed7e5836478.png) 22 | 23 | -------------------------------------------------------------------------------- /web-center-name-v2/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template 2 | from os import environ as envar 3 | from socket import gethostname 4 | 5 | app = Flask(__name__) 6 | 7 | @app.route('/') 8 | def root(): 9 | hostname = gethostname() 10 | return render_template('index.html', app_title=envar['APP_TITLE'], hostname=hostname) 11 | 12 | @app.route('/health') 13 | def health(): 14 | return ('', 204) 15 | 16 | @app.route('/health/liveness') 17 | def liveness(): 18 | return ('ok', 200) 19 | 20 | @app.route('/health/readiness') 21 | def readiness(): 22 | return ('ok', 200) 23 | 24 | if __name__ == '__main__': 25 | app.run(host='0.0.0.0', port=5000) 26 | -------------------------------------------------------------------------------- /web-center-name-v2/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{ app_title }} 8 | 9 | 10 | 11 | 12 | 13 | 65 | 66 | 67 |
68 |
69 |
70 | {{ app_title }} 71 |
72 | 73 | 76 |
77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /web-center-name/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3-alpine 2 | 3 | RUN pip install flask 4 | WORKDIR /app 5 | ADD . . 6 | 7 | CMD ["python", "app.py"] 8 | -------------------------------------------------------------------------------- /web-center-name/README.md: -------------------------------------------------------------------------------- 1 | ## Docker Hub 2 | 3 | - [ruanbekker/web-center-name](https://hub.docker.com/r/ruanbekker/web-center-name) 4 | 5 | ## Usage 6 | 7 | Staging: 8 | 9 | ``` 10 | docker run -it -e APP_ENVIRONMENT=Staging -p 81:5000 ruanbekker/web-center-name 11 | ``` 12 | 13 | Production: 14 | 15 | ``` 16 | docker run -it -e APP_ENVIRONMENT=Production -p 80:5000 ruanbekker/web-center-name 17 | ``` 18 | 19 | ## Screenshots 20 | 21 | Staging: 22 | 23 | image 24 | 25 | Production: 26 | 27 | image 28 | -------------------------------------------------------------------------------- /web-center-name/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template 2 | from os import environ as envar 3 | 4 | app = Flask(__name__) 5 | 6 | @app.route('/') 7 | def root(): 8 | return render_template('index.html', app_environment=envar['APP_ENVIRONMENT']) 9 | 10 | if __name__ == '__main__': 11 | app.run(host='0.0.0.0', port=5000) 12 | -------------------------------------------------------------------------------- /web-center-name/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 35 | 36 | 37 | 38 |

This is {{ app_environment }}

39 | 40 | 41 | -------------------------------------------------------------------------------- /webhook-basic/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | RUN pip install flask 3 | ADD app.py /app.py 4 | EXPOSE 5000 5 | CMD ["python", "/app.py"] 6 | -------------------------------------------------------------------------------- /webhook-basic/README.md: -------------------------------------------------------------------------------- 1 | Server: 2 | 3 | ``` 4 | > docker run -it -p 5000:5000 ruanbekker/python-flask-webhook 5 | ``` 6 | 7 | Client: 8 | 9 | ``` 10 | > curl -XPOST http://localhost:5000 -d "foobar" -d "name" -d "foo" 11 | event: {'event': b'foobar&name&foo'} 12 | ``` 13 | 14 | ``` 15 | > curl -H "Content-Type: application/json" -XPOST http://localhost:5000 -d '{"name": "james"}' 16 | event: {'event': {'name': 'james'}} 17 | ``` 18 | -------------------------------------------------------------------------------- /webhook-basic/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request 2 | 3 | app = Flask(__name__) 4 | 5 | @app.route("/", methods=["POST", "GET"]) 6 | def main(): 7 | response = {} 8 | 9 | if request.headers["Content-Type"] == 'application/json': 10 | response["event"] = request.get_json() 11 | else: 12 | response["event"] = request.get_data() 13 | 14 | print("Received Event:") 15 | print(response) 16 | return "event: {} \n".format(response) 17 | 18 | if __name__ == "__main__": 19 | app.run(host="0.0.0.0", port=5000) 20 | -------------------------------------------------------------------------------- /whoami/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | 3 | WORKDIR /go/src/myapp/ 4 | 5 | COPY app.go . 6 | 7 | ARG CGO_ENABLED=0 8 | RUN go build -o /go/app 9 | 10 | FROM scratch 11 | COPY --from=builder /go/app /go/app 12 | 13 | CMD ["/go/app"] 14 | -------------------------------------------------------------------------------- /whoami/README.md: -------------------------------------------------------------------------------- 1 | ## Whoami 2 | 3 | Golang app that returns the hostname 4 | 5 | ### Usage: 6 | 7 | Run a container: 8 | 9 | ``` 10 | $ docker run -p 8000:8000 ruanbekker/whoami:me 2 ↵ 11 | Server listening on port 8000 12 | ``` 13 | 14 | Make a request: 15 | 16 | ``` 17 | $ curl http://localhost:8000/ 130 ↵ 18 | Hostname: ea75b484dbaf 19 | ``` 20 | 21 | About me: 22 | 23 | ``` 24 | $ curl -s http://localhost:8000/about | jq . 25 | { 26 | "name": "Ruan", 27 | "twitter": "@ruanbekker", 28 | "contact": "https://ruan.dev", 29 | "blogs": [ 30 | "https://blog.ruanbekker.com", 31 | "https://sysadmins.co.za", 32 | "https://ruan.dev/blog" 33 | ] 34 | } 35 | ``` 36 | 37 | ### Resources: 38 | 39 | - https://gowebexamples.com/http-server/ 40 | - https://gobyexample.com/environment-variables 41 | - https://www.golang-book.com/books/intro/4 42 | - https://flaviocopes.com/go-web-server/ 43 | - https://www.alexedwards.net/blog/golang-response-snippets 44 | -------------------------------------------------------------------------------- /whoami/app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "net/http" 7 | "encoding/json" 8 | ) 9 | 10 | type User struct { 11 | Name string `json:"name"` 12 | Twitter string `json:"twitter"` 13 | Contact string `json:"contact"` 14 | Blogs []string `json:"blogs"` 15 | } 16 | 17 | func main() { 18 | const port string = "8000" 19 | fmt.Println("Server listening on port", port) 20 | http.HandleFunc("/", hostnameHandler) 21 | http.HandleFunc("/about", aboutHandler) 22 | http.ListenAndServe(":" + port, nil) 23 | } 24 | 25 | func hostnameHandler(w http.ResponseWriter, r *http.Request) { 26 | myhostname, _ := os.Hostname() 27 | fmt.Fprintln(w, "Hostname:", myhostname) 28 | } 29 | 30 | func aboutHandler(w http.ResponseWriter, r *http.Request) { 31 | w.Header().Set("Content-Type", "application/json") 32 | user := User{ 33 | Name: "Ruan", 34 | Twitter: "@ruanbekker", 35 | Contact: "https://ruan.dev", 36 | Blogs: []string{"https://blog.ruanbekker.com", "https://sysadmins.co.za", "https://ruan.dev/blog"}, 37 | } 38 | if err := json.NewEncoder(w).Encode(user); err != nil { 39 | http.Error(w, err.Error(), http.StatusInternalServerError) 40 | return 41 | } 42 | } 43 | --------------------------------------------------------------------------------