webserver
Configuration and experiences using webservers, here we show a deployment of wikimedia as example.
webservers
apache
Ligthweight, fast and reliable but complicated to configure and test.
nginx
Same as apache but somehow easier to configure and test.
configuration
yaml
services:
nginx:
image: nginx:alpine
#image: nginx:latest
#restart: unless-stopped
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ${HOME}/certbot/conf:/etc/letsencrypt
- ${HOME}/apache2:/etc/apache2
- ${HOME}/certbot/www:/var/www/certbot
#- /var/www/:/var/www/
- ${HOME}/lav/siti:/var/www/html/
- ${HOME}/log:/var/log/
ports:
- "80:80"
- "443:443"
networks:
- webserver-net
Example of a default website:
server {
listen 80;
listen [::]:80;
server_name ${SERVER_PROD};
# server_tokens off;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
#error_log stderr notice;
location /.well-known {
root /var/www/certbot/;
allow all;
}
return 301 https://${DOLLAR}host${DOLLAR}request_uri;
}
server {
listen 443 ssl;
server_name ${SERVER_PROD};
server_tokens off;
root /var/www/html/;
index index.html index.htm index.php;
ssl_certificate /etc/letsencrypt/live/${SERVER_PROD}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${SERVER_PROD}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
try_files ${DOLLAR}uri ${DOLLAR}uri/ =404;
#proxy_set_header Host ${DOLLAR}http_host;
#proxy_set_header X-Real-IP ${DOLLAR}remote_addr;
#proxy_set_header X-Forwarded-For ${DOLLAR}proxy_add_x_forwarded_for;
}
location ~ /.ht {
deny all;
}
}
traefik
Only reverse-proxy with no webserver capability. Easy to configure but not completely reliable, I personally never understood why secure redirects weren't working and I dropped it.
Example of used configuration
yaml
services:
traefik:
image: "traefik:latest"
restart: unless-stopped
ports:
- "8080:8080"
- "443:443"
labels:
traefik.enable: true
traefik.port: 8080
traefik.http.routers.traefik_https.rule: Host(
${SERVER_ROOT}
)
traefik.http.routers.traefik_https.entrypoints: websecure
traefik.http.routers.traefik_https.tls: true
traefik.http.routers.traefik_https.tls.certResolver: lets-encrypt
traefik.http.routers.traefik_https.service: api@internal
traefik.backend: home
traefik.frontend.rule: "PathPrefixStrip:/"
traefik.port: 2015
traefik.docker.network: ntw_front
traefik.frontend.entryPoints: websecure
#traefik.http.routers.traefik_https.middlewares: auth-dash
#traefik.http.middlewares.auth-dash.basicauth.users: "admin:$$apr1$$.Mqpju24$OH9r.WHWHvUeUy3L0qsUM0"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik/traefik.d:/etc/traefik/traefik.d:ro
- ./traefik/acme.json:/acme.json:rw
- ./letsencrypt:/etc/letsencrypt
- ../../logs/:/logs/
networks:
- traefik-net
certificate
We use certbot (let'e encrypt)
yaml
services:
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ${HOME}/certbot/conf:/etc/letsencrypt
- ${HOME}/certbot/www:/var/www/certbot
- ${HOME}/log/:/var/log/
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
networks:
- webserver-net
Example for docker-compose :
docker-compose run --rm --entrypoint "\
certbot certonly --webroot -w /var/www/certbot \
$staging_arg \
$email_arg \
$domain_args \
--rsa-key-size $rsa_key_size \
--agree-tos \
--force-renewal" certbot
echo
php
[Dockerfile](https://github.com/sabeiro/sawmill/webserver/php/:
FROM php:7.4-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libjpg-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
WORKDIR /var/www/html
COPY selections.conf selections.conf
RUN apt-get install debconf-utils
RUN debconf-set-selections < selections.conf
RUN dpkg-reconfigure keyboard-configuration -f noninteractive
RUN apt install -y libicu-dev
RUN apt install -y lilypond imagemagick ghostscript fluidsynth firejail lame
RUN docker-php-ext-configure intl
RUN docker-php-ext-install gd pdo pdo_mysql mysqli intl
RUN docker-php-ext-enable pdo_mysql intl
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN usermod -u 1000 www-data
USER www-data
EXPOSE 9000
CMD ["php-fpm"]
Webserver configuration to route all the php requests to the php container:
upstream php_upstream {
server php-app:9000 fail_timeout=5s max_fails=5;
}
server {
...
location ~ .php${DOLLAR} {
try_files ${DOLLAR}uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)${DOLLAR};
fastcgi_pass php_upstream;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ${DOLLAR}document_root${DOLLAR}fastcgi_script_name;
include /etc/nginx/fastcgi_params;
include fastcgi.conf;
#include fastcgi_params;
fastcgi_param PATH_INFO ${DOLLAR}fastcgi_path_info;
}
}
load balancing
Redis, celery...