...
 
Commits (17)
apache-logs/
certbot-logs/
vhosts/
certs/
laststart.var
......@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.2.0] - 2018-04-08
### Added
- Custom persistent data location
## [1.1.1] - 2018-03-29
### Added
......
......@@ -7,7 +7,7 @@
SLARP is an environment that is ready to forward HTTP requests to backend web servers (so it acts as a reverse proxy), while ensuring SSL termination for HTTPS requests.
Easily installable and sufficient in many cases.
There's almost no configuration to be done for SLARP itself. Your main work is to write **vhosts** that call your backends, and to run some short commands to request new Let's Encrypt SSL certificates (renewal is then automatic).
It is not especially designed for high scalability, though Apache (here used with its default configuration) can handle a decent number of simultaneous connections.
It is not especially designed for high performance or scalability, though Apache (here used with its default configuration) can handle a decent number of simultaneous connections.
The typical situation is when:
* You have several containers on your machine that act as backend web servers, so you need a single entrypoint that listens to the ports 80/443 of the host.
......@@ -22,6 +22,8 @@ All operations must be run as **root**. The reasons are:
* Server administration tasks usually need the highest privileges.
* Thus, files of this project are intended to belong to root.
Be sure to read and understand all this document before running any command.
### 1- Get the minimal Docker image on which the SLARP image will be based
SLARP needs some things that are provided by the project [debian9-workbase](https://gitlab.zareldyn.net/zareldyn/debian9-workbase#debian9-workbase).
......@@ -33,8 +35,9 @@ This will build a Docker image named "my-debian9". You can choose another name i
### 2- Clone this project
Note that the working copy is the location where some data (certificates, logs…) will persist; you may have noticed the empty directories in the project's tree.
I suggest to install SLARP in `/opt`.
```
# cd /opt
# git clone https://gitlab.zareldyn.net/zareldyn/slarp.git && ./slarp/fix-permissions
```
......@@ -56,10 +59,16 @@ This builds the "slarp-reverse-proxy" image from the "my-debian9" image.
### 4- Launch SLARP
Be sure you have no other program listening to the ports 80 and 443. Then, just run
Be sure you have no other program listening to the ports 80 and 443. To launch the service with the default configuration, just run
```
# ./start
```
By default all important data go to the SLARP installation directory. However you can adjust the values of 4 environment variables before starting: `VHOSTS_DIR`, `CERTS_DIR`, `APACHE_LOGS_DIR` and `CERTBOT_LOGS_DIR`. For example
```
# VHOSTS_DIR=/path/to/your/vhosts CERTS_DIR=/path/to/your/certificates ./start
```
runs the service with a customized location for the *vhosts* and the *certs*, but still keeps logs where SLARP is installed.
Now a container named "slarp-reverse-proxy" is running, but for now it has nothing to forward.
### 5- Define your needs
......@@ -68,7 +77,7 @@ Let's say your machine must handle requests like `http(s)://www.my-great-website
#### Add a vhost
In the *vhosts* directory of the SLARP working copy, add a file containing:
In the *vhosts* directory, add a file containing:
```apache
# This is just an example of Apache virtual host configuration.
# In build-context/Dockerfile you can see the Apache mods that are enabled.
......@@ -106,8 +115,8 @@ In the *vhosts* directory of the SLARP working copy, add a file containing:
</VirtualHost>
```
Notes:
* The internal `${APACHE_LOG_DIR}` directory is bound to the *apache-logs* directory of the SLARP working copy; I recommend to use it.
* The internal `/etc/letsencrypt` directory is bound to the *certs* directory of the SLARP working copy; always use the pattern "/etc/letsencrypt/live/{domain}/{file}" for `SSLCertificate*File` directives.
* The internal `${APACHE_LOG_DIR}` directory is bound to the external Apache logs directory you have probably customized via the external `APACHE_LOGS_DIR` variable; I recommend to use it.
* The internal `/etc/letsencrypt` directory is bound to the external *certs* directory; always use the pattern "/etc/letsencrypt/live/{domain}/{file}" for `SSLCertificate*File` directives.
#### Get a new Let's Encrypt SSL certificate
......@@ -120,7 +129,7 @@ Then, run
certbot certonly --apache -d www.my-great-website.org
```
and follow the instructions.
The certificate will be saved in the *certs* directory of the SLARP working copy, and the renewal is already scheduled.
The certificate will be saved in the *certs* directory, and the renewal is already scheduled; while SLARP is running Certbot periodically checks if a renewal is needed.
No other command required, you can [ctrl][d] the SLARP environment.
### 6- Apply your changes
......@@ -155,11 +164,10 @@ The *stop* command removes the SLARP container.
#### Persistent data
The *certs* directory contains the LE certificates Certbot has requested for you, and regularly you may want to make a copy of it, even if it is persisted when you *stop* SLARP.
The *certs* directory contains the LE certificates Certbot has requested for you, and regularly you may want to make a copy of it, even if it is persisted when you stop SLARP.
The same applies to the *vhosts* you create.
Finally, the purpose of *apache-logs* and *certbot-logs* is to avoid having logs growing inside the container. Moreover, it is usually useful to keep them.
Finally, the purpose of *apache-logs* and *certbot-logs* (their default names in the SLARP installation if not customized) is to avoid having logs growing inside the container's filesystem. Moreover, it is usually useful to keep them.
#### Updating SLARP
......
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
function show_usage {
......@@ -39,4 +39,4 @@ if [ -z $BASE_IMAGE ]; then
exit 64
fi
docker build --no-cache -t $APP_NAME --build-arg BASE_IMAGE=$BASE_IMAGE "$SELF_DIR"build-context
docker build --no-cache -t $APP_NAME --build-arg BASE_IMAGE=$BASE_IMAGE "$SELF_DIR"/build-context
......@@ -4,7 +4,7 @@ FROM $BASE_IMAGE
LABEL maintainer="zareldyn" \
description="A simple HTTP(S) reverse proxy based on Apache and Let's Encrypt."
ENV SLARP_VERSION="1.1.1"
ENV SLARP_VERSION="1.2.0"
RUN ["/bin/bash", "-c", " \
apt-get update && \
......
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
chmod 744 "$SELF_DIR"{build,reload,resolve-containers,start,stop,fix-permissions}
chmod 755 "$SELF_DIR"is-running
chmod 744 "$SELF_DIR"/{build,reload,resolve-containers,start,stop,fix-permissions}
chmod 755 "$SELF_DIR"/is-running
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
function say_no {
......
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
[ $(. "$SELF_DIR"is-running) == "yes" ] || {
[ $(. "$SELF_DIR"/is-running) == "yes" ] || {
echo "Error: $APP_NAME is not running" >&2
exit 1
}
. "$SELF_DIR"resolve-containers
. "$SELF_DIR"/resolve-containers
docker exec $APP_NAME bash -c 'service apache2 reload'
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
APP_VARFILE="$SELF_DIR/laststart.var"
[ $(. "$SELF_DIR"is-running) == "yes" ] || {
function abort_varfile {
echo "Error: $APP_VARFILE absent or corrupted - please restart $APP_NAME" >&2
exit 1
}
[ $(. "$SELF_DIR"/is-running) == "yes" ] || {
echo "Error: $APP_NAME is not running" >&2
exit 1
}
cd "$SELF_DIR"vhosts
source "$APP_VARFILE" || abort_varfile
[ -z "$VHOSTS_DIR" ] && abort_varfile
cd "$VHOSTS_DIR"
vhostsSection="#APACHE VHOSTS"
......@@ -54,4 +62,4 @@ done < <(docker exec $APP_NAME cat /etc/hosts)
newHostsFileContent="$newHostsFileContent
$vhostsSection"
docker exec $APP_NAME bash -c "echo \"$newHostsFileContent\" > /etc/hosts"
echo "Updated hosts file"
echo "Updated container's hosts file"
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
APP_VARFILE="$SELF_DIR/laststart.var"
[ $(. "$SELF_DIR"is-running) == "no" ] || {
echo "$APP_NAME is already running!"
[ $(. "$SELF_DIR"/is-running) == "no" ] || {
echo "$APP_NAME is already running"
exit
}
docker run -d --restart on-failure\
--name $APP_NAME\
-e CONTAINER_NAME=$APP_NAME\
-v "$SELF_DIR"certs/:/etc/letsencrypt/\
-v "$SELF_DIR"vhosts/:/etc/apache2/sites-enabled/\
-v "$SELF_DIR"apache-logs/:/var/log/apache2/\
-v "$SELF_DIR"certbot-logs/:/var/log/letsencrypt/\
-p 80:80 -p 443:443\
$APP_NAME:latest bash -c\
[ -z "$CERTS_DIR" ] && CERTS_DIR="$SELF_DIR"/certs
[ -z "$VHOSTS_DIR" ] && VHOSTS_DIR="$SELF_DIR"/vhosts
[ -z "$APACHE_LOGS_DIR" ] && APACHE_LOGS_DIR="$SELF_DIR"/apache-logs
[ -z "$CERTBOT_LOGS_DIR" ] && CERTBOT_LOGS_DIR="$SELF_DIR"/certbot-logs
for dir in "$CERTS_DIR" "$VHOSTS_DIR" "$APACHE_LOGS_DIR" "$CERTBOT_LOGS_DIR"; do
mkdir -p "$dir" || {
echo "Could not create $dir - aborting" >&2
exit 74
}
done
echo CERTS_DIR="$CERTS_DIR" > "$APP_VARFILE" || {
echo "Could not write $APP_VARFILE - aborting" >&2
exit 74
}
echo VHOSTS_DIR="$VHOSTS_DIR" >> "$APP_VARFILE"
echo APACHE_LOGS_DIR="$APACHE_LOGS_DIR" >> "$APP_VARFILE"
echo CERTBOT_LOGS_DIR="$CERTBOT_LOGS_DIR" >> "$APP_VARFILE"
docker run -d --restart on-failure \
--name $APP_NAME \
-e CONTAINER_NAME=$APP_NAME \
-v "$CERTS_DIR":/etc/letsencrypt \
-v "$VHOSTS_DIR":/etc/apache2/sites-enabled \
-v "$APACHE_LOGS_DIR":/var/log/apache2 \
-v "$CERTBOT_LOGS_DIR":/var/log/letsencrypt \
-p 80:80 -p 443:443 \
$APP_NAME:latest bash -c \
"cron &&
apache2ctl -DFOREGROUND"
. "$SELF_DIR"resolve-containers
. "$SELF_DIR"/resolve-containers
echo "$APP_NAME started"
#!/bin/bash
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_NAME=$(basename "$SELF_DIR")
[ $(. "$SELF_DIR"is-running) == "yes" ] || {
echo "$APP_NAME is already stopped!"
[ $(. "$SELF_DIR"/is-running) == "yes" ] || {
echo "$APP_NAME is already stopped"
exit
}
......