diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7fd1f5c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +*.iml +*.md +LICENSE diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bff2d76 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.iml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..57aa39b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: generic +sudo: required +services: + - docker + +before_script: + - docker login -u "${DOCKERHUB_USERNAME}" -p "${DOCKERHUB_PASSWORD}" +script: + - docker build -t infolinks/httpd:${TRAVIS_COMMIT} . + - | + if [[ ${TRAVIS_TAG} =~ ^v[0-9]+$ ]]; then + docker tag infolinks/httpd:${TRAVIS_COMMIT} infolinks/httpd:${TRAVIS_TAG} + docker push infolinks/httpd:${TRAVIS_TAG} + docker tag infolinks/httpd:${TRAVIS_COMMIT} infolinks/httpd:latest + docker push infolinks/httpd:latest + fi +after_script: + - | + if [[ "${TRAVIS_BRANCH}" == "master" ]]; then + docker run infolinks/github-release \ + --token="${GITHUB_ACCESS_TOKEN}" \ + --repo="${TRAVIS_REPO_SLUG}" \ + --commit="${TRAVIS_COMMIT}" + fi diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..d62b131 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,47 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@infolinks.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..adacfcf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Include updates to README.md with details of the change, including new environment variables or mounts, preferably with examples. +2. Undocumented code will be rejected, as well as over-documented code :) + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c4a5f83 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM httpd:2.4.27-alpine +MAINTAINER Arik Kfir +COPY ./bin/httpd.sh /usr/local/bin/ +COPY ./resources/trusted-proxies /var/www/ +COPY ./resources/ok.txt /var/www/html/ +COPY ./conf/*.conf /etc/httpd/conf.d/ +RUN apk add --no-cache mod_dav_svn && \ + chmod -v 0755 /usr/local/bin/httpd.sh && \ + mkdir -vp /var/log/httpd && \ + echo "IncludeOptional /etc/httpd/conf.d/*.conf" >> /usr/local/apache2/conf/httpd.conf +EXPOSE 80 443 +ENTRYPOINT ["/usr/local/bin/httpd.sh"] diff --git a/README.md b/README.md index d04781b..8a0d80f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,23 @@ # httpd -httpd base image + +Simple & reusable base image for simple [httpd](https://httpd.apache.org/) +servers. + +This image will start an `httpd` instance with sensible defaults yet +fully extensible. Its extension points are: + +* Any file conforming to `/etc/httpd/conf.d/*.conf` will automatically + be picked up. + +* Access log written under `/var/log/httpd` - you should collect those + using a logging side-car agent, such as [loggly-sidecar](https://github.com/infolinks/loggly-sidecar). + +* Trusted proxies that can provide `x-forwarded-for` header can be added + to `/var/www/trusted-proxies`. + +## Contributions + +Any contribution to the project will be appreciated! Whether it's bug +reports, feature requests, pull requests - all are welcome, as long as +you follow our [contribution guidelines for this project](CONTRIBUTING.md) +and our [code of conduct](CODE_OF_CONDUCT.md). diff --git a/bin/httpd.sh b/bin/httpd.sh new file mode 100644 index 0000000..1f2e5db --- /dev/null +++ b/bin/httpd.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +echo +echo "************************************************************" +echo "STARTING httpd" +echo "************************************************************" +echo + +# replace current shell with original httpd-alpine's entrypoint +exec /usr/local/bin/httpd-foreground diff --git a/conf/010_general.conf b/conf/010_general.conf new file mode 100644 index 0000000..cd3edf9 --- /dev/null +++ b/conf/010_general.conf @@ -0,0 +1,41 @@ +# Response +ServerTokens ProductOnly +ServerSignature Off +UseCanonicalName Off + +# Content location +DocumentRoot "/var/www/html" +AccessFileName .htaccess + +# Logging +CustomLog "/var/log/httpd/access_log" combined + +# Add header with the container hostname +PassEnv HOSTNAME +Header always set X-Container "%{HOSTNAME}e" + +# Networking +HostnameLookups Off + +# misc modules +LoadModule actions_module modules/mod_actions.so +LoadModule allowmethods_module modules/mod_allowmethods.so +LoadModule data_module modules/mod_data.so +LoadModule deflate_module modules/mod_deflate.so +LoadModule logio_module modules/mod_logio.so +LoadModule macro_module modules/mod_macro.so +LoadModule mime_magic_module modules/mod_mime_magic.so +LoadModule negotiation_module modules/mod_negotiation.so +LoadModule reflector_module modules/mod_reflector.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule sed_module modules/mod_sed.so +LoadModule session_module modules/mod_session.so +LoadModule session_cookie_module modules/mod_session_cookie.so +LoadModule session_crypto_module modules/mod_session_crypto.so +LoadModule slotmem_plain_module modules/mod_slotmem_plain.so +LoadModule slotmem_shm_module modules/mod_slotmem_shm.so +LoadModule substitute_module modules/mod_substitute.so +LoadModule unique_id_module modules/mod_unique_id.so +LoadModule usertrack_module modules/mod_usertrack.so +LoadModule watchdog_module modules/mod_watchdog.so +LoadModule xml2enc_module modules/mod_xml2enc.so diff --git a/conf/020_simple_error_pages.inc b/conf/020_simple_error_pages.inc new file mode 100644 index 0000000..e0c9ab2 --- /dev/null +++ b/conf/020_simple_error_pages.inc @@ -0,0 +1,37 @@ +ErrorDocument 400 "Bad request mister. Try again?" +ErrorDocument 401 "Unauthorized you are" +ErrorDocument 402 "Pay and you shall receive" +ErrorDocument 403 "Forbidden" +ErrorDocument 404 "Not Found" +ErrorDocument 405 "Method not allowed" +ErrorDocument 406 "You can't handle what I've got" +ErrorDocument 407 "Proxy authentication required" +ErrorDocument 408 "We waited and waited, where were you?" +ErrorDocument 409 "Conflicted are you?" +ErrorDocument 410 "Gone, like the wind" +ErrorDocument 411 "Length please?" +ErrorDocument 412 "Precondition failed" +ErrorDocument 413 "You're just too big for me to handle" +ErrorDocument 414 "Just too much for me, sorry" +ErrorDocument 415 "What the hell am I supposed to do with THAT!?" +ErrorDocument 416 "No one can satisfy that" +ErrorDocument 417 "Your expectations are way too high" +ErrorDocument 422 "Semantisisation blabation" +ErrorDocument 423 "Locked far far away" +ErrorDocument 424 "Failing on" +ErrorDocument 426 "Upgrade Required" +ErrorDocument 428 "Precondition Required" +ErrorDocument 429 "Leave me alone" +ErrorDocument 431 "Now that's way too much" +ErrorDocument 451 "Fahrenheit 451" +ErrorDocument 500 "Ooops. That's all I know." +ErrorDocument 501 "Not Implemented" +ErrorDocument 502 "Bad Gateway" +ErrorDocument 503 "Unavailable" +ErrorDocument 504 "Gateway Timeout" +ErrorDocument 505 "Unsupported HTTP version" +ErrorDocument 506 "Blah." +ErrorDocument 507 "You're not privy to know this." +ErrorDocument 508 "Loop and loop and loop you are" +ErrorDocument 510 "Keep trying, no avail buddy." +ErrorDocument 511 "Blah." diff --git a/conf/030_server_status.conf b/conf/030_server_status.conf new file mode 100644 index 0000000..a80812d --- /dev/null +++ b/conf/030_server_status.conf @@ -0,0 +1,7 @@ +# Enable the mod_status server status provider and create a **local only** virtual host with the server status handler +LoadModule info_module modules/mod_info.so +ExtendedStatus On + + Require ip 127.0.0.1 ::1 + SetHandler server-status + diff --git a/conf/040_caching.conf b/conf/040_caching.conf new file mode 100644 index 0000000..cf78b8a --- /dev/null +++ b/conf/040_caching.conf @@ -0,0 +1,5 @@ +LoadModule cache_module modules/mod_cache.so +LoadModule cache_disk_module modules/mod_cache_disk.so +LoadModule cache_socache_module modules/mod_cache_socache.so +LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +LoadModule expires_module modules/mod_expires.so diff --git a/conf/050_remoteip.inc b/conf/050_remoteip.inc new file mode 100644 index 0000000..6e37f26 --- /dev/null +++ b/conf/050_remoteip.inc @@ -0,0 +1,4 @@ +LoadModule remoteip_module modules/mod_remoteip.so +RemoteIPHeader X-Forwarded-For +RemoteIPProxiesHeader X-Forwarded-By +RemoteIPInternalProxyList /var/www/trusted-proxies diff --git a/conf/060_proxy.conf b/conf/060_proxy.conf new file mode 100644 index 0000000..2b50d1f --- /dev/null +++ b/conf/060_proxy.conf @@ -0,0 +1,8 @@ +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_balancer_module modules/mod_proxy_balancer.so +LoadModule proxy_ajp_module modules/mod_proxy_ajp.so +LoadModule proxy_http_module modules/mod_proxy_http.so +LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so +LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so +LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so +LoadModule proxy_html_module modules/mod_proxy_html.so diff --git a/conf/070_dav.conf b/conf/070_dav.conf new file mode 100644 index 0000000..2724e22 --- /dev/null +++ b/conf/070_dav.conf @@ -0,0 +1,5 @@ +LoadModule dav_module modules/mod_dav.so +LoadModule dav_fs_module modules/mod_dav_fs.so +LoadModule dav_lock_module modules/mod_dav_lock.so +LoadModule dav_svn_module /usr/lib/apache2/mod_dav_svn.so +LoadModule authz_svn_module /usr/lib/apache2/mod_authz_svn.so diff --git a/conf/900_health.conf b/conf/900_health.conf new file mode 100644 index 0000000..5ead54e --- /dev/null +++ b/conf/900_health.conf @@ -0,0 +1,15 @@ +# Health check (required for k8s httpd pods behind a service/ingress) +# This is intentionally in a file with a "900_" prefix, so it is applied AFTER applicative configurations; to disable, +# simply use an additional file with a higher priority, or create an extending image that deletes this file. + +Alias /health /var/www/html/ok.txt +Alias /healthz /var/www/html/ok.txt + + Require all granted + + + Require all granted + + + Require all granted + diff --git a/resources/ok.txt b/resources/ok.txt new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/resources/ok.txt @@ -0,0 +1 @@ +OK diff --git a/resources/trusted-proxies b/resources/trusted-proxies new file mode 100644 index 0000000..76fc349 --- /dev/null +++ b/resources/trusted-proxies @@ -0,0 +1,6 @@ +10.0.0.0/8 +127.0.0.0/8 +169.254.0.0/16 +172.16.0.0/12 +192.0.0.0/24 +192.168.0.0/16