commit
6e477d0a27
@ -0,0 +1,61 @@
|
|||||||
|
FROM httpd:alpine
|
||||||
|
MAINTAINER Bytemark Hosting "support@bytemark.co.uk"
|
||||||
|
|
||||||
|
# This variable is inherited from httpd:alpine image:
|
||||||
|
# ENV HTTPD_PREFIX /usr/local/apache2
|
||||||
|
|
||||||
|
RUN set -ex; \
|
||||||
|
# Create Debian-style subdirectories.
|
||||||
|
mkdir -p "$HTTPD_PREFIX/conf/conf-available"; \
|
||||||
|
mkdir -p "$HTTPD_PREFIX/conf/conf-enabled"; \
|
||||||
|
mkdir -p "$HTTPD_PREFIX/conf/sites-available"; \
|
||||||
|
mkdir -p "$HTTPD_PREFIX/conf/sites-enabled"
|
||||||
|
|
||||||
|
# Copy in our configuration files.
|
||||||
|
COPY dav.conf "$HTTPD_PREFIX/conf/conf-available"
|
||||||
|
COPY default.conf "$HTTPD_PREFIX/conf/sites-available"
|
||||||
|
COPY default-ssl.conf "$HTTPD_PREFIX/conf/sites-available"
|
||||||
|
|
||||||
|
RUN set -ex; \
|
||||||
|
# Create empty default DocumentRoot.
|
||||||
|
mkdir -p "/var/www/html"; \
|
||||||
|
# Create directories for Dav data and lock database.
|
||||||
|
mkdir -p "/var/lib/dav"; \
|
||||||
|
mkdir -p "/var/lib/dav/data"; \
|
||||||
|
touch "/var/lib/dav/DavLock"; \
|
||||||
|
chown -R www-data:www-data "/var/lib/dav"; \
|
||||||
|
\
|
||||||
|
# Enable DAV modules.
|
||||||
|
for i in dav dav_fs; do \
|
||||||
|
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
done; \
|
||||||
|
\
|
||||||
|
# Make sure authentication modules are enabled.
|
||||||
|
for i in authn_core authn_file authz_core authz_user auth_basic auth_digest; do \
|
||||||
|
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
done; \
|
||||||
|
\
|
||||||
|
# Make sure other modules are enabled.
|
||||||
|
for i in alias headers mime setenvif; do \
|
||||||
|
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
done; \
|
||||||
|
\
|
||||||
|
# Run httpd as "www-data" (instead of "daemon").
|
||||||
|
for i in User Group; do \
|
||||||
|
sed -i -e "s|^$i .*|$i www-data|" "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
done; \
|
||||||
|
\
|
||||||
|
# Include enabled configs and sites.
|
||||||
|
printf '%s\n' "Include conf/conf-enabled/*.conf" \
|
||||||
|
>> "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
printf '%s\n' "Include conf/sites-enabled/*.conf" \
|
||||||
|
>> "$HTTPD_PREFIX/conf/httpd.conf"; \
|
||||||
|
\
|
||||||
|
# Enable dav and default site.
|
||||||
|
ln -s ../conf-available/dav.conf "$HTTPD_PREFIX/conf/conf-enabled"; \
|
||||||
|
ln -s ../sites-available/default.conf "$HTTPD_PREFIX/conf/sites-enabled"
|
||||||
|
|
||||||
|
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||||
|
EXPOSE 80/tcp 443/tcp
|
||||||
|
ENTRYPOINT [ "docker-entrypoint.sh" ]
|
||||||
|
CMD [ "httpd-foreground" ]
|
@ -0,0 +1,132 @@
|
|||||||
|
## Supported tags
|
||||||
|
|
||||||
|
* [`2.4`, `latest` (*stretch/Dockerfile*)](https://github.com/BytemarkHosting/docker-webdav/blob/master/2.4/Dockerfile)
|
||||||
|
|
||||||
|
## Quick reference
|
||||||
|
|
||||||
|
This image runs an easily configurable WebDAV server with Apache.
|
||||||
|
|
||||||
|
* **Code repository:**
|
||||||
|
https://github.com/BytemarkHosting/docker-webdav
|
||||||
|
* **Where to file issues:**
|
||||||
|
https://github.com/BytemarkHosting/docker-webdav/issues
|
||||||
|
* **Maintained by:**
|
||||||
|
[Bytemark Hosting](https://www.bytemark.co.uk)
|
||||||
|
* **Supported architectures:**
|
||||||
|
[Any architecture that the `httpd` image supports](https://hub.docker.com/_/httpd/)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic WebDAV server
|
||||||
|
|
||||||
|
This example starts a WebDAV server.
|
||||||
|
|
||||||
|
When using unencrypted HTTP, use `Digest` authentication (instead of `Basic`)
|
||||||
|
to avoid sending plaintext passwords in the clear.
|
||||||
|
|
||||||
|
To make sure your data doesn't get deleted, you'll probably want to create a
|
||||||
|
persistent storage volume (`-v vol-webdav:/var/lib/dav`) or bind mount a
|
||||||
|
directory (`-v /path/to/directory:/var/lib/dav`):
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --restart always -v /srv/dav:/var/lib/dav \
|
||||||
|
-e AUTH_TYPE=Digest -e USERNAME=alice -e PASSWORD=secret1234 \
|
||||||
|
--publish 80:80 -d bytemark/webdav
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Via Docker Compose:
|
||||||
|
|
||||||
|
```
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
mail:
|
||||||
|
image: bytemark/webdav
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
environment:
|
||||||
|
AUTH_TYPE: Digest
|
||||||
|
USERNAME: alice
|
||||||
|
PASSWORD: secret1234
|
||||||
|
volumes:
|
||||||
|
- /srv/dav:/var/lib/dav
|
||||||
|
|
||||||
|
```
|
||||||
|
### Secure WebDAV with SSL
|
||||||
|
|
||||||
|
We recommend you use a reverse proxy (eg, Traefik) to handle SSL certificates.
|
||||||
|
|
||||||
|
If you're happy with a self-signed certificate, you can specify `-e
|
||||||
|
SSL_CERT=selfsigned` and the container will generate one for you.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --restart always -v /srv/dav:/var/lib/dav \
|
||||||
|
-e AUTH_TYPE=Basic -e USERNAME=test -e PASSWORD=test \
|
||||||
|
-e SSL_CERT=selfsigned --publish 443:443 -d bytemark/webdav
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authenticate multiple clients
|
||||||
|
|
||||||
|
Specifying `USERNAME` and `PASSWORD` only supports a single user. Bind mount
|
||||||
|
your own file to `/user.passwd` and the container will use that instead.
|
||||||
|
|
||||||
|
If using `Basic` authentication, run the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
touch user.passwd
|
||||||
|
htpasswd -B user.passwd alice
|
||||||
|
htpasswd -B user.passwd bob
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
If using `Digest` authentication, run the following commands. (NB: The default
|
||||||
|
`REALM` is `WebDAV`. If you specify your own `REALM`, you'll need to run
|
||||||
|
`htdigest` again with the new name.)
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
touch user.passwd
|
||||||
|
htdigest user.passwd WebDAV alice
|
||||||
|
htdigest user.passwd WebDAV bob
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you've created your own `user.passwd`, bind mount it into your container
|
||||||
|
with `-v /path/to/user.passwd:/user.passwd`.
|
||||||
|
|
||||||
|
### Environment variables
|
||||||
|
|
||||||
|
All environment variables are optional. You probably want to at least specify
|
||||||
|
`USERNAME` and `PASSWORD` (or bind mount your own authentication file to
|
||||||
|
`/user.passwd`) otherwise nobody will be able to access your WebDAV server!
|
||||||
|
|
||||||
|
* **`SERVER_NAMES`**: Comma-separated list of domains (eg,
|
||||||
|
`example.com,www.example.com`). The first is set as the
|
||||||
|
[ServerName](https://httpd.apache.org/docs/current/mod/core.html#servername),
|
||||||
|
and the rest (if any) are set as
|
||||||
|
[ServerAlias](https://httpd.apache.org/docs/current/mod/core.html#serveralias).
|
||||||
|
The default is `localhost`.
|
||||||
|
* **`LOCATION`**: The URL path for WebDAV (eg, if set to `/webdav` then clients
|
||||||
|
should connect to `example.com/webdav`). The default is `/`.
|
||||||
|
* **`AUTH_TYPE`**: Apache authentication type to use. This can be `Basic` (best
|
||||||
|
choice for HTTPS) or `Digest` (best choice for HTTP). The default is `Basic`.
|
||||||
|
* **`REALM`**: Sets
|
||||||
|
[AuthName](https://httpd.apache.org/docs/current/mod/mod_authn_core.html#authname),
|
||||||
|
an identifier that is displayed to clients when they connect. The default is
|
||||||
|
`WebDAV`.
|
||||||
|
* **`USERNAME`**: Authenticate with this username (and the password below).
|
||||||
|
This is ignored if you bind mount your own authentication file to
|
||||||
|
`/user.passwd`.
|
||||||
|
* **`PASSWORD`**: Authenticate with this password (and the username above).
|
||||||
|
This is ignored if you bind mount your own authentication file to
|
||||||
|
`/user.passwd`.
|
||||||
|
* **`ANONYMOUS_METHODS`**: Comma-separated list of HTTP request methods (eg,
|
||||||
|
`GET,POST,OPTIONS,PROPFIND`). Clients can use any method you specify here
|
||||||
|
without authentication. Set to `ALL` to disable authentication. The default
|
||||||
|
is to disallow any anonymous access.
|
||||||
|
* **`SSL_CERT`**: Set to `selfsigned` to generate a self-signed certificate and
|
||||||
|
enable Apache's SSL module. If you specify `SERVER_NAMES`, the first domain
|
||||||
|
is set as the Common Name.
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
DavLockDB "/var/lib/dav/DavLock"
|
||||||
|
Alias / "/var/lib/dav/data/"
|
||||||
|
<Directory "/var/lib/dav/data/">
|
||||||
|
Dav On
|
||||||
|
Options Indexes FollowSymLinks
|
||||||
|
|
||||||
|
AuthType Basic
|
||||||
|
AuthName "WebDAV"
|
||||||
|
AuthUserFile "/user.passwd"
|
||||||
|
<RequireAny>
|
||||||
|
Require valid-user
|
||||||
|
</RequireAny>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# These disable redirects on non-GET requests for directories that
|
||||||
|
# don't include the trailing slash (for misbehaving clients).
|
||||||
|
BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
|
||||||
|
BrowserMatch "MS FrontPage" redirect-carefully
|
||||||
|
BrowserMatch "^WebDrive" redirect-carefully
|
||||||
|
BrowserMatch "^WebDAVFS/1.[01234]" redirect-carefully
|
||||||
|
BrowserMatch "^gnome-vfs/1.0" redirect-carefully
|
||||||
|
BrowserMatch "^XML Spy" redirect-carefully
|
||||||
|
BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
|
||||||
|
BrowserMatch " Konqueror/4" redirect-carefully
|
||||||
|
BrowserMatch "^gvfs" redirect-carefully
|
@ -0,0 +1,18 @@
|
|||||||
|
Listen 443
|
||||||
|
<VirtualHost *:443>
|
||||||
|
Protocols h2 http/1.1
|
||||||
|
ServerName localhost
|
||||||
|
DocumentRoot "/var/www/html/"
|
||||||
|
<Directory "/var/www/html/">
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
CustomLog /proc/self/fd/1 combined
|
||||||
|
ErrorLog /proc/self/fd/2
|
||||||
|
SSLEngine on
|
||||||
|
SSLCertificateFile /cert.pem
|
||||||
|
SSLCertificateKeyFile /privkey.pem
|
||||||
|
SSLProtocol all -SSLv3
|
||||||
|
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
||||||
|
SSLHonorCipherOrder on
|
||||||
|
SSLSessionTickets off
|
||||||
|
</VirtualHost>
|
@ -0,0 +1,11 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName localhost
|
||||||
|
DocumentRoot "/var/www/html/"
|
||||||
|
<Directory "/var/www/html/">
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
CustomLog /proc/self/fd/1 combined
|
||||||
|
ErrorLog /proc/self/fd/2
|
||||||
|
# This lets certain DAV methods work behind an SSL reverse proxy.
|
||||||
|
RequestHeader edit Destination ^https http early
|
||||||
|
</VirtualHost>
|
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Environment variables that are used if not empty:
|
||||||
|
# SERVER_NAMES
|
||||||
|
# LOCATION
|
||||||
|
# AUTH_TYPE
|
||||||
|
# REALM
|
||||||
|
# USERNAME
|
||||||
|
# PASSWORD
|
||||||
|
# ANONYMOUS_METHODS
|
||||||
|
# SSL_CERT
|
||||||
|
|
||||||
|
# Just in case this environment variable has gone missing.
|
||||||
|
HTTPD_PREFIX="${HTTPD_PREFIX:-/usr/local/apache2}"
|
||||||
|
|
||||||
|
# Configure vhosts.
|
||||||
|
if [ "x$SERVER_NAMES" != "x" ]; then
|
||||||
|
# Use first domain as Apache ServerName.
|
||||||
|
SERVER_NAME="${SERVER_NAMES%%,*}"
|
||||||
|
sed -e "s|ServerName .*|ServerName $SERVER_NAME|" \
|
||||||
|
-i "$HTTPD_PREFIX"/conf/sites-available/default*.conf
|
||||||
|
|
||||||
|
# Replace commas with spaces and set as Apache ServerAlias.
|
||||||
|
SERVER_ALIAS="`printf '%s\n' "$SERVER_NAMES" | tr ',' ' '`"
|
||||||
|
sed -e "/ServerName/a\ \ ServerAlias $SERVER_ALIAS" \
|
||||||
|
-i "$HTTPD_PREFIX"/conf/sites-available/default*.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure dav.conf
|
||||||
|
if [ "x$LOCATION" != "x" ]; then
|
||||||
|
sed -e "s|Alias /|Alias $LOCATION|" \
|
||||||
|
-i "$HTTPD_PREFIX/conf/conf-available/dav.conf"
|
||||||
|
fi
|
||||||
|
if [ "x$REALM" != "x" ]; then
|
||||||
|
sed -e "s|AuthName .*|AuthName \"$REALM\"|" \
|
||||||
|
-i "$HTTPD_PREFIX/conf/conf-available/dav.conf"
|
||||||
|
else
|
||||||
|
REALM="WebDAV"
|
||||||
|
fi
|
||||||
|
if [ "x$AUTH_TYPE" != "x" ]; then
|
||||||
|
# Only support "Basic" and "Digest".
|
||||||
|
if [ "$AUTH_TYPE" != "Basic" ] && [ "$AUTH_TYPE" != "Digest" ]; then
|
||||||
|
printf '%s\n' "$AUTH_TYPE: Unknown AuthType" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sed -e "s|AuthType .*|AuthType $AUTH_TYPE|" \
|
||||||
|
-i "$HTTPD_PREFIX/conf/conf-available/dav.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add password hash, unless "user.passwd" already exists (ie, bind mounted).
|
||||||
|
if [ ! -e "/user.passwd" ]; then
|
||||||
|
touch "/user.passwd"
|
||||||
|
# Only generate a password hash if both username and password given.
|
||||||
|
if [ "x$USERNAME" != "x" ] && [ "x$PASSWORD" != "x" ]; then
|
||||||
|
if [ "$AUTH_TYPE" = "Digest" ]; then
|
||||||
|
# Can't run `htdigest` non-interactively, so use other tools.
|
||||||
|
HASH="`printf '%s' "$USERNAME:$REALM:$PASSWORD" | md5sum | awk '{print $1}'`"
|
||||||
|
printf '%s\n' "$USERNAME:$REALM:$HASH" > /user.passwd
|
||||||
|
else
|
||||||
|
htpasswd -B -b -c "/user.passwd" $USERNAME $PASSWORD
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If specified, allow anonymous access to specified methods.
|
||||||
|
if [ "x$ANONYMOUS_METHODS" != "x" ]; then
|
||||||
|
if [ "$ANONYMOUS_METHODS" = "ALL" ]; then
|
||||||
|
sed -e "s/Require valid-user/Require all granted/" \
|
||||||
|
-i "$HTTPD_PREFIX/conf/conf-available/dav.conf"
|
||||||
|
else
|
||||||
|
sed -e "/Require valid-user/a\ \ \ \ Require method $ANONYMOUS_METHODS" \
|
||||||
|
-i "$HTTPD_PREFIX/conf/conf-available/dav.conf"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${SSL_CERT:-none}" in
|
||||||
|
"selfsigned")
|
||||||
|
# Generate self-signed SSL certificate.
|
||||||
|
# If SERVER_NAMES is given, use the first domain as the Common Name.
|
||||||
|
if [ ! -e /privkey.pem ] || [ ! -e /cert.pem ]; then
|
||||||
|
apk add --no-cache openssl
|
||||||
|
openssl req -x509 -newkey rsa:2048 -days 1000 -nodes \
|
||||||
|
-keyout /privkey.pem -out /cert.pem -subj "/CN=${SERVER_NAME:-selfsigned}"
|
||||||
|
apk del --no-cache openssl
|
||||||
|
fi
|
||||||
|
# Enable SSL Apache modules.
|
||||||
|
for i in http2 ssl; do
|
||||||
|
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "$HTTPD_PREFIX/conf/httpd.conf"
|
||||||
|
done
|
||||||
|
# Enable SSL vhost.
|
||||||
|
if [ -e /privkey.pem ] && [ -e /cert.pem ]; then
|
||||||
|
ln -s ../sites-available/default-ssl.conf "$HTTPD_PREFIX/conf/sites-enabled"; \
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exec "$@"
|
Loading…
Reference in new issue