-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e5929ce
Showing
5 changed files
with
303 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Build Docker | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Login into Github Docker Registery | ||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | ||
|
||
- name: Build Docker Images | ||
uses: docker/build-push-action@v4 | ||
with: | ||
tags: ghcr.io/shopwarelabs/varnish | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
platforms: linux/amd64,linux/arm64 | ||
push: true | ||
provenance: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM varnish:fresh-alpine | ||
|
||
# install build dependencies | ||
USER root | ||
RUN set -e; \ | ||
apk upgrade --no-cache; \ | ||
apk add --no-cache $VMOD_DEPS; \ | ||
\ | ||
# install one, possibly multiple vmods | ||
install-vmod https://github.com/varnish/varnish-modules/releases/download/0.24.0/varnish-modules-0.24.0.tar.gz; \ | ||
\ | ||
# clean up | ||
apk del --no-network $VMOD_DEPS | ||
USER varnish | ||
ENV SHOPWARE_BACKEND_HOST=localhost \ | ||
SHOPWARE_BACKEND_PORT=8000 | ||
|
||
COPY --chown=1000 rootfs / |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Shopware Varnish Docker image | ||
|
||
The image bases on the official [Varnish image](https://hub.docker.com/_/varnish) and contains the Shopware default VCL. | ||
|
||
## Additional environment variables | ||
|
||
- `SHOPWARE_BACKEND_HOST` - The host of the Shopware backend. Default: `localhost` | ||
- `SHOPWARE_BACKEND_PORT` - The port of the Shopware backend. Default: `8000` | ||
- `SHOPWARE_SOFT_PURGE` - If set to `1`, the soft purge feature is enabled. Default: `0` | ||
|
||
## Example usage | ||
|
||
```bash | ||
docker run \ | ||
--rm \ | ||
-it \ | ||
# host ip where Shopware is | ||
-e SHOPWARE_BACKEND_HOST=host.docker.internal \ | ||
-p 8080:80 \ | ||
--name=varnish \ | ||
varnish | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
vcl 4.1; | ||
|
||
import std; | ||
import xkey; | ||
|
||
# Specify your app nodes here. Use round-robin balancing to add more than one. | ||
backend default { | ||
.host = "__SHOPWARE_BACKEND_HOST__"; | ||
.port = "__SHOPWARE_BACKEND_PORT__"; | ||
} | ||
|
||
# ACL for purgers IP. (This needs to contain app server ips) | ||
acl purgers { | ||
"127.0.0.1"; | ||
"localhost"; | ||
"::1"; | ||
} | ||
|
||
sub vcl_recv { | ||
# Mitigate httpoxy application vulnerability, see: https://httpoxy.org/ | ||
unset req.http.Proxy; | ||
|
||
# Ignore query strings that are only necessary for the js on the client. Customize as needed. | ||
if (req.url ~ "(\?|&)(pk_campaign|piwik_campaign|pk_kwd|piwik_kwd|pk_keyword|pixelId|kwid|kw|adid|chl|dv|nk|pa|camid|adgid|cx|ie|cof|siteurl|utm_[a-z]+|_ga|gclid)=") { | ||
# see rfc3986#section-2.3 "Unreserved Characters" for regex | ||
set req.url = regsuball(req.url, "(pk_campaign|piwik_campaign|pk_kwd|piwik_kwd|pk_keyword|pixelId|kwid|kw|adid|chl|dv|nk|pa|camid|adgid|cx|ie|cof|siteurl|utm_[a-z]+|_ga|gclid)=[A-Za-z0-9\-\_\.\~]+&?", ""); | ||
} | ||
set req.url = regsub(req.url, "(\?|\?&|&)$", ""); | ||
|
||
# Normalize query arguments | ||
set req.url = std.querysort(req.url); | ||
|
||
# Set a header announcing Surrogate Capability to the origin | ||
set req.http.Surrogate-Capability = "shopware=ESI/1.0"; | ||
|
||
# Make sure that the client ip is forward to the client. | ||
if (req.http.x-forwarded-for) { | ||
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; | ||
} else { | ||
set req.http.X-Forwarded-For = client.ip; | ||
} | ||
|
||
# Handle PURGE | ||
if (req.method == "PURGE") { | ||
if (client.ip !~ purgers) { | ||
return (synth(403, "Forbidden")); | ||
} | ||
if (req.http.xkey) { | ||
set req.http.n-gone = xkey.purge(req.http.xkey); | ||
|
||
return (synth(200, "Invalidated "+req.http.n-gone+" objects")); | ||
} else { | ||
return (purge); | ||
} | ||
} | ||
|
||
if (req.method == "BAN") { | ||
if (!client.ip ~ purgers) { | ||
return (synth(405, "Method not allowed")); | ||
} | ||
|
||
ban("req.url ~ "+req.url); | ||
return (synth(200, "BAN URLs containing (" + req.url + ") done.")); | ||
} | ||
# Normalize Accept-Encoding header | ||
# straight from the manual: https://www.varnish-cache.org/docs/3.0/tutorial/vary.html | ||
if (req.http.Accept-Encoding) { | ||
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { | ||
# No point in compressing these | ||
unset req.http.Accept-Encoding; | ||
} elsif (req.http.Accept-Encoding ~ "gzip") { | ||
set req.http.Accept-Encoding = "gzip"; | ||
} elsif (req.http.Accept-Encoding ~ "deflate") { | ||
set req.http.Accept-Encoding = "deflate"; | ||
} else { | ||
# unknown algorithm | ||
unset req.http.Accept-Encoding; | ||
} | ||
} | ||
if (req.method != "GET" && | ||
req.method != "HEAD" && | ||
req.method != "PUT" && | ||
req.method != "POST" && | ||
req.method != "TRACE" && | ||
req.method != "OPTIONS" && | ||
req.method != "PATCH" && | ||
req.method != "DELETE") { | ||
/* Non-RFC2616 or CONNECT which is weird. */ | ||
return (pipe); | ||
} | ||
# We only deal with GET and HEAD by default | ||
if (req.method != "GET" && req.method != "HEAD") { | ||
return (pass); | ||
} | ||
# Don't cache Authenticate & Authorization | ||
if (req.http.Authenticate || req.http.Authorization) { | ||
return (pass); | ||
} | ||
# Always pass these paths directly to php without caching | ||
# Note: virtual URLs might bypass this rule (e.g. /en/checkout) | ||
if (req.url ~ "^/(checkout|account|admin|api)(/.*)?$") { | ||
return (pass); | ||
} | ||
return (hash); | ||
} | ||
sub vcl_hash { | ||
# Consider Shopware HTTP cache cookies | ||
if (req.http.cookie ~ "sw-cache-hash=") { | ||
hash_data("+context=" + regsub(req.http.cookie, "^.*?sw-cache-hash=([^;]*);*.*$", "\1")); | ||
} elseif (req.http.cookie ~ "sw-currency=") { | ||
hash_data("+currency=" + regsub(req.http.cookie, "^.*?sw-currency=([^;]*);*.*$", "\1")); | ||
} | ||
} | ||
sub vcl_hit { | ||
# Consider client states for response headers | ||
if (req.http.cookie ~ "sw-states=") { | ||
set req.http.states = regsub(req.http.cookie, "^.*?sw-states=([^;]*);*.*$", "\1"); | ||
if (req.http.states ~ "logged-in" && obj.http.sw-invalidation-states ~ "logged-in" ) { | ||
return (pass); | ||
} | ||
if (req.http.states ~ "cart-filled" && obj.http.sw-invalidation-states ~ "cart-filled" ) { | ||
return (pass); | ||
} | ||
} | ||
} | ||
sub vcl_backend_response { | ||
# Fix Vary Header in some cases | ||
# https://www.varnish-cache.org/trac/wiki/VCLExampleFixupVary | ||
if (beresp.http.Vary ~ "User-Agent") { | ||
set beresp.http.Vary = regsub(beresp.http.Vary, ",? *User-Agent *", ""); | ||
set beresp.http.Vary = regsub(beresp.http.Vary, "^, *", ""); | ||
if (beresp.http.Vary == "") { | ||
unset beresp.http.Vary; | ||
} | ||
} | ||
if (beresp.http.Surrogate-Control ~ "ESI/1.0") { | ||
unset beresp.http.Surrogate-Control; | ||
set beresp.do_esi = true; | ||
return (deliver); | ||
} | ||
# Respect the Cache-Control=private header from the backend | ||
if ( | ||
beresp.http.Pragma ~ "no-cache" || | ||
beresp.http.Cache-Control ~ "no-cache" || | ||
beresp.http.Cache-Control ~ "private" | ||
) { | ||
set beresp.ttl = 0s; | ||
set beresp.http.X-Cacheable = "NO:Cache-Control=private"; | ||
set beresp.uncacheable = true; | ||
return (deliver); | ||
} | ||
# strip the cookie before the image is inserted into cache. | ||
if (bereq.url ~ "\.(png|gif|jpg|swf|css|js|webp)$") { | ||
unset beresp.http.set-cookie; | ||
} | ||
# Allow items to be stale if needed. | ||
set beresp.grace = 6h; | ||
# Save the bereq.url so bans work efficiently | ||
set beresp.http.x-url = bereq.url; | ||
set beresp.http.X-Cacheable = "YES"; | ||
# Remove the exact PHP Version from the response for more security | ||
unset beresp.http.x-powered-by; | ||
return (deliver); | ||
} | ||
sub vcl_deliver { | ||
## we don't want the client to cache | ||
set resp.http.Cache-Control = "max-age=0, private"; | ||
# remove link header, if session is already started to save client resources | ||
if (req.http.cookie ~ "session-") { | ||
unset resp.http.Link; | ||
} | ||
# Set a cache header to allow us to inspect the response headers during testing | ||
if (obj.hits > 0) { | ||
unset resp.http.set-cookie; | ||
set resp.http.X-Cache = "HIT"; | ||
} else { | ||
set resp.http.X-Cache = "MISS"; | ||
} | ||
# Remove the exact PHP Version from the response for more security (e.g. 404 pages) | ||
unset resp.http.x-powered-by; | ||
# invalidation headers are only for internal use | ||
unset resp.http.sw-invalidation-states; | ||
unset resp.http.xkey; | ||
set resp.http.X-Cache-Hits = obj.hits; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env sh | ||
|
||
set -eo pipefail | ||
|
||
sed -i "s|__SHOPWARE_BACKEND_HOST__|${SHOPWARE_BACKEND_HOST}|g" /etc/varnish/default.vcl | ||
sed -i "s|__SHOPWARE_BACKEND_PORT__|${SHOPWARE_BACKEND_PORT}|g" /etc/varnish/default.vcl | ||
|
||
if [[ "${SHOPWARE_SOFT_PURGE}" ]]; then | ||
sed -i "s|xkey.purge|xkey.softpurge|g" /etc/varnish/default.vcl | ||
fi | ||
|
||
# this will check if the first argument is a flag | ||
# but only works if all arguments require a hyphenated flag | ||
# -v; -SL; -f arg; etc will work, but not arg1 arg2 | ||
if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then | ||
set -- varnishd \ | ||
-F \ | ||
-f /etc/varnish/default.vcl \ | ||
-a http=:${VARNISH_HTTP_PORT:-80},HTTP \ | ||
-a proxy=:${VARNISH_PROXY_PORT:-8443},PROXY \ | ||
-p feature=+http2 \ | ||
-s malloc,$VARNISH_SIZE \ | ||
"$@" | ||
fi | ||
|
||
exec "$@" |