├── LICENSE.md ├── Makefile ├── README.md ├── base ├── Dockerfile ├── README.md └── root │ ├── bin │ └── envsubst │ ├── etc │ ├── init │ │ └── srv │ └── service │ │ ├── .s6-svscan │ │ ├── crash │ │ └── finish │ │ ├── cmdline │ │ ├── down │ │ ├── finish │ │ ├── nosetsid │ │ └── run │ │ ├── crond │ │ └── run │ │ └── syslog │ │ └── run │ └── sbin │ ├── halt │ ├── init │ ├── service │ └── shutdown ├── digitalocean-ddns ├── Dockerfile └── ddns.sh ├── gitweb ├── Dockerfile └── root │ └── etc │ ├── gitweb.conf │ ├── nginx │ └── conf.d │ │ └── default.conf │ └── service │ ├── fcgiwrap │ └── run │ └── gitweb │ └── run ├── matomo ├── Dockerfile ├── README.md └── root │ └── etc │ ├── config.ini.php.template │ ├── init │ └── matomo-generate-config.sh │ └── periodic │ └── hourly │ └── matomo-archive ├── mkdocs ├── Dockerfile └── README.md ├── nginx ├── Dockerfile ├── README.md └── root │ └── etc │ ├── nginx │ ├── conf.d │ │ └── default.conf │ ├── gzip │ └── nginx.conf │ └── service │ └── nginx │ ├── finish │ └── run ├── openssh ├── Dockerfile ├── README.md └── root │ └── etc │ ├── init │ └── sshd-keygen │ └── service │ └── sshd │ ├── finish │ └── run ├── php-nginx ├── Dockerfile ├── README.md └── root │ ├── etc │ ├── nginx │ │ └── conf.d │ │ │ └── default.conf │ ├── php7 │ │ └── php-fpm.conf │ └── service │ │ └── php-fpm7 │ │ ├── finish │ │ └── run │ └── srv │ └── www │ └── index.php ├── php └── Dockerfile ├── pritunl ├── Dockerfile └── etc │ ├── init │ └── tun │ └── service │ ├── mongodb │ └── run │ └── pritunl │ ├── finish │ └── run ├── prosody ├── Dockerfile ├── etc │ ├── init │ │ └── prosody │ ├── nginx │ │ └── conf.d │ │ │ └── default.conf │ ├── prosody │ │ └── prosody.cfg.lua │ └── service │ │ └── prosody │ │ ├── finish │ │ └── run └── www │ └── index.html ├── remote-docker ├── Dockerfile ├── README.md └── root │ └── etc │ └── init │ └── docker-tunnel ├── reverse-proxy ├── Dockerfile ├── README.md └── root │ └── etc │ ├── nginx │ ├── prelude.d │ │ └── reverse-proxy.conf │ └── proxy_cache │ └── service │ └── dnsmasq │ └── run ├── seafile ├── Dockerfile ├── README.md ├── etc │ ├── init │ │ └── seafile │ ├── nginx │ │ └── conf.d │ │ │ └── default.conf │ └── service │ │ ├── seafile │ │ ├── finish │ │ └── run │ │ └── seahub │ │ ├── finish │ │ └── run └── seahub.conf └── znc ├── Dockerfile ├── README.md └── root └── etc ├── init └── znc ├── service └── znc │ ├── finish │ └── run └── znc.default.conf /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © 2016 Stephen Coakley 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NS = sagebind 2 | DOCKERFILES = $(wildcard */Dockerfile) 3 | 4 | all: $(patsubst %/Dockerfile,build-%,$(DOCKERFILES)) 5 | 6 | push: $(patsubst %/Dockerfile,push-%,$(DOCKERFILES)) 7 | 8 | build-%: 9 | docker build -t $(NS)/$* $* 10 | 11 | push-%: build-% 12 | docker push $(NS)/$(subst @,:,$*) 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dockerfiles 2 | 3 | [![Build Status](https://semaphoreci.com/api/v1/sagebind/dockerfiles/branches/master/badge.svg)](https://semaphoreci.com/sagebind/dockerfiles) 4 | 5 | This repository contains a collection of Dockerfiles, which are specifications of container images for Docker. Official builds of these images are available in [Docker Hub][docker-hub] under my user name. 6 | 7 | ## Conventions 8 | While each image in this repository serves a different use-case, for simplicity they all share some common conventions: 9 | 10 | - When possible, services are run under a non-root user for enhanced security. 11 | - Binaries, sources, and configs for a container's primary apps are put in [`/srv`][srv] to keep paths short and sane and to ease managing permissions. This directory is accessible to all users in the `srv` group, and is always readable and writable to users in the `srv` group. These settings are set when the container boots up. 12 | 13 | ## Images 14 | Below is a list and brief summary of all the images contained in this repository. The image name is linked to an appropriate README with further details on the image. 15 | 16 | ### [`base`](base) 17 | A tiny image based on [Alpine Linux][alpine] using [s6] to supervise multiple processes in one container. Most of the images in this repository are based on this image. 18 | 19 | ### [`matomo`](matomo) 20 | A lightweight image for [Matomo], a popular open-source analytics platform. 21 | 22 | ### [`nginx`](nginx) 23 | A lightweight [NGINX] image that runs NGINX as an unpriveleged system service. 24 | 25 | ### [`php-nginx`](php-nginx) 26 | A lightweight PHP application server with PHP 7, PHP-FPM and [NGINX]. 27 | 28 | ## License 29 | Unless otherwise indicated, all files in this repository are licensed under the [MIT license][license]. 30 | 31 | 32 | [alpine]: https://www.alpinelinux.org 33 | [docker]: https://www.docker.com 34 | [docker-hub]: https://index.docker.io/u/sagebind 35 | [license]: LICENSE.md 36 | [matomo]: http://matomo.org 37 | [nginx]: http://nginx.org 38 | [s6]: http://skarnet.org/software/s6/ 39 | [srv]: http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/srv.html 40 | -------------------------------------------------------------------------------- /base/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:$ALPINE_VERSION 3 | 4 | RUN apk --no-cache upgrade && \ 5 | apk --no-cache add s6 && \ 6 | addgroup -g 9000 srv 7 | 8 | COPY root / 9 | 10 | ENTRYPOINT ["/sbin/init"] 11 | -------------------------------------------------------------------------------- /base/README.md: -------------------------------------------------------------------------------- 1 | # Sagebind's tiny base image 2 | A tiny image based on [Alpine Linux][alpine] using [s6] to supervise multiple processes in one container. 3 | 4 | This is a low-level [Docker][docker] image meant to be a base for building lightweight, correct Docker images. Most of my own images use this image as a base, and you can use it as a solid base for your own lightweight images, too. 5 | 6 | The goal of this image is to meet all of the following needs: 7 | 8 | - A stable, secure system containing only the essential components. 9 | - A correct `init` process. 10 | - Ability to run multiple processes as part of a single, conceptual service. 11 | - Logging that integrates with `docker logs`. 12 | 13 | ## The init process 14 | A container based on this image always starts its life by executing `/sbin/init`, which performs the following steps: 15 | 16 | 1. Execute any available init scripts located in `/etc/init`. 17 | 2. If a command is passed to the container, fork and start the command in the background. 18 | 3. Execute [`s6-svscan`][s6-svscan], which spawns and supervises all configured services. 19 | 20 | ### Init process and PID 1 21 | The init process always executes `s6-svscan` as PID 1, which was written to handle the responsibilities that are expected of PID 1. See [Docker and the PID 1 zombie reaping problem](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/) for an excellent explanation of why this is important. 22 | 23 | ### Init scripts 24 | This image supports running one-time scripts at boot time. Any file marked as executable in the `/etc/init` directory or a subdirectory will be executed before services are started. These scripts can be added during the build process by a downstream image to ensure a script is run without overwriting the CMD directive. 25 | 26 | ## Services 27 | This image runs services as background processes with automatic and proper process supervision with minimal overhead. You can even run a foreground service by giving Docker a CMD to run, and all services in the container will still run in the background without interrupting the foreground process. 28 | 29 | By default the image is mostly empty and has only a few core services. To add a service, just add a script at `/etc/service/{name}/run` that executes the desired program _in the foreground_. Typically service-like programs will have a "no daemonize" flag to prevent forking and daemonizing. For example, to create a service for NGINX, you could put the following in `/etc/service/nginx/run`: 30 | 31 | ```sh 32 | #!/bin/sh 33 | exec nginx -g 'daemon off;' 34 | ``` 35 | 36 | By default services will be restarted if they exit or crash. For primary services this is not usually the desired behavior. To make sure the Docker container stops when a critial service dies, add a `finish` script for the service at `/etc/service/{name}/finish` that executes `halt`: 37 | 38 | ```sh 39 | #!/bin/sh 40 | exec halt 41 | ``` 42 | 43 | ## Cron jobs 44 | You can also configure scripts to be run at regular intervals as cron jobs. This image enables the [cron system built in to Alpine Linux](https://wiki.alpinelinux.org/wiki/Alpine_Linux:FAQ#My_cron_jobs_don.27t_run.3F) as a service. Scripts can be placed in `/etc/periodic/{15min,hourly,daily,weekly,monthly}` and it will be run at the interval specified by the directory name. 45 | 46 | ## Logging 47 | Docker encourages the use of stdout and stderr as the means of capturing logs from a container. These logs can be hooked up to logging drivers and can be put to much better use _outside_ the container rather than _inside_. As a result, output logs from both syslog and all running services are all aggregated and redirected to stdout and stderr. 48 | 49 | ## Runtime configuration 50 | Some of the behavior of the init process can be customized at runtime via environment variables. 51 | 52 | - `INIT_ENABLED_SERVICES`: Comma-delimited list of services to enable. This is useful for providing services that are disabled by default, but can be optionally enabled when a container is run. 53 | - `INIT_DISABLED_SERVICES`: Opposite of `INIT_ENABLED_SERVICES`. A comma-delimited list of services to disable. 54 | 55 | ## Utility commands 56 | Some custom commands are included for controlling services, the container state, or for just making working with common tasks easier: 57 | 58 | - `envsubst`: Piping command that replaces patterns of the form `${ENV_NAME}` with the value of the `ENV_NAME` environment variable. Useful for making templated config files. 59 | - `service`: Helper script for starting and stopping services. 60 | - `shutdown`: Shuts down all services and then terminates the container. 61 | - `halt`: Like `shutdown`, but causes the container to return a failure exit code. 62 | 63 | 64 | [alpine]: https://www.alpinelinux.org 65 | [docker]: https://www.docker.com 66 | [phusion-baseimage]: https://github.com/phusion/baseimage-docker 67 | [s6]: http://skarnet.org/software/s6/ 68 | [s6-svscan]: http://skarnet.org/software/s6/s6-svscan.html 69 | -------------------------------------------------------------------------------- /base/root/bin/envsubst: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | # Simple environment expander utility, similar to Gettext's envsubst utility. 3 | BEGIN { 4 | for (i in ARGV) { 5 | if (match(ARGV[i], "^--?h(elp)?$")) { 6 | print "Usage: envsubst < template > output"; 7 | print; 8 | print "Expands environment variables of the form ${NAME} to the variable value from"; 9 | print "standard input to standard output."; 10 | exit; 11 | } 12 | } 13 | } 14 | 15 | { 16 | while (match($0, "[$]{[^}]*}")) { 17 | var = substr($0, RSTART + 2, RLENGTH - 3); 18 | gsub("[$]{"var"}", ENVIRON[var], $0); 19 | } 20 | print; 21 | } 22 | -------------------------------------------------------------------------------- /base/root/etc/init/srv: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | chgrp -R srv /srv 3 | chmod -R g+rw /srv 4 | -------------------------------------------------------------------------------- /base/root/etc/service/.s6-svscan/crash: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | false 3 | -------------------------------------------------------------------------------- /base/root/etc/service/.s6-svscan/finish: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -S0 2 | test "$1" != halt 3 | -------------------------------------------------------------------------------- /base/root/etc/service/cmdline/down: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sagebind/dockerfiles/cf6419ff5ce62301d3f27ae9d4712afafd326554/base/root/etc/service/cmdline/down -------------------------------------------------------------------------------- /base/root/etc/service/cmdline/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec shutdown 3 | -------------------------------------------------------------------------------- /base/root/etc/service/cmdline/nosetsid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sagebind/dockerfiles/cf6419ff5ce62301d3f27ae9d4712afafd326554/base/root/etc/service/cmdline/nosetsid -------------------------------------------------------------------------------- /base/root/etc/service/cmdline/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Wait for all other services to be up. 3 | for service in /etc/service/*; do 4 | if [ ! -f $service/down ]; then 5 | s6-svwait -u $service 6 | fi 7 | done 8 | 9 | # Change to the user working directory. 10 | cd $(cat /run/pwd) 11 | 12 | # Execute the user command. 13 | IFS=$'\n' 14 | exec s6-setsid -g -q $(cat /run/cmdline) 15 | -------------------------------------------------------------------------------- /base/root/etc/service/crond/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec crond -f -d ${CRON_LOG_LEVEL-9} 3 | -------------------------------------------------------------------------------- /base/root/etc/service/syslog/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec syslogd -n -l ${SYSLOG_LEVEL-6} -O - 3 | -------------------------------------------------------------------------------- /base/root/sbin/halt: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | redirfd -w 2 /dev/null s6-svscanctl -s -t /etc/service 3 | -------------------------------------------------------------------------------- /base/root/sbin/init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | # Run init scripts. 5 | find /etc/init -type f -perm -300 -exec {} \; 6 | 7 | # If a user command is given, save it and enable the cmdline service. 8 | if [ $# -ne 0 ]; then 9 | printf '%s\n' "$@" > /run/cmdline 10 | pwd > /run/pwd 11 | rm /etc/service/cmdline/down 12 | fi 13 | 14 | # Enable services listed in $INIT_ENABLED_SERVICES. 15 | if [ -n "${INIT_ENABLED_SERVICES-}" ]; then 16 | IFS="," 17 | for service in $INIT_ENABLED_SERVICES; do 18 | rm /etc/service/$service/down || true 19 | done 20 | unset IFS 21 | fi 22 | 23 | # Disable services listed in $INIT_DISABLED_SERVICES. 24 | if [ -n "${INIT_DISABLED_SERVICES-}" ]; then 25 | IFS="," 26 | for service in $INIT_DISABLED_SERVICES; do 27 | touch /etc/service/$service/down 28 | done 29 | unset IFS 30 | fi 31 | 32 | # Start process manager. 33 | exec s6-svscan -S -t0 /etc/service 34 | -------------------------------------------------------------------------------- /base/root/sbin/service: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | SERVICE_DIR=/etc/service/$1 3 | COMMAND=$2 4 | 5 | if test ! -d $SERVICE_DIR; then 6 | echo "Service not found: $1" >&2 7 | exit 1 8 | fi 9 | 10 | case $COMMAND in 11 | restart) 12 | s6-svc -d -wd $SERVICE_DIR 13 | s6-svc -u $SERVICE_DIR 14 | ;; 15 | start) 16 | s6-svc -u $SERVICE_DIR 17 | ;; 18 | status) 19 | echo "Service: $SERVICE_DIR" 20 | echo " Status: $(s6-svstat $SERVICE_DIR)" 21 | ;; 22 | stop) 23 | s6-svc -d $SERVICE_DIR 24 | ;; 25 | *) 26 | echo "Unknown command: $COMMAND" >&2 27 | exit 1 28 | ;; 29 | esac 30 | -------------------------------------------------------------------------------- /base/root/sbin/shutdown: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | redirfd -w 2 /dev/null s6-svscanctl -t /etc/service 3 | -------------------------------------------------------------------------------- /digitalocean-ddns/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add bind-tools curl jq 5 | 6 | COPY ddns.sh /etc/periodic/hourly/ddns 7 | -------------------------------------------------------------------------------- /digitalocean-ddns/ddns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z $DIGITALOCEAN_TOKEN ]; then 3 | echo "DIGITALOCEAN DDNS: DIGITALOCEAN_TOKEN is not set" >&2 4 | exit 1 5 | fi 6 | if [ -z $DOMAIN ]; then 7 | echo "DIGITALOCEAN DDNS: DOMAIN is not set" >&2 8 | exit 1 9 | fi 10 | if [ -z $RECORD ]; then 11 | echo "DIGITALOCEAN DDNS: RECORD is not set" >&2 12 | exit 1 13 | fi 14 | 15 | IP_FILE=/etc/public_ip 16 | RECORDS_API=https://api.digitalocean.com/v2/domains/$DOMAIN/records 17 | PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com) 18 | echo "DIGITALOCEAN DDNS: IP address is $PUBLIC_IP" 19 | 20 | if [ -f $IP_FILE ]; then 21 | PREVIOUS_IP=$(<$IP_FILE) 22 | 23 | if [ $PUBLIC_IP = $PREVIOUS_IP ]; then 24 | echo "DIGITALOCEAN DDNS: IP address unchanged" 25 | exit 26 | fi 27 | fi 28 | 29 | echo "DIGITALOCEAN DDNS: IP address changed" 30 | echo $PUBLIC_IP > $IP_FILE 31 | 32 | RECORD_ID=$(curl -s -X GET \ 33 | -H "Content-Type: application/json" \ 34 | -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ 35 | $RECORDS_API | jq ".domain_records[] | select(.name == \"$RECORD\") | .id") 36 | PAYLOAD='{"type":"A","name":"'$RECORD'","data":"'$PUBLIC_IP'"}' 37 | 38 | if [ -z $RECORD_ID ]; then 39 | echo "DIGITALOCEAN DDNS: Existing DNS record not found, creating a new one" 40 | 41 | curl -s -X POST \ 42 | -H "Content-Type: application/json" \ 43 | -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ 44 | -d $PAYLOAD \ 45 | $RECORDS_API > /dev/null 46 | else 47 | echo "DIGITALOCEAN DDNS: Updating existing DNS record id $RECORD_ID" 48 | 49 | # curl -s -X PUT \ 50 | # -H "Content-Type: application/json" \ 51 | # -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ 52 | # -d $PAYLOAD \ 53 | # $RECORDS_API/$RECORD_ID > /dev/null 54 | fi 55 | -------------------------------------------------------------------------------- /gitweb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/nginx:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add fcgiwrap git-gitweb highlight perl-cgi perl-cgi-fast perl-fcgi-procmanager 5 | 6 | COPY root / 7 | 8 | VOLUME /var/git 9 | -------------------------------------------------------------------------------- /gitweb/root/etc/gitweb.conf: -------------------------------------------------------------------------------- 1 | $GIT = "/usr/bin/git"; 2 | $projectroot = "/var/git"; 3 | $git_temp = "/tmp"; 4 | 5 | $feature{'avatar'}{'default'} = ['gravatar']; 6 | $feature{'highlight'}{'default'} = [1]; 7 | $feature{'pathinfo'}{'default'} = [1]; 8 | -------------------------------------------------------------------------------- /gitweb/root/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | client_max_body_size 100M; 6 | 7 | # requests that need to go to git-http-backend 8 | location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-upload-pack)$ { 9 | root /var/git; 10 | fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock; 11 | fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; 12 | fastcgi_param PATH_INFO $uri; 13 | fastcgi_param GIT_PROJECT_ROOT /var/git; 14 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; 15 | fastcgi_param REMOTE_USER $remote_user; 16 | include fastcgi_params; 17 | } 18 | 19 | location / { 20 | root /usr/share/gitweb; 21 | include /etc/nginx/mime.types; 22 | 23 | location ~ \.css { 24 | add_header Content-Type text/css; 25 | } 26 | 27 | location ~ \.js { 28 | add_header Content-Type application/javascript; 29 | } 30 | 31 | try_files $uri @gitweb; 32 | } 33 | 34 | location @gitweb { 35 | fastcgi_pass 127.0.0.1:9002; 36 | fastcgi_param PATH_INFO $uri; 37 | fastcgi_param GITWEB_CONFIG /etc/gitweb.conf; 38 | include fastcgi_params; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gitweb/root/etc/service/fcgiwrap/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p /var/run/fcgiwrap 3 | chown nginx:daemon /var/run/fcgiwrap 4 | exec s6-setuidgid nginx fcgiwrap -s unix:/var/run/fcgiwrap/fcgiwrap.sock 5 | -------------------------------------------------------------------------------- /gitweb/root/etc/service/gitweb/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export FCGI_SOCKET_PATH=127.0.0.1:9002 3 | exec s6-setuidgid nginx /usr/share/gitweb/gitweb.cgi --fastcgi 4 | -------------------------------------------------------------------------------- /matomo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/php-nginx:latest 2 | LABEL maintainer="Stephen Coakley " 3 | 4 | ARG VERSION=latest 5 | 6 | RUN apk --no-cache add \ 7 | php7-ctype \ 8 | php7-dom \ 9 | php7-gd \ 10 | php7-iconv \ 11 | php7-pdo_mysql \ 12 | php7-simplexml \ 13 | wget && \ 14 | wget -q http://builds.piwik.org/piwik-${VERSION}.tar.gz && \ 15 | tar -xzf piwik-${VERSION}.tar.gz && \ 16 | rm piwik-${VERSION}.tar.gz ./*.html && \ 17 | mv piwik/* . && \ 18 | rm -r piwik && \ 19 | wget -qO - https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz | tar -xzf - && \ 20 | mv GeoLite2-City*/GeoLite2-City.mmdb misc/GeoLite2-City.mmdb && \ 21 | rm -r GeoLite2-City* 22 | 23 | COPY root / 24 | -------------------------------------------------------------------------------- /matomo/README.md: -------------------------------------------------------------------------------- 1 | # Matomo 2 | A lightweight image for [Matomo], a popular open-source analytics platform. Includes [NGINX] as a web server, PHP 7, and the latest Matomo version. Matomo jobs and tasks are automatically run in the container as a cron job, so no extra setup for archiving is needed. 3 | 4 | ## Usage 5 | To set up a working Matomo container, you will need to provide a MySQL database. The best way is to create a separate container for the database and then link it to the Matomo container, but you can also use a remote database. 6 | 7 | The database can be configured using environment variables when the container is created. The following variables are respected: 8 | 9 | - `DB_HOST`: Host name or IP address of the MySQL server. Required. 10 | - `DB_PORT`: Override MySQL server port. Optional. 11 | - `DB_USERNAME`: MySQL user for Matomo to use. Required. 12 | - `DB_PASSWORD`: Password for the MySQL user. Required. 13 | - `DB_NAME`: Name of the database to connect to. Defaults to `matomo`. Optional. 14 | - `DB_PREFIX`: A string that the Matomo table names are prefixed with. Default is `matomo_`. Optional. 15 | 16 | 17 | [matomo]: https://matomo.org 18 | [nginx]: http://nginx.org 19 | -------------------------------------------------------------------------------- /matomo/root/etc/config.ini.php.template: -------------------------------------------------------------------------------- 1 | ; DO NOT REMOVE THIS LINE 2 | ; file automatically generated or modified by Piwik; you can manually override the default values in global.ini.php by redefining them in this file. 3 | [database] 4 | host = "${DB_HOST}" 5 | port = ${DB_PORT} 6 | username = "${DB_USERNAME}" 7 | password = "${DB_PASSWORD}" 8 | dbname = "${DB_NAME}" 9 | tables_prefix = "${DB_PREFIX}" 10 | adapter = "PDO\MYSQL" 11 | type = "InnoDB" 12 | schema = "Mysql" 13 | -------------------------------------------------------------------------------- /matomo/root/etc/init/matomo-generate-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | CONFIG_FILE=/srv/www/config/config.ini.php 3 | TEMPLATE=/etc/config.ini.php.template 4 | 5 | if [ -z "$DB_PORT" ]; then 6 | export DB_PORT=3306 7 | fi 8 | 9 | if [ -z "$DB_NAME" ]; then 10 | export DB_NAME=matomo 11 | fi 12 | 13 | if [ -z "$DB_PREFIX" ]; then 14 | export DB_PREFIX=matomo_ 15 | fi 16 | 17 | envsubst < $TEMPLATE > $CONFIG_FILE 18 | chown nginx:nginx $CONFIG_FILE 19 | -------------------------------------------------------------------------------- /matomo/root/etc/periodic/hourly/matomo-archive: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec php7 /srv/www/console core:archive 3 | -------------------------------------------------------------------------------- /mkdocs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk --no-cache add python3 && \ 3 | pip3 install mkdocs mkdocs-material 4 | VOLUME ["/src", "/build"] 5 | WORKDIR /src 6 | ENTRYPOINT ["/usr/bin/mkdocs"] 7 | CMD ["build", "--site-dir", "/build"] 8 | -------------------------------------------------------------------------------- /mkdocs/README.md: -------------------------------------------------------------------------------- 1 | # MkDocs 2 | MkDocs builder in a lightweight Docker image. 3 | 4 | You can use this image to build your static site without installing any dependencies on your build system: 5 | 6 | ```sh 7 | docker run -it --rm -v /path/to/source:/src -v /path/to/output:/build --user=$UID:$GID sagebind/mkdocs 8 | ``` 9 | -------------------------------------------------------------------------------- /nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add nginx && \ 5 | addgroup nginx srv && \ 6 | mv /var/lib/nginx/html /srv/www && \ 7 | chown -R nginx:srv /srv/www 8 | 9 | COPY root / 10 | 11 | WORKDIR /srv/www 12 | 13 | EXPOSE 80 443 14 | -------------------------------------------------------------------------------- /nginx/README.md: -------------------------------------------------------------------------------- 1 | # sagebind/nginx 2 | Lightweight, service-oriented [NGINX] image. 3 | 4 | Hosting simple static content: 5 | 6 | ```sh 7 | docker run --name some-nginx -v /some/content:/srv:ro -d sagebind/nginx 8 | ``` 9 | 10 | The default server configuration is located at `/etc/nginx/conf.d/default.conf`. To customize the http server config, it is recommended that you override this file with your own. For more advanced configuration, you can provide your own `nginx.conf` and copy it to `/etc/nginx/nginx.conf`, which will override all existing settings. 11 | 12 | 13 | [nginx]: http://nginx.org 14 | -------------------------------------------------------------------------------- /nginx/root/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | 6 | location / { 7 | root /srv/www; 8 | index index.html index.htm; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /nginx/root/etc/nginx/gzip: -------------------------------------------------------------------------------- 1 | gzip on; 2 | gzip_proxied expired no-cache no-store private auth; 3 | gzip_types application/javascript application/x-javascript application/xml image/svg+xml text/css text/plain text/xml; 4 | gzip_vary on; 5 | -------------------------------------------------------------------------------- /nginx/root/etc/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes auto; 3 | error_log stderr; 4 | pid /run/nginx.pid; 5 | 6 | events { 7 | worker_connections 1024; 8 | multi_accept on; 9 | } 10 | 11 | http { 12 | access_log /dev/stdout; 13 | 14 | sendfile on; 15 | 16 | include /etc/nginx/mime.types; 17 | default_type application/octet-stream; 18 | 19 | include /etc/nginx/prelude.d/*.conf; 20 | include /etc/nginx/conf.d/*.conf; 21 | } 22 | -------------------------------------------------------------------------------- /nginx/root/etc/service/nginx/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /nginx/root/etc/service/nginx/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec nginx -g 'daemon off;' 3 | -------------------------------------------------------------------------------- /openssh/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base 2 | LABEL maintainer="Stephen Coakley " 3 | 4 | RUN apk --no-cache add openssh 5 | 6 | COPY root / 7 | 8 | EXPOSE 22 9 | -------------------------------------------------------------------------------- /openssh/README.md: -------------------------------------------------------------------------------- 1 | # OpenSSH 2 | A tiny OpenSSH server image. 3 | 4 | You can provide your own SSH host keys as a volume in `/etc/ssh`. If no host keys are found on startup they will be generated. 5 | -------------------------------------------------------------------------------- /openssh/root/etc/init/sshd-keygen: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then 3 | ssh-keygen -A 4 | fi 5 | -------------------------------------------------------------------------------- /openssh/root/etc/service/sshd/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /openssh/root/etc/service/sshd/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec /usr/sbin/sshd -De 3 | -------------------------------------------------------------------------------- /php-nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/nginx:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add \ 5 | php7 \ 6 | php7-ctype \ 7 | php7-dom \ 8 | php7-fpm \ 9 | php7-json \ 10 | php7-mbstring \ 11 | php7-openssl \ 12 | php7-phar \ 13 | php7-posix \ 14 | php7-session \ 15 | php7-simplexml \ 16 | php7-sockets \ 17 | php7-xml \ 18 | php7-xmlreader \ 19 | php7-xmlwriter \ 20 | php7-zlib 21 | 22 | COPY root / 23 | -------------------------------------------------------------------------------- /php-nginx/README.md: -------------------------------------------------------------------------------- 1 | # sagebind/php-nginx 2 | A lightweight PHP application server with PHP 7, PHP-FPM and [NGINX]. 3 | 4 | This image is designed to be a minimal, stable environment for running standard PHP applications behind a web server in a single container. 5 | 6 | Add the root of the web application to `/var/www`, either as a volume or by creating an image based on this one with the application files copied into it. 7 | 8 | 9 | [nginx]: http://nginx.org 10 | -------------------------------------------------------------------------------- /php-nginx/root/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | 6 | root /srv/www; 7 | 8 | location / { 9 | index index.php; 10 | } 11 | 12 | location ~ \.php$ { 13 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 14 | fastcgi_pass localhost:9000; 15 | include fastcgi_params; 16 | fastcgi_param SCRIPT_FILENAME $request_filename; 17 | fastcgi_read_timeout 1000; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /php-nginx/root/etc/php7/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | pid = /run/php-fpm7.pid 3 | error_log = /dev/stderr 4 | daemonize = no 5 | 6 | [www] 7 | user = nginx 8 | group = nginx 9 | listen = 127.0.0.1:9000 10 | catch_workers_output = yes 11 | clear_env = no 12 | access.log = /dev/stdout 13 | pm = dynamic 14 | pm.max_children = 5 15 | pm.start_servers = 2 16 | pm.min_spare_servers = 1 17 | pm.max_spare_servers = 3 18 | -------------------------------------------------------------------------------- /php-nginx/root/etc/service/php-fpm7/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /php-nginx/root/etc/service/php-fpm7/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec php-fpm7 --nodaemonize 3 | -------------------------------------------------------------------------------- /php-nginx/root/srv/www/index.php: -------------------------------------------------------------------------------- 1 | 3 | 4 | RUN apk --no-cache add \ 5 | php7 \ 6 | php7-json \ 7 | php7-mbstring \ 8 | php7-openssl \ 9 | php7-phar \ 10 | php7-posix \ 11 | php7-session \ 12 | php7-sockets \ 13 | php7-zlib 14 | -------------------------------------------------------------------------------- /pritunl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base:3.6 2 | 3 | ARG VERSION=1.28.1545.95 4 | RUN apk --no-cache add bridge-utils bzr ca-certificates curl mongodb net-tools procps python py2-pip openssl openvpn && \ 5 | 6 | # Build time dependencies 7 | apk --no-cache add --virtual .build git go libffi-dev linux-headers musl-dev openssl-dev py-setuptools python-dev && \ 8 | 9 | export GOPATH=/go && \ 10 | go get github.com/pritunl/pritunl-dns && \ 11 | go get github.com/pritunl/pritunl-monitor && \ 12 | go get github.com/pritunl/pritunl-web && \ 13 | mv /go/bin/* /usr/local/bin/ && \ 14 | 15 | curl -L https://github.com/pritunl/pritunl/archive/$VERSION.tar.gz | tar zxf - && \ 16 | cd pritunl-$VERSION && \ 17 | python setup.py build && \ 18 | pip install -r requirements.txt && \ 19 | python setup.py install && \ 20 | 21 | # Cleanup 22 | cd / && \ 23 | rm -rf /go /pritunl-$VERSION && \ 24 | apk --no-cache del .build 25 | 26 | COPY etc /etc 27 | VOLUME /data 28 | EXPOSE 80 443 1194 29 | -------------------------------------------------------------------------------- /pritunl/etc/init/tun: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p /dev/net 3 | if [ ! -c /dev/net/tun ]; then 4 | mknod /dev/net/tun c 10 200 5 | fi 6 | -------------------------------------------------------------------------------- /pritunl/etc/service/mongodb/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p /data/db 3 | exec mongod --dbpath /data/db 4 | -------------------------------------------------------------------------------- /pritunl/etc/service/pritunl/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec halt 3 | -------------------------------------------------------------------------------- /pritunl/etc/service/pritunl/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pritunl set-mongodb mongodb://localhost:27017/pritunl 3 | exec pritunl start 4 | -------------------------------------------------------------------------------- /prosody/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/nginx 2 | 3 | ARG PROSODY_NIGHTLY=1nightly435 4 | ENV HOST=localhost 5 | 6 | # Install Prosody server. 7 | RUN apk --no-cache add ca-certificates curl libevent libidn lua5.1-dbi-sqlite3 lua5.1-expat lua5.1-filesystem \ 8 | lua5.1-libs lua5.1-sec openssl && \ 9 | 10 | # Build time dependencies. 11 | apk --no-cache add --virtual .build build-base git libevent-dev libidn-dev linux-headers lua5.1-dev luarocks5.1 \ 12 | openssl-dev && \ 13 | 14 | # Build Prosody nightly. 15 | curl https://prosody.im/nightly/0.10/build435/prosody-0.10-${PROSODY_NIGHTLY}.tar.gz | tar xzf - && \ 16 | cd prosody-0.10-${PROSODY_NIGHTLY} && \ 17 | ./configure \ 18 | --ostype=linux \ 19 | --prefix=/usr \ 20 | --sysconfdir=/etc/prosody \ 21 | --with-lua=/usr \ 22 | --with-lua-lib=/usr/lib \ 23 | --with-lua-include=/usr/include \ 24 | --add-cflags="-DWITHOUT_MALLINFO" \ 25 | --no-example-certs && \ 26 | make install && \ 27 | addgroup -S prosody && \ 28 | adduser -S -D -h /var/lib/prosody -s /sbin/nologin -G prosody -g "Prosody XMPP Server" prosody && \ 29 | 30 | # Build other required Lua native modules. 31 | luarocks-5.1 install luabitop && \ 32 | luarocks-5.1 install luaevent && \ 33 | 34 | # Cleanup 35 | cd .. && \ 36 | rm -rf prosody-0.10-${PROSODY_NIGHTLY} && \ 37 | apk --no-cache del .build 38 | 39 | # Install community modules. 40 | RUN curl https://hg.prosody.im/prosody-modules/archive/tip.tar.gz | tar xzf - && \ 41 | cd prosody-modules-* && \ 42 | mkdir -p /srv/prosody/modules && \ 43 | cp mod_admin_message/*.lua /srv/prosody/modules && \ 44 | cp mod_csi/*.lua /srv/prosody/modules && \ 45 | cp mod_filter_chatstates/*.lua /srv/prosody/modules && \ 46 | cp mod_smacks/*.lua /srv/prosody/modules && \ 47 | cp mod_throttle_presence/*.lua /srv/prosody/modules && \ 48 | cd .. && rm -r prosody-modules-* 49 | 50 | # Install web frontend. 51 | RUN curl -L -o inverse.min.js https://github.com/jcbrand/converse.js/releases/download/v3.2.1/inverse.min.js && \ 52 | curl -L https://github.com/jcbrand/converse.js/archive/v3.2.1.tar.gz | tar xzf - && \ 53 | mv converse.js-3.2.1/css/inverse.css ./ && \ 54 | rm -r converse.js-3.2.1 55 | 56 | COPY etc /etc 57 | COPY www /srv/www 58 | 59 | VOLUME /etc/certs /data 60 | 61 | EXPOSE 5222 5269 62 | -------------------------------------------------------------------------------- /prosody/etc/init/prosody: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p /var/run/prosody 3 | chown -R prosody:prosody /data /var/run/prosody 4 | 5 | 6 | if [ ! -f /etc/certs/$HOST.key ]; then 7 | prosodyctl cert generate $HOST 8 | mv /var/lib/prosody/*.cnf /etc/certs 9 | mv /var/lib/prosody/*.crt /etc/certs 10 | mv /var/lib/prosody/*.key /etc/certs 11 | fi 12 | -------------------------------------------------------------------------------- /prosody/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name localhost; 4 | 5 | location /http-bind/ { 6 | proxy_pass http://localhost:5280/http-bind/; 7 | proxy_buffering off; 8 | tcp_nodelay on; 9 | } 10 | 11 | location / { 12 | root /srv/www; 13 | index index.html; 14 | 15 | error_page 405 =200 $uri; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /prosody/etc/prosody/prosody.cfg.lua: -------------------------------------------------------------------------------- 1 | -- Core configuration. 2 | daemonize = false 3 | pidfile = "/var/run/prosody/prosody.pid" 4 | use_libevent = true 5 | plugin_paths = {"/srv/prosody/modules"} 6 | log = { 7 | debug = nil; 8 | info = "*console"; 9 | } 10 | 11 | -- Set admin accounts. 12 | if os.getenv("ADMINS") then 13 | local jids = {} 14 | for jid in string.gmatch(os.getenv("ADMINS"), "([^,]+)") do 15 | table.insert(jids, jid) 16 | end 17 | admins = jids 18 | else 19 | admins = {} 20 | end 21 | 22 | modules_enabled = { 23 | "admin_adhoc"; -- administration via an XMPP client that supports ad-hoc commands 24 | "admin_message"; -- admin console over XMPP 25 | "announce"; -- Send announcement to all online users 26 | "blocklist"; 27 | "bosh"; -- support for web clients 28 | "carbons"; -- live multi device syncing 29 | "csi"; -- client state indication for mobile 30 | "dialback"; -- s2s dialback support 31 | "disco"; -- Service discovery 32 | "filter_chatstates"; -- csi chat states 33 | "groups"; -- Shared roster support 34 | "mam"; -- message archiving 35 | "pep"; -- Enables users to publish their mood, activity, playing music and more 36 | "ping"; -- Replies to XMPP pings with pongs 37 | "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. 38 | "private"; -- Private XML storage (for room bookmarks, etc.) 39 | "register"; -- Allow users to register on this server using a client and change passwords 40 | "roster"; -- Allow users to have a roster. Recommended ;) 41 | "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. 42 | "smacks"; -- unstable client connection support, for users out in the boonies 43 | "throttle_presence"; -- csi presence 44 | "time"; -- Let others know the time here on this server 45 | "tls"; -- secure TLS on c2s/s2s connections 46 | "uptime"; -- Report how long server has been running 47 | "vcard"; -- Allow users to set vCards 48 | "version"; -- Replies to server version requests 49 | } 50 | 51 | -- Configure security and SSL/TLS encryption. 52 | authentication = "internal_hashed" 53 | allow_registration = (os.getenv("ALLOW_REGISTRATION") == "true") 54 | c2s_require_encryption = true 55 | s2s_require_encryption = true 56 | s2s_secure_auth = false 57 | s2s_secure_domains = {"jabber.org"} 58 | https_certificate = "/etc/certs/"..os.getenv("HOST")..".crt" 59 | ssl = { 60 | key = "/etc/certs/"..os.getenv("HOST")..".key"; 61 | certificate = "/etc/certs/"..os.getenv("HOST")..".crt"; 62 | } 63 | 64 | -- Configure storage backend. 65 | default_storage = "sql" 66 | sql = { 67 | driver = "SQLite3"; 68 | database = "/data/prosody.sqlite"; 69 | } 70 | storage = { 71 | archive2 = "sql"; 72 | } 73 | 74 | -- Preserve message history forever. 75 | archive_expires_after = "never" 76 | 77 | -- Define the virtual host. 78 | VirtualHost(os.getenv("HOST")) 79 | 80 | ---Set up a MUC (multi-user chat) room server on conference.example.com: 81 | if os.getenv("MUC_HOST") then 82 | Component(os.getenv("MUC_HOST"))("muc") 83 | end 84 | 85 | -- Set up admin console address. 86 | Component("console@"..os.getenv("HOST"))("admin_message") 87 | -------------------------------------------------------------------------------- /prosody/etc/service/prosody/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec halt 3 | -------------------------------------------------------------------------------- /prosody/etc/service/prosody/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export __FLUSH_LOG=yes 3 | exec s6-setuidgid prosody prosody 4 | -------------------------------------------------------------------------------- /prosody/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | XMPP 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /remote-docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base 2 | RUN apk --no-cache add openssh-client 3 | COPY --from=docker:latest /usr/local/bin/docker /usr/local/bin/docker 4 | COPY root / 5 | -------------------------------------------------------------------------------- /remote-docker/README.md: -------------------------------------------------------------------------------- 1 | # remote-docker 2 | Connect to a Docker engine on a remote host using SSH and then run commands against it. 3 | 4 | This container will allow you to connect to a remote Docker engine with an SSH key by using SSH port forwarding. This is simpler and more secure than exposing the Docker socket over TLS and maintaining separate Docker TLS certificates. 5 | -------------------------------------------------------------------------------- /remote-docker/root/etc/init/docker-tunnel: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | mkdir -p /var/run 5 | exec ssh -fnNT \ 6 | -o 'ExitOnForwardFailure yes' \ 7 | -o 'StrictHostKeyChecking no' \ 8 | -i /var/key \ 9 | -L /var/run/docker.sock:/var/run/docker.sock \ 10 | "${REMOTE_USER-root}@$REMOTE_HOST" 11 | -------------------------------------------------------------------------------- /reverse-proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/nginx:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add dnsmasq && \ 5 | rm /etc/nginx/conf.d/default.conf 6 | 7 | COPY root / 8 | -------------------------------------------------------------------------------- /reverse-proxy/README.md: -------------------------------------------------------------------------------- 1 | # Reverse proxy 2 | A dynamic, config-free [NGINX] reverse proxy server. 3 | 4 | ## Usage 5 | This reverse proxy does not require priveleged access to the Docker daemon. Instead, it dynamically determines upstream server names by matching container names to domain names. The rule matches any container name ending in `.local`. For example, `foobar.local` would match `foobar.com`, `foobar.net`, `www.foobar.com`, etc... 6 | 7 | Desiged to work well with Docker networks. Just add the reverse proxy container to the same network as your public-facing containers and their domain names will be automatically resolved and proxied. Adding or removing a container also works dynamically and the proxy server will automatically pick up the changes without needing a restart. 8 | 9 | 10 | [nginx]: http://nginx.org 11 | -------------------------------------------------------------------------------- /reverse-proxy/root/etc/nginx/prelude.d/reverse-proxy.conf: -------------------------------------------------------------------------------- 1 | resolver 127.0.0.1:53; 2 | 3 | include gzip; 4 | include proxy_cache; 5 | 6 | proxy_set_header Host $host; 7 | add_header X-Forwarded-For $remote_addr; 8 | add_header X-Cache-Status $upstream_cache_status; 9 | 10 | server { 11 | listen 80; 12 | listen [::]:80; 13 | 14 | server_name "~^(www\.)?(?[\w\.]+)\.\w+$"; 15 | 16 | location / { 17 | proxy_pass http://$app.local:80; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /reverse-proxy/root/etc/nginx/proxy_cache: -------------------------------------------------------------------------------- 1 | proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m max_size=2g inactive=60m use_temp_path=off; 2 | proxy_buffering on; 3 | proxy_http_version 1.1; 4 | proxy_cache cache; 5 | 6 | proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; 7 | proxy_cache_revalidate on; 8 | proxy_cache_valid 200 302 30m; 9 | proxy_cache_valid 404 1m; 10 | proxy_cache_bypass $http_x_update; 11 | proxy_cache_bypass $http_cache_control; 12 | -------------------------------------------------------------------------------- /reverse-proxy/root/etc/service/dnsmasq/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec dnsmasq --keep-in-foreground --user=root --no-negcache 3 | -------------------------------------------------------------------------------- /seafile/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/nginx 2 | 3 | # Install runtime dependencies. 4 | RUN apk --no-cache add bash ca-certificates curl glib jansson libarchive libevent libuuid openssl python py2-pip \ 5 | py-chardet py-dateutil py-flup py-gevent py-gunicorn py-imaging py-numpy py-pyldap py-requests py-tz \ 6 | sqlite util-linux 7 | 8 | ENV SERVER_NAME=seafile \ 9 | FILESERVER_PORT=8082 \ 10 | CCNET_PORT=10001 \ 11 | SEAFILE_PORT=12001 \ 12 | CCNET_CONF_DIR=/srv/ccnet \ 13 | SEAFILE_CENTRAL_CONF_DIR=/srv/conf \ 14 | SEAFILE_CONF_DIR=/data \ 15 | SEAHUB_LOG_DIR=/srv/logs \ 16 | PYTHONPATH=/srv/seafile-server/seahub:/srv/seafile-server/seahub/thirdpart:/usr/local/lib/python2.7/site-packages 17 | 18 | ARG SEAFILE_VERSION=6.2.3 19 | RUN apk --no-cache add --virtual .build autoconf automake bsd-compat-headers build-base cmake curl-dev fuse-dev \ 20 | glib-dev intltool jansson-dev jpeg-dev libarchive-dev libevent-dev libpng-dev libtool musl-dev openssl-dev \ 21 | python-dev sqlite-dev util-linux-dev vala zlib-dev && \ 22 | 23 | # Download Seafile source bundles and dependencies 24 | mkdir /src && cd /src && \ 25 | curl -L https://github.com/criticalstack/libevhtp/archive/1.1.6.tar.gz | tar xzf - && \ 26 | curl -L https://github.com/haiwen/libsearpc/archive/v3.1-latest.tar.gz | tar xzf - && \ 27 | curl -L https://github.com/haiwen/seafile-server/archive/v${SEAFILE_VERSION}-server.tar.gz | tar xzf - && \ 28 | curl -L https://github.com/haiwen/ccnet-server/archive/v${SEAFILE_VERSION}-server.tar.gz | tar xzf - && \ 29 | curl -L https://github.com/haiwen/seahub/archive/v${SEAFILE_VERSION}-server.tar.gz | tar xzf - && \ 30 | 31 | # Compile and install libevhtp 32 | cd /src/libevhtp-1.1.6 && \ 33 | cmake -DEVHTP_DISABLE_SSL=ON -DEVHTP_BUILD_SHARED=OFF . && \ 34 | make install && \ 35 | 36 | # Compile and install libsearpc 37 | cd /src/libsearpc-3.1-latest && \ 38 | ./autogen.sh && \ 39 | ./configure && \ 40 | make install && \ 41 | 42 | # Compile and install ccnet 43 | cd /src/ccnet-server-${SEAFILE_VERSION}-server && \ 44 | ./autogen.sh && \ 45 | ./configure --without-mysql --without-postgresql && \ 46 | make install && \ 47 | 48 | # Compile and install seafile 49 | cd /src/seafile-server-${SEAFILE_VERSION}-server && \ 50 | export CFLAGS="-I/usr/include/evhtp" && \ 51 | ./autogen.sh && \ 52 | ./configure && \ 53 | make install && \ 54 | mkdir -p /srv && mv scripts /srv/scripts && \ 55 | 56 | # Install seahub 57 | mkdir -p /srv/seafile-server && mv /src/seahub-${SEAFILE_VERSION}-server /srv/seafile-server/seahub && \ 58 | cd /srv/seafile-server/seahub && \ 59 | pip install https://github.com/haiwen/django-constance/archive/6b04a31.zip && \ 60 | env LIBRARY_PATH=/lib:/usr/lib pip install -r requirements.txt && \ 61 | 62 | # Cleanup 63 | cd / && rm -rf /src /root/.cache && \ 64 | apk --no-cache del .build 65 | 66 | COPY etc /etc 67 | COPY seahub.conf /srv/seafile-server/runtime/seahub.conf 68 | 69 | WORKDIR /srv 70 | VOLUME $SEAFILE_CONF_DIR 71 | 72 | EXPOSE 80 $FILESERVER_PORT $CCNET_PORT $SEAFILE_PORT 73 | -------------------------------------------------------------------------------- /seafile/README.md: -------------------------------------------------------------------------------- 1 | # Seafile server 2 | Lightweight Docker image for [Seafile], a self-hosted file hosting and syncing platform. 3 | 4 | The Seafile server is broken up into several components spread around, which can make installation tricky. This Docker image can reduce installation time to just a few minutes. I recommend that you brush up on the [Seafile manual] before setting up your own server; there's a lot to be aware of. 5 | 6 | Like most of my images, this image is based off my tiny Alpine base image, and contains the minimal environment needed to run Seafile. 7 | 8 | ## Usage 9 | You can create a new Seafile container by using a command like below: 10 | 11 | ```sh 12 | docker run -p 80:80 -p 8082:8082 -p 10001:10001 -p 12001:12001 -v seafile-data:/data -e SERVER_NAME=myserver sagebind/seafile 13 | ``` 14 | 15 | ## Logging in 16 | Currently the image does not instrument any users for you, so you will have to do that yourself when you first create your data. You can do this by connecting to the running container and provisioning an account using the command line: 17 | 18 | ```sh 19 | docker exec -it my_container_name seafile-admin create-admin 20 | ``` 21 | 22 | Follow the interactive prompts to create the user. 23 | 24 | ## Configuration 25 | There's not many interesting settings to configure that can't be done within the Seafile web interface; the only thing that ought to be overriden is the server name, which can be specified using the aptly-named `SERVER_NAME` environment variable. 26 | 27 | Of course, a file-syncing service is not very useful if it can't persist any files. Everything worth persisting is stored in the `/data` volume; be sure to mount the volume somewhere persistent and safe. It might be a good idea to back this volume up as well. 28 | 29 | ## Building the image 30 | You can build the image yourself by using the `Makefile` in this repository, as usual: 31 | 32 | ```sh 33 | cd sagebind/dockerfiles 34 | make seafile 35 | ``` 36 | 37 | Note that this image can take quite some time to build, as it compiles Seafile from scratch. 38 | 39 | 40 | [seafile]: https://www.seafile.com 41 | [seafile manual]: https://manual.seafile.com 42 | -------------------------------------------------------------------------------- /seafile/etc/init/seafile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p $SEAFILE_CENTRAL_CONF_DIR 3 | mkdir -p /srv/logs 4 | 5 | # Initialize ccnet config. 6 | ccnet-init -F $SEAFILE_CENTRAL_CONF_DIR -c $CCNET_CONF_DIR --name $SERVER_NAME --port $CCNET_PORT --host 0.0.0.0 7 | 8 | # Initialize Seafile server config. 9 | seaf-server-init -F $SEAFILE_CENTRAL_CONF_DIR --seafile-dir $SEAFILE_CONF_DIR --port $SEAFILE_PORT --fileserver-port $FILESERVER_PORT 10 | 11 | # Set Seafile data directory. 12 | if [ ! -f $CCNET_CONF_DIR/seafile.ini ]; then 13 | printf $SEAFILE_CONF_DIR > $CCNET_CONF_DIR/seafile.ini 14 | fi 15 | 16 | # Configure Seahub. 17 | if [ ! -f $SEAFILE_CENTRAL_CONF_DIR/seahub_settings.py ]; then 18 | echo "SERVICE_URL = 'http://127.0.0.1'" >> $SEAFILE_CENTRAL_CONF_DIR/seahub_settings.py 19 | echo "FILE_SERVER_ROOT = 'http://127.0.0.1/seafhttp'" >> $SEAFILE_CENTRAL_CONF_DIR/seahub_settings.py 20 | echo "SECRET_KEY = '$(uuidgen -r)'" >> $SEAFILE_CENTRAL_CONF_DIR/seahub_settings.py 21 | fi 22 | 23 | # Set up databases. 24 | if [ ! -f $SEAFILE_CONF_DIR/seahub.db ]; then 25 | python /srv/seafile-server/seahub/manage.py syncdb 26 | 27 | # Move the database into the persistent volume. 28 | mv /srv/seahub.db $SEAFILE_CONF_DIR/seahub.db 29 | fi 30 | 31 | # We want to keep all persistent data in the persistent volume, so create 32 | # symbolic links to databases in the place Seahub expects. 33 | mkdir -p $SEAFILE_CONF_DIR/GroupMgr 34 | mkdir -p $SEAFILE_CONF_DIR/OrgMgr 35 | mkdir -p $SEAFILE_CONF_DIR/PeerMgr 36 | ln -fs $SEAFILE_CONF_DIR/GroupMgr $CCNET_CONF_DIR/GroupMgr 37 | ln -fs $SEAFILE_CONF_DIR/OrgMgr $CCNET_CONF_DIR/OrgMgr 38 | ln -fs $SEAFILE_CONF_DIR/PeerMgr $CCNET_CONF_DIR/PeerMgr 39 | ln -fs $SEAFILE_CONF_DIR/seahub.db /srv/seahub.db 40 | -------------------------------------------------------------------------------- /seafile/etc/nginx/conf.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name localhost; 4 | 5 | proxy_set_header X-Forwarded-For $remote_addr; 6 | 7 | location / { 8 | proxy_pass http://127.0.0.1:8000; 9 | proxy_set_header Host $host; 10 | proxy_set_header X-Real-IP $remote_addr; 11 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 12 | proxy_set_header X-Forwarded-Host $server_name; 13 | proxy_read_timeout 1200s; 14 | client_max_body_size 0; 15 | } 16 | 17 | location /seafhttp/ { 18 | proxy_pass http://127.0.0.1:8082/; 19 | client_max_body_size 0; 20 | proxy_request_buffering off; 21 | 22 | proxy_connect_timeout 36000s; 23 | proxy_read_timeout 36000s; 24 | proxy_send_timeout 36000s; 25 | send_timeout 36000s; 26 | } 27 | 28 | location /seafmedia { 29 | rewrite ^/seafmedia(.*)$ /media$1 break; 30 | root /srv/seafile-server/seahub; 31 | } 32 | 33 | location /media { 34 | root /srv/seafile-server/seahub; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /seafile/etc/service/seafile/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | echo exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /seafile/etc/service/seafile/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec seafile-controller -f -c $CCNET_CONF_DIR -d $SEAFILE_CONF_DIR -F $SEAFILE_CENTRAL_CONF_DIR 3 | -------------------------------------------------------------------------------- /seafile/etc/service/seahub/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /seafile/etc/service/seahub/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -f /srv/seafile-server/runtime/seahub.pid ]; then 3 | rm /srv/seafile-server/runtime/seahub.pid 4 | fi 5 | 6 | exec gunicorn seahub.wsgi:application -c /srv/seafile-server/runtime/seahub.conf -b 127.0.0.1:8000 --enable-stdio-inheritance --capture-output 7 | -------------------------------------------------------------------------------- /seafile/seahub.conf: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | daemon = False 4 | workers = 4 5 | worker_class = 'gevent' 6 | 7 | runtime_dir = os.path.dirname(__file__) 8 | pidfile = os.path.join(runtime_dir, 'seahub.pid') 9 | errorlog = '/dev/stderr' 10 | accesslog = '/dev/stdout' 11 | -------------------------------------------------------------------------------- /znc/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagebind/base:latest 2 | MAINTAINER Stephen Coakley 3 | 4 | RUN apk --no-cache add ca-certificates znc && \ 5 | apk --no-cache add --virtual build build-base curl-dev git openssl-dev znc-dev && \ 6 | git clone https://github.com/jreese/znc-push && \ 7 | make -C znc-push && \ 8 | mv znc-push/push.so /usr/lib/znc && \ 9 | rm -rf znc-push && \ 10 | apk del build 11 | 12 | COPY root / 13 | 14 | VOLUME /etc/znc 15 | 16 | EXPOSE 6667 17 | -------------------------------------------------------------------------------- /znc/README.md: -------------------------------------------------------------------------------- 1 | # sagebind/znc 2 | Lightweight Docker image with [ZNC] IRC bouncer. 3 | 4 | Listens on port 6667 and is set up with user `admin` and password `admin`. It is strongly recommended to create a new user and delete the admin user or change the admin password after starting the container. 5 | 6 | To persist settings and data, mount a host directory on the `/etc/znc` volume. 7 | 8 | 9 | [ZNC]: http://znc.in 10 | -------------------------------------------------------------------------------- /znc/root/etc/init/znc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! -d /etc/znc/configs ]; then 3 | mkdir -p /etc/znc/configs 4 | fi 5 | 6 | if [ ! -f /etc/znc/configs/znc.conf ]; then 7 | cp /etc/znc.default.conf /etc/znc/configs/znc.conf 8 | fi 9 | -------------------------------------------------------------------------------- /znc/root/etc/service/znc/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $1 -ne 0 -a $1 -ne 256 ]; then 3 | exec halt 4 | fi 5 | -------------------------------------------------------------------------------- /znc/root/etc/service/znc/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec s6-setuidgid znc znc --datadir /etc/znc --foreground 3 | -------------------------------------------------------------------------------- /znc/root/etc/znc.default.conf: -------------------------------------------------------------------------------- 1 | // WARNING 2 | // 3 | // Do NOT edit this file while ZNC is running! 4 | // Use webadmin or *controlpanel instead. 5 | // 6 | // Altering this file by hand will forfeit all support. 7 | // 8 | // But if you feel risky, you might want to read help on /znc saveconfig and /znc rehash. 9 | // Also check http://en.znc.in/wiki/Configuration 10 | 11 | Version = 1.6.3 12 | 13 | 14 | Port = 6667 15 | IPv4 = true 16 | IPv6 = true 17 | SSL = false 18 | 19 | 20 | LoadModule = webadmin 21 | 22 | 23 | Admin = true 24 | 25 | 26 | Method = sha256 27 | Hash = 35a1eeccd6d690f2a26ab35890879107884eb4017261260a36d894cddd43fba0 28 | Salt = !3pT0*EdEx:HGOG!1mi4 29 | 30 | 31 | LoadModule = chansaver 32 | LoadModule = controlpanel 33 | 34 | --------------------------------------------------------------------------------