add php-nginx

This commit is contained in:
Stille 2022-07-20 23:24:29 +08:00
parent 920a445fab
commit 473df97a18
115 changed files with 2903 additions and 0 deletions

View File

@ -0,0 +1,25 @@
#+++++++++++++++++++++++++++++++++++++++
# Dockerfile for webdevops/php-nginx:7.4-alpine
# -- automatically generated --
#+++++++++++++++++++++++++++++++++++++++
FROM php:7.4-alpine
ENV WEB_DOCUMENT_ROOT=/app \
WEB_DOCUMENT_INDEX=index.php \
WEB_ALIAS_DOMAIN=*.vm \
WEB_PHP_TIMEOUT=600 \
WEB_PHP_SOCKET=""
ENV WEB_PHP_SOCKET=127.0.0.1:9000
ENV SERVICE_NGINX_CLIENT_MAX_BODY_SIZE="50m"
COPY conf/ /opt/docker/
RUN set -x \
# Install nginx
&& apk-install \
nginx \
&& docker-run-bootstrap \
&& docker-image-cleanup
EXPOSE 80 443

View File

@ -0,0 +1,14 @@
{{ docker.from("php", "7.4-alpine") }}
{{ environment.web() }}
{{ environment.webPhp() }}
{{ environment.nginx() }}
{{ docker.copy('conf/', '/opt/docker/') }}
RUN set -x \
{{ nginx.alpine() }} \
{{ provision.runBootstrap() }} \
{{ docker.cleanup() }}
{{ docker.expose('80 443') }}

View File

@ -0,0 +1,5 @@
if [[ ! -e "$WEB_DOCUMENT_ROOT" ]]; then
echo ""
echo "[WARNING] WEB_DOCUMENT_ROOT does not exists with path \"$WEB_DOCUMENT_ROOT\"!"
echo ""
fi

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_NGINX_OPTS" ]]; then SERVICE_NGINX_OPTS=""; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/nginx.d/"
exec /usr/sbin/nginx -g 'daemon off;' $SERVICE_NGINX_OPTS

View File

@ -0,0 +1,3 @@
upstream php {
server <PHP_SOCKET>;
}

View File

@ -0,0 +1 @@
# deprecated

View File

@ -0,0 +1,4 @@
include /opt/docker/etc/nginx/global.conf;
include /opt/docker/etc/nginx/php.conf;
include /opt/docker/etc/nginx/conf.d/*.conf;
include /opt/docker/etc/nginx/vhost.conf;

View File

@ -0,0 +1,34 @@
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /docker.stdout;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /docker.stdout main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
}

View File

@ -0,0 +1 @@
# deprecated

View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIE1DCCArwCCQDMMwGnSuK0tTANBgkqhkiG9w0BAQsFADAsMRswGQYDVQQKExJE
b2NrZXIgQm9pbGVycGxhdGUxDTALBgNVBAMUBCoudm0wHhcNMTUwNTA0MTcxNDQw
WhcNMjUwNTAxMTcxNDQwWjAsMRswGQYDVQQKExJEb2NrZXIgQm9pbGVycGxhdGUx
DTALBgNVBAMUBCoudm0wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDK
3TIUiyDvXelWeY9VXMrpjuZtYpVSDsACLpjFUhMnsP5/iKT0VbeZyqHvmwZjAg4G
Y10d+yZDdgv/xeu0HPOFbtR6pCp10d1tdLHZto5Cyuxu7IQsAVjnD6Ko7XFwtNk7
9o6JZfAFaGL4w5MokrVmCtspnsMZH7/7zU4f96cbF39zLopnpuXGD6t6DA8Qj3gy
0duaTjs42bYRN+rwLzVKAev99iQ4kPMJn4vV6/Xk6rtoSzC67GQyVZYaFypicD1S
NtsRmgEVvjCBDbrLOneUiRwff6qxEsZi7Hxv7BKFj4iUWnII7K/nP7T6uBHQjHO+
FpsGkU9lCMrCeVFBe8kKz/cbhd+yLUxXwAPr6gSOPmwn232Gy4tozvqZHpbUxsgx
7sT3ej9K66h1D7J+BjNFWYM1hbnC1r7H/xS7EBzBV8qRoQCVe08Juf5xsouXFakD
clLV4+L+1cxkpwsCQDly5g3tm/TBqA2O+ZJ+YHQDHKkzMyhLs6i0X/M5qvJBiLg1
GLTCS20rpQ5gXTEGuINqHgwXQWkUO6bhgSYqdHGX3zbZ5+qWpI4eui3dHZ1Ll0VH
6Icpb7ORTQwhc6W8KBlybssYPSlGOEBGUjYGNheoz9FpoSkxCis+P8ZNKtrmpPoq
Su0eOOGFOFHG02eOgPVxSwrDeN9MVJo7BPysGMHJmQIDAQABMA0GCSqGSIb3DQEB
CwUAA4ICAQC63g6NHmQKbiy3G6iaDkpUSbr5Mq2YgU61XnvWVyREqDcy/BXCw9oY
SJ/KUvCpqPnACNOFqjadRAmPiA9nf2WduoCgwQGV/YRFGswSuVvh/3X2TX5NWvbS
t8MQDttQg1dxpiMUjlu3rqhfohBdWJvp2lVSdpDb/MOlXBc/+p7HfOHwhqB7wwPN
NNbSKUbZqZxmD8cOf1X0hASr1yfFPj+2vST3ESaON8S0T2p63YX/sD5jvOUiEuyw
I5WcvLmiRZA07SH8nWyckLY3qWL+OlhSZrlAnolWS00b+7h5LNuRYEjKzwVgntoA
aCopyQih6wIk0+AfJO4sfhJBmQhnIrAaP/zwBH5g9zVizLf5H7U+hNXrMwgw55Sq
vjMdkZHvPKUXTvVit/rYE9H+PY3brkRWzOl4V/i/ZLJJm5805H/NyTbz9kPMJw2Q
nn+KOpfXXySD39f8iuRgSKXsYNul38hxWgcZZ6g+sOOp2n/VUmf0eZUWNnJ8i7AP
4Qif7aDKMcibOwSwsB+DKZXDvZ5XSdnMphtuLS5rPSL81rVRmWC2DMfQ2eP8j0WN
VTroSk0xedQ7Qr+9TNooi9IyzX6n1a2S1UiciEZ3ZcDbXPl/P01m+IYZyPnLv0+9
ZeioZYh1JLv3/OKsMrMLTfh2ZCj3aXwmc2Owi/wU2LS5QUOMcHH7CQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEcTCCAlkCAQAwLDEbMBkGA1UEChMSRG9ja2VyIEJvaWxlcnBsYXRlMQ0wCwYD
VQQDFAQqLnZtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyt0yFIsg
713pVnmPVVzK6Y7mbWKVUg7AAi6YxVITJ7D+f4ik9FW3mcqh75sGYwIOBmNdHfsm
Q3YL/8XrtBzzhW7UeqQqddHdbXSx2baOQsrsbuyELAFY5w+iqO1xcLTZO/aOiWXw
BWhi+MOTKJK1ZgrbKZ7DGR+/+81OH/enGxd/cy6KZ6blxg+regwPEI94MtHbmk47
ONm2ETfq8C81SgHr/fYkOJDzCZ+L1ev15Oq7aEswuuxkMlWWGhcqYnA9UjbbEZoB
Fb4wgQ26yzp3lIkcH3+qsRLGYux8b+wShY+IlFpyCOyv5z+0+rgR0IxzvhabBpFP
ZQjKwnlRQXvJCs/3G4Xfsi1MV8AD6+oEjj5sJ9t9hsuLaM76mR6W1MbIMe7E93o/
SuuodQ+yfgYzRVmDNYW5wta+x/8UuxAcwVfKkaEAlXtPCbn+cbKLlxWpA3JS1ePi
/tXMZKcLAkA5cuYN7Zv0wagNjvmSfmB0AxypMzMoS7OotF/zOaryQYi4NRi0wktt
K6UOYF0xBriDah4MF0FpFDum4YEmKnRxl9822efqlqSOHrot3R2dS5dFR+iHKW+z
kU0MIXOlvCgZcm7LGD0pRjhARlI2BjYXqM/RaaEpMQorPj/GTSra5qT6KkrtHjjh
hThRxtNnjoD1cUsKw3jfTFSaOwT8rBjByZkCAwEAAaAAMA0GCSqGSIb3DQEBCwUA
A4ICAQBsEBgC2YepuZq/8UqvKMZKVy/etDKXj7BB+QPb+leNiKD7p4LDxHJsZSH8
Ku9uMPeLfiQDn5jA41k5SlGttzvObd65RdEbO3yHpqsg05EGSDDLfaE1k2Al/qmX
/o8roPZF7+2kZthgMAgkcokS54LYqEYTGqOf3J9Ss0yRIZwhaOVebfFIbIOdpw0B
JNMIJPHTMdZrcuRVI+wR1uPLIlEJzBvxTGbTrvPU25WJFtu+EajKqXO0SHdy0yx8
uH4ykRBJRc36+oYo7nZ5D56dh7pZn3+9J64FKAOV0Q3KqMFieGy053ezuhJd70eZ
UozTgfjs3WpMzoYmKETSyl3XZSdInRe+sUlKPruTsKyg69oYxjPlrGfAmmGcCFca
TnZinT18dI92zK7OtOVkmYeYKC1lwuhftVrNMXzZuHOGpS9NNYtc4nDqDMIEOfV3
6rCdu03WjEgJ+Z67tJs16xOx9du4/EHxS2Ijn9DPfVJvYy0TgzDi1BUpjWx0KTLx
C4OQbEZ/QTWmHVbSch/hcZhzbf7SNh5RpnW4EtmcpDFjIKMfxJmoKeiTf7qnilx0
7uRvsZFKoDKRDOFiPfgMg5AOtLHziYsd9m0tJjC2GHvFuPjzOtzhnUUjmmvht170
2aqKakjST4amg7jzLcs871HX0/WjOtt29NpOz140blkKf1bisg==
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,2 @@
# compatibility for PHP and TYPO3 Docker Boilerplate
include /opt/docker/etc/nginx/vhost.common.d/*.conf;

View File

@ -0,0 +1 @@
client_max_body_size <SERVICE_NGINX_CLIENT_MAX_BODY_SIZE>;

View File

@ -0,0 +1,3 @@
location / {
try_files $uri $uri/ /<DOCUMENT_INDEX>?$query_string;
}

View File

@ -0,0 +1,2 @@
access_log /docker.stdout;
error_log /docker.stderr warn;

View File

@ -0,0 +1,7 @@
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}

View File

@ -0,0 +1,28 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _ <ALIAS_DOMAIN> docker;
root "<DOCUMENT_ROOT>";
index <DOCUMENT_INDEX>;
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
}
##############
# SSL
##############
server {
listen 443 default_server;
listen [::]:443 default_server;
server_name _ <ALIAS_DOMAIN> docker;
root "<DOCUMENT_ROOT>";
index <DOCUMENT_INDEX>;
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
include /opt/docker/etc/nginx/vhost.ssl.conf;
}

View File

@ -0,0 +1,7 @@
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
ssl_prefer_server_ciphers on;
ssl_certificate /opt/docker/etc/nginx/ssl/server.crt;
ssl_certificate_key /opt/docker/etc/nginx/ssl/server.key;

View File

@ -0,0 +1,14 @@
[group:nginx]
programs=nginxd
priority=20
[program:nginxd]
command = /opt/docker/bin/service.d/nginx.sh
process_name=%(program_name)s
startsecs = 0
autostart = true
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
IMAGE_FAMILY=$(docker-image-info family)
# Remove daemon statement (will be added as command line argument)
go-replace --mode=lineinfile --regex --regex-backrefs \
-s '^[\s#]*daemon ' -r '' \
-- /etc/nginx/nginx.conf
go-replace --mode=line --regex --regex-backrefs \
-s '^([ \t]*access_log)[ \t]*([^\t ;]+)(.*;)$' -r '$1 /docker.stdout $3' \
-s '^([ \t]*error_log)[ \t]*([^\t ;]+)(.*;)$' -r '$1 /docker.stderr $3' \
-- /etc/nginx/nginx.conf
# Enable nginx main config
mkdir -p /etc/nginx/conf.d/
ln -sf /opt/docker/etc/nginx/main.conf /etc/nginx/conf.d/10-docker.conf
rm -f \
/etc/nginx/sites-enabled/default \
/etc/nginx/conf.d/default.conf
if [[ "$IMAGE_FAMILY" == "RedHat" ]] || [[ "$IMAGE_FAMILY" == "Alpine" ]]; then
ln -sf /opt/docker/etc/nginx/nginx.conf /etc/nginx/nginx.conf
fi
# Clear log dir
rm -rf /var/lib/nginx/logs
mkdir -p /var/lib/nginx/logs
# Set log to stdout/stderr
ln -sf /var/lib/nginx/logs/access.log /docker.stdout
ln -sf /var/lib/nginx/logs/error.log /docker.stderr
# Fix rights of ssl files
chown -R root:root /opt/docker/etc/nginx/ssl
find /opt/docker/etc/nginx/ssl -type d -exec chmod 750 {} \;
find /opt/docker/etc/nginx/ssl -type f -exec chmod 640 {} \;

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Restrict php-fpm to local connection
go-replace --mode=line --regex \
-s '^[\s;]*listen[\s]*=' -r 'listen = 127.0.0.1:9000' \
--path=/opt/docker/etc/php/fpm/ \
--path-pattern='*.conf'

View File

@ -0,0 +1,24 @@
# Create tmp dir for nginx
mkdir -p /var/tmp/nginx/
# Prevent startup of nginx (ubuntu 16.04 needs it)
ln -f -s /var/lib/nginx/logs /var/log/nginx
# Replace markers
go-replace \
-s "<DOCUMENT_INDEX>" -r "$WEB_DOCUMENT_INDEX" \
-s "<DOCUMENT_ROOT>" -r "$WEB_DOCUMENT_ROOT" \
-s "<ALIAS_DOMAIN>" -r "$WEB_ALIAS_DOMAIN" \
-s "<SERVERNAME>" -r "$HOSTNAME" \
-s "<PHP_SOCKET>" -r "$WEB_PHP_SOCKET" \
-s "<PHP_TIMEOUT>" -r "$WEB_PHP_TIMEOUT" \
-s "<SERVICE_NGINX_CLIENT_MAX_BODY_SIZE>" -r "$SERVICE_NGINX_CLIENT_MAX_BODY_SIZE" \
--path=/opt/docker/etc/nginx/ \
--path-pattern='*.conf' \
--ignore-empty
if [[ -z "$WEB_PHP_SOCKET" ]]; then
## WEB_PHP_SOCKET is not set, remove PHP files
rm -f -- /opt/docker/etc/nginx/conf.d/10-php.conf
rm -f -- /opt/docker/etc/nginx/vhost.common.d/10-php.conf
fi

90
base/php-nginx/README.md Normal file
View File

@ -0,0 +1,90 @@
# php-nginx
build arm image based [webdevops/Dockerfile](https://github.com/webdevops/Dockerfile)
## 镜像链
所需镜像`php-nginx:7.4-alpine`需要上游基础镜像`php:7.4-alpine`.
而`php:7.4-alpine`又需要上游基础镜像`toolbox`.
上述镜像由 [webdevops/Dockerfile](https://github.com/webdevops/Dockerfile) 维护,均为 X86 架构.
根据每个基础镜像的 Dockerfile 文件发现了部分 X86 二进制执行文件,很难直接使用 buildx 直接构建多架构.
需手动修改相关命令支持 ARM, 尝试使用 GitHub Action 来构建多次因部分测试命令报错, 最终只能使用 ARM 服务器来一层层手动构建.
## 构建 ARM 镜像
### toolbox
```shell
cd toolbox/latest
docker build -t tookbox .
```
### php:7.4-alpine
```shell
cd php/7.4-alpine
docker build -t php:7.4-alpine .
```
### php-nginx:7.4-alpine
```shell
cd 7.4-alpine
docker build -t php-nginx:7.4-alpine .
```
## 合并镜像
上述已构建出 ARM 架构`php-nginx:7.4-alpine`, 加上官方的 X86 架构`webdevops/php-nginx:7.4-alpine`, 使用起来并不方便,推荐使用`manifest`来合并镜像.
### 推送现有镜像
制作单镜像多架构,需要先把 2 个不同架构的镜像分别推送至 docker hub 上.
所以需要 X86 和 ARM 两台服务器分别执行.
在推送之前可以使用`tag`命令规划好镜像名方便区分.
- X86 ioiox/php-nginx-x86:latest
- ARM ioiox/php-nginx-arm:latest
#### X86
> *注意请使用 X86 服务器,先下载 webdevops 的 X86 版本,重新`tag`并推送至 docker hub.*
```shell
docker pull webdevops/php-nginx:7.4-alpine
docker tag webdevops/php-nginx:7.4-alpine ioiox/php-nginx-x86:latest
docker push ioiox/php-nginx-x86:latest
```
#### ARM
> *注意请使用 ARM 服务器将上述构建的 ARM 版`php-nginx:7.4-alpine`重新`tag`并推送至 docker hub.*
```shell
docker tag php-nginx:7.4-alpine ioiox/php-nginx-arm:latest
docker push ioiox/php-nginx-arm:latest
```
### 创建 manifest 列表
创建单镜像的 manifest 列表, 建议加上`tag`,列表中包含了上文推送的 2 个架构的镜像.
> *以下操作可以在任意架构服务器执行*
```shell
docker manifest create ioiox/php-nginx:7.4-alpine \
ioiox/php-nginx-x86:latest \
ioiox/php-nginx-arm:latest
```
### 设置 manifest 列表
为对应的架构设置对应的镜像
```shell
docker manifest annotate ioiox/php-nginx:7.4-alpine \
ioiox/php-nginx-x86:latest \
--os linux --arch x86_64
docker manifest annotate ioiox/php-nginx:7.4-alpine \
ioiox/php-nginx-arm:latest \
--os linux --arch arm64 --variant v8
```
### 查看 manifest 列表
查看并检查 manifest 列表
```shell
docker manifest inspect ioiox/php-nginx:7.4-alpine
```
### 推送 manifest 列表
推送 manifest 列表至 docker hub
```shell
docker manifest push ioiox/php-nginx:7.4-alpine
```
此时已完成镜像合并,在 X86 或 ARM 服务器上使用`ioiox/php-nginx:7.4-alpine`镜像就会使用各自的架构镜像,同时可以在 docker hub 上删除刚才推送上去的`ioiox/php-nginx-x86:latest`和`ioiox/php-nginx-arm:latest`也不会影响新镜像的使用.

View File

@ -0,0 +1,262 @@
#+++++++++++++++++++++++++++++++++++++++
# Dockerfile for webdevops/php-official:7.4-alpine
# -- automatically generated --
#+++++++++++++++++++++++++++++++++++++++
# Staged baselayout builder
FROM toolbox AS baselayout
RUN mkdir -p \
/baselayout/sbin \
/baselayout/usr/local/bin \
# Baselayout scripts
&& wget -O /tmp/baselayout-install.sh https://raw.githubusercontent.com/webdevops/Docker-Image-Baselayout/master/install.sh \
&& sh /tmp/baselayout-install.sh /baselayout \
## Install go-replace
&& wget -O "/baselayout/usr/local/bin/go-replace" "https://github.com/webdevops/goreplace/releases/download/1.1.2/gr-arm64-linux" \
&& chmod +x "/baselayout/usr/local/bin/go-replace" \
&& "/baselayout/usr/local/bin/go-replace" --version \
# Install gosu
&& wget -O "/baselayout/sbin/gosu" "https://github.com/tianon/gosu/releases/download/1.10/gosu-arm64" \
&& wget -O "/tmp/gosu.asc" "https://github.com/tianon/gosu/releases/download/1.10/gosu-arm64.asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /tmp/gosu.asc "/baselayout/sbin/gosu" \
&& rm -rf "$GNUPGHOME" /tmp/gosu.asc \
&& chmod +x "/baselayout/sbin/gosu" \
&& "/baselayout/sbin/gosu" nobody true
FROM php:7.4-fpm-alpine
LABEL maintainer=info@webdevops.io \
vendor=WebDevOps.io \
io.webdevops.layout=8 \
io.webdevops.version=1.5.0
ENV TERM="xterm" \
LANG="C.UTF-8" \
LC_ALL="C.UTF-8"
ENV DOCKER_CONF_HOME=/opt/docker/ \
LOG_STDOUT="" \
LOG_STDERR=""
ENV APPLICATION_USER=application \
APPLICATION_GROUP=application \
APPLICATION_PATH=/app \
APPLICATION_UID=1000 \
APPLICATION_GID=1000
ENV PHP_SENDMAIL_PATH="/usr/sbin/sendmail -t -i"
ENV LD_PRELOAD="/usr/lib/preloadable_libiconv.so"
ENV COMPOSER_VERSION="2"
# Baselayout copy (from staged image)
COPY --from=baselayout /baselayout /
COPY conf/ /opt/docker/
RUN set -x \
# Init bootstrap
# Add community
&& echo https://dl-4.alpinelinux.org/alpine/v3.11/community/ >> /etc/apk/repositories \
# System update
&& /usr/local/bin/apk-upgrade \
# Install base stuff
&& apk-install \
bash \
ca-certificates \
openssl \
&& update-ca-certificates \
&& /usr/local/bin/generate-dockerimage-info \
## Fix su execution (eg for tests)
&& mkdir -p /etc/pam.d/ \
&& echo 'auth sufficient pam_rootok.so' >> /etc/pam.d/su
RUN set -x \
# Install services
&& chmod +x /opt/docker/bin/* \
&& apk-install \
supervisor \
wget \
curl \
vim \
sed \
tzdata \
busybox-suid \
&& chmod +s /sbin/gosu \
&& docker-run-bootstrap \
&& docker-image-cleanup
RUN set -x \
&& apk-install shadow \
&& apk-install \
# Install common tools
zip \
unzip \
bzip2 \
drill \
ldns \
openssh-client \
rsync \
patch \
git \
&& docker-run-bootstrap \
&& docker-image-cleanup
RUN set -x \
# Install php environment
&& apk-install \
imagemagick \
graphicsmagick \
ghostscript \
jpegoptim \
pngcrush \
optipng \
pngquant \
vips \
rabbitmq-c \
c-client \
# Libraries
libldap \
icu-libs \
libintl \
libpq \
libxslt \
libzip \
libmemcached \
yaml \
# Build dependencies
autoconf \
g++ \
make \
libtool \
pcre-dev \
gettext-dev \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
vips-dev \
krb5-dev \
openssl-dev \
imap-dev \
imagemagick-dev \
rabbitmq-c-dev \
openldap-dev \
icu-dev \
postgresql-dev \
libxml2-dev \
ldb-dev \
pcre-dev \
libxslt-dev \
libzip-dev \
libmemcached-dev \
yaml-dev \
# Install guetzli
&& wget https://github.com/google/guetzli/archive/master.zip \
&& unzip master.zip \
&& make -C guetzli-master \
&& cp guetzli-master/bin/Release/guetzli /usr/local/bin/ \
&& rm -rf master.zip guetzli-master \
# https://github.com/docker-library/php/issues/240
&& apk add gnu-libiconv --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted \
# Install new version of ICU
&& curl -sS -o /tmp/icu.tar.gz -L https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-src.tgz \
&& tar -zxf /tmp/icu.tar.gz -C /tmp && cd /tmp/icu/source && ./configure --prefix=/usr/local && make && make install && cd / && rm -rf /tmp/icu* \
# Install extensions
&& PKG_CONFIG_PATH=/usr/local docker-php-ext-configure intl \
&& docker-php-ext-configure gd --with-jpeg --with-freetype --with-webp \
&& docker-php-ext-configure ldap \
&& PHP_OPENSSL=yes docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& docker-php-ext-install \
bcmath \
bz2 \
calendar \
exif \
ffi \
intl \
gettext \
ldap \
mysqli \
imap \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
soap \
sockets \
tokenizer \
sysvmsg \
sysvsem \
sysvshm \
shmop \
xmlrpc \
xsl \
zip \
gd \
gettext \
opcache \
# Install extensions for PHP 7.x
# Memcached for 7.3 can currently only be built from master
&& MEMCACHED="`mktemp -d`" \
&& curl -skL https://github.com/php-memcached-dev/php-memcached/archive/master.tar.gz | tar zxf - --strip-components 1 -C $MEMCACHED \
&& docker-php-ext-configure $MEMCACHED \
&& docker-php-ext-install $MEMCACHED \
&& rm -rf $MEMCACHED \
# Install vips (only works with PHP >= 7.0)
&& pecl install apcu \
&& printf "\n" | pecl install vips \
&& pecl install redis \
&& pecl install mongodb \
&& pecl install imagick \
&& pecl install amqp \
&& pecl install yaml \
&& docker-php-ext-enable \
apcu \
redis \
imagick \
mongodb \
amqp \
vips \
yaml \
# Uninstall dev and header packages
&& apk del -f --purge \
autoconf \
g++ \
make \
libtool \
pcre-dev \
gettext-dev \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
vips-dev \
krb5-dev \
openssl-dev \
imap-dev \
rabbitmq-c-dev \
imagemagick-dev \
openldap-dev \
icu-dev \
postgresql-dev \
libxml2-dev \
ldb-dev \
pcre-dev \
libxslt-dev \
libzip-dev \
libmemcached-dev \
yaml-dev \
&& rm -f /usr/local/etc/php-fpm.d/zz-docker.conf \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer2 \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer1 --1 \
&& ln -sf /usr/local/bin/composer2 /usr/local/bin/composer \
# Enable php services
&& docker-service enable syslog \
&& docker-service enable cron \
&& docker-run-bootstrap \
&& docker-image-cleanup
WORKDIR /
EXPOSE 9000
ENTRYPOINT ["/entrypoint"]
CMD ["supervisord"]

View File

@ -0,0 +1,39 @@
{{ baselayout.dockerStage() }}
{{ docker.fromOfficial("php", "7.4-fpm-alpine") }}
{{ docker.version() }}
{{ environment.general() }}
{{ environment.base() }}
{{ environment.baseApp() }}
{{ environment.phpOfficialSendmailWorkaround() }} {# Check if needed #}
{{ environment.phpAlpineIconvWorkaround() }}
{{ environment.phpComposerVersion() }}
{{ baselayout.copy() }}
{{ docker.copy('conf/', '/opt/docker/') }}
RUN set -x \
{{ bootstrap.alpine('3.11') }}
RUN set -x \
{{ base.alpine() }} \
{{ provision.runBootstrap() }} \
{{ docker.cleanup() }}
RUN set -x \
{{ baseapp.alpine() }} \
{{ provision.runBootstrap() }} \
{{ docker.cleanup() }}
RUN set -x \
{{ php.officialAlpine(version='7.4') }} \
{{ provision.runBootstrap() }} \
{{ docker.cleanup() }}
{{ docker.workdir('/') }}
{{ docker.expose('9000') }}
{{ docker.entrypoint("/entrypoint") }}
{{ docker.cmd("supervisord") }}

View File

@ -0,0 +1 @@
8

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
exec docker-run-bootstrap

View File

@ -0,0 +1,117 @@
#!/usr/bin/env bash
shopt -s nullglob
###
# Check if current user is root
#
##
function rootCheck() {
# Root check
if [ "$(/usr/bin/whoami)" != "root" ]; then
echo "[ERROR] $* must be run as root"
exit 1
fi
}
###
# Create /docker.stdout and /docker.stderr
#
##
function createDockerStdoutStderr() {
# link stdout from docker
if [[ -n "$LOG_STDOUT" ]]; then
echo "Log stdout redirected to $LOG_STDOUT"
else
LOG_STDOUT="/proc/$$/fd/1"
fi
if [[ -n "$LOG_STDERR" ]]; then
echo "Log stderr redirected to $LOG_STDERR"
else
LOG_STDERR="/proc/$$/fd/2"
fi
ln -f -s "$LOG_STDOUT" /docker.stdout
ln -f -s "$LOG_STDERR" /docker.stderr
}
###
# Include script directory text inside a file
#
# $1 -> path
#
##
function includeScriptDir() {
if [[ -d "$1" ]]; then
for FILE in "$1"/*.sh; do
echo "-> Executing ${FILE}"
# run custom scripts, only once
. "$FILE"
done
fi
}
###
# Show deprecation notice
#
##
function deprecationNotice() {
echo ""
echo "###############################################################################"
echo "### THIS CALL IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE"
echo "###"
echo "### $*"
echo "###"
echo "###############################################################################"
echo ""
}
###
# Run "entrypoint" scripts
##
function runEntrypoints() {
###############
# Try to find entrypoint
###############
ENTRYPOINT_SCRIPT="/opt/docker/bin/entrypoint.d/${TASK}.sh"
if [ -f "$ENTRYPOINT_SCRIPT" ]; then
. "$ENTRYPOINT_SCRIPT"
fi
###############
# Run default
###############
if [ -f "/opt/docker/bin/entrypoint.d/default.sh" ]; then
. /opt/docker/bin/entrypoint.d/default.sh
fi
exit 1
}
# Run "entrypoint" provisioning
##
function runProvisionEntrypoint() {
includeScriptDir "/opt/docker/provision/entrypoint.d"
includeScriptDir "/entrypoint.d"
}
###
# List environment variables (based on prefix)
##
function envListVars() {
if [[ $# -eq 1 ]]; then
env | grep "^${1}" | cut -d= -f1
else
env | cut -d= -f1
fi
}
###
# Get environment variable (even with dots in name)
#
##
function envGetValue() {
awk "BEGIN {print ENVIRON[\"$1\"]}"
}

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
source /opt/docker/bin/config.sh
rootCheck "$0"
CONTROL_COMMAND="$1"
shift
case "$CONTROL_COMMAND" in
## ------------------------------------------
## PROVISION
## ------------------------------------------
## main roles
"provision.role")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild --tag entrypoint "$1"
;;
"provision.role.bootstrap")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap "$1"
;;
"provision.role.build")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag build [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag build "$1"
;;
"provision.role.onbuild")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag onbuild [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag onbuild "$1"
;;
"provision.role.entrypoint")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag entrypoint [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag entrypoint "$1"
;;
## startup roles
"provision.role.startup")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild --priority 50 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild --tag entrypoint --priority 50 "$1"
;;
"provision.role.startup.bootstrap")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap --priority 50 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap --priority 50 "$1"
;;
"provision.role.startup.build")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag build --priority 50 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag build --priority 50 "$1"
;;
"provision.role.startup.onbuild")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag onbuild --priority 50 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag onbuild --priority 50 "$1"
;;
"provision.role.startup.entrypoint")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag entrypoint --priority 50 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag entrypoint --priority 50 "$1"
;;
## finish roles
"provision.role.finish")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild --priority 200 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap --tag build --tag onbuild --tag entrypoint --priority 200 "$1"
;;
"provision.role.finish.bootstrap")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag bootstrap --priority 200 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag bootstrap --priority 200 "$1"
;;
"provision.role.finish.build")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag build --priority 200 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag build --priority 200 "$1"
;;
"provision.role.finish.onbuild")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag onbuild --priority 200 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag onbuild --priority 200 "$1"
;;
"provision.role.finish.entrypoint")
deprecationNotice " Please use >>/opt/docker/bin/provision add --tag entrypoint --priority 200 [role]<< for adding provision roles"
/opt/docker/bin/provision add --tag entrypoint --priority 200 "$1"
;;
## ------------------------------------------
## Service
## ------------------------------------------
"service.enable")
deprecationNotice " Please use >>docker-service-enable [service]<<"
docker-service-enable "$1"
;;
"service.disable")
deprecationNotice " Please use >>docker-service-disable [service]<<"
docker-service-disable "$1"
;;
## ------------------------------------------
## Version
## ------------------------------------------
"version.get")
cat /opt/docker/VERSION
;;
"version.require.min")
EXPECTED_VERSION="$1"
CURRENT_VERSION="$(cat /opt/docker/VERSION)"
if [ "$CURRENT_VERSION" -lt "$EXPECTED_VERSION" ]; then
echo "-----------------------------------------------------------"
echo "--- This docker image is not up2date!"
echo "--- "
echo "--- Version expected min: $EXPECTED_VERSION"
echo "--- Version current: $CURRENT_VERSION"
echo "--- "
echo "--- Run 'docker pull <imagename>' to update image"
echo "-----------------------------------------------------------"
exit 1
fi
;;
"version.require.max")
EXPECTED_VERSION="$1"
CURRENT_VERSION="$(cat /opt/docker/VERSION)"
if [ "$CURRENT_VERSION" -gt "$EXPECTED_VERSION" ]; then
echo "-----------------------------------------------------------"
echo "--- This docker image is too new!"
echo "--- "
echo "--- Version expected max: $EXPECTED_VERSION"
echo "--- Version current: $CURRENT_VERSION"
echo "-----------------------------------------------------------"
exit 1
fi
;;
"buildtime.get")
cat /opt/docker/BUILDTIME
;;
*)
echo "[ERROR] Invalid controll command: \"${CONTROL_COMMAND}\""
exit 1
;;
esac

View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
#############################################
## Run CLI_SCRIPT from environment variable
#############################################
if [ -n "${CLI_SCRIPT}" ]; then
if [ -n "$APPLICATION_USER" ]; then
# Run as EFFECTIVE_USER
shift
exec gosu "${APPLICATION_USER}" ${CLI_SCRIPT} "$@"
else
# Run as root
exec ${CLI_SCRIPT} "$@"
fi
else
echo "[ERROR] No CLI_SCRIPT in in docker environment defined"
exit 1
fi

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
exec "$@"

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
#############################################
## NOOP (no operation)
#############################################
exec tail -f /dev/null

View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
#############################################
## Root shell
#############################################
if [ "$#" -eq 1 ]; then
## No command, fall back to interactive shell
exec bash
else
## Exec root command
shift
exec "$@"
fi

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
#############################################
## Supervisord (start daemons)
#############################################
## Start services
exec /opt/docker/bin/service.d/supervisor.sh

View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
if [[ -z "$CONTAINER_UID" ]]; then
export CONTAINER_UID="application"
fi
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
# auto elevate privileges (if container is not started as root)
if [[ "$UID" -ne 0 ]]; then
export CONTAINER_UID="$UID"
exec gosu root "$0" "$@"
fi
# remove suid bit on gosu
chmod -s /sbin/gosu
trap 'echo sigterm ; exit' SIGTERM
trap 'echo sigkill ; exit' SIGKILL
# sanitize input and set task
TASK="$(echo $1| sed 's/[^-_a-zA-Z0-9]*//g')"
source /opt/docker/bin/config.sh
createDockerStdoutStderr
if [[ "$UID" -eq 0 ]]; then
# Only run provision if user is root
if [ "$TASK" == "supervisord" -o "$TASK" == "noop" ]; then
# Visible provisioning
runProvisionEntrypoint
else
# Hidden provisioning
runProvisionEntrypoint > /dev/null
fi
fi
#############################
## COMMAND
#############################
runEntrypoints "$@"

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Install ansible if not installed
if [ -z "`which ansible-playbook`" ]; then
docker-ansible-install
fi
exec /opt/docker/bin/provision.py "$@"

View File

@ -0,0 +1,328 @@
#!/usr/bin/env python
import os
import argparse
import json
import sys
from string import Template
from subprocess import call
import tempfile
import time
STORAGE = '/opt/docker/etc/.registry/provision.json'
PROVISION_DIR = '/opt/docker/provision/'
PLAYBOOK_TAGS=['bootstrap', 'build', 'onbuild', 'entrypoint']
PLAYBOOK = Template(
"""---
- hosts: all
vars_files:
- ./variables-webdevops.yml
- ./variables.yml
roles:
- $roles
""")
def readJson():
ret = {}
# create registry directory if it doesn't exists
if not os.path.exists(os.path.dirname(STORAGE)):
os.mkdir(os.path.dirname(STORAGE))
# try to read file
if os.path.isfile(STORAGE):
f=open(STORAGE).read()
ret = json.loads(f)
return ret
def saveJson(data):
with open(STORAGE, 'w') as f:
json.dump(data, f)
def buildRoleList(tags):
json = readJson()
roleList = {}
# fetch roles list for each tag
for tag in tags:
if tag in json:
for role in json[tag]:
roleRow = json[tag][role]
if role not in roleList:
roleList[role] = {}
if 'tags' not in roleList[role]:
roleList[role]['tags'] = {}
roleList[role]['role'] = role
roleList[role]['added'] = roleRow['added']
roleList[role]['priority'] = roleRow['priority']
roleList[role]['tags'][tag] = tag
return roleList
def buildSortedRoleList(tags):
roleList = buildRoleList(tags)
# sort list
roleList = sorted(roleList, key=lambda x: (roleList[x]['priority'], roleList[x]['added']))
return roleList
def buildPlaybook(roleList):
## build playbook
ret = PLAYBOOK.substitute(
roles = "\n - ".join(roleList)
)
return ret
def buildPlaybookFromArgs(args):
roleList = []
## add roles from tag (if use registry is active)
if args.useRegistry and args.tags:
roleList.extend(buildSortedRoleList(args.tags))
## add roles from command arguments
if args.roles:
for role in args.roles:
roleList.extend(role.split(','))
if roleList:
return buildPlaybook(roleList)
else:
return False
def actionRun(args):
if args.playbook:
## predefined playbook
playbook = args.playbook
else:
## dynamic playbook
playbookContent = buildPlaybookFromArgs(args)
if playbookContent:
f = tempfile.NamedTemporaryFile(dir=PROVISION_DIR, prefix='playbook.', suffix='.yml', delete=False)
f.write(playbookContent)
f.close()
playbook = f.name
else:
## nothing to do
sys.exit(0)
## build ansible command with args
cmd = [
'ansible-playbook',
playbook,
'-i', 'localhost,',
'--connection=local',
]
if args.tags:
cmd.extend([
'--tags=' + ','.join(args.tags)
])
if args.args:
cmd.extend(args.args)
## run ansible
retval = call(cmd)
## cleanup dynamic playbook
if not args.playbook:
os.unlink(playbook)
sys.exit(retval)
def actionPlaybook(args):
playbook = buildPlaybookFromArgs(args)
if playbook:
print playbook
else:
sys.exit(1)
def actionList(args):
json = readJson()
list = {}
for tag in args.tags:
if tag in json:
for role in json[tag]:
print role
def actionAdd(args):
json = readJson()
for tag in args.tags:
for role in args.role:
if tag not in json:
json[tag] = {}
json[tag][role] = {
'name': role,
'added': int(time.time()),
'priority': args.priority
}
saveJson(json)
def actionSummary(args):
# list all roles in each possible tag
for tag in PLAYBOOK_TAGS:
roleList = buildRoleList([tag])
if roleList:
maxLength = len(max(roleList.keys(), key=len))
print "Roles in " + tag + ":"
for role in roleList:
print ' - ' + role.ljust(maxLength, ' ') + ' [priority: ' + str(roleList[role]['priority']) + ']'
print ''
def main(args):
actions = {
'list': actionList,
'add': actionAdd,
'summary': actionSummary,
'playbook': actionPlaybook,
'run': actionRun
}
func = actions.get(args.action, lambda: "nothing")
return func(args)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(
title='subcommands',
dest='action'
)
###################################
## SUMMARY command
summary = subparsers.add_parser('summary')
###################################
## RUN command
run = subparsers.add_parser('run')
run.add_argument(
'--tag',
dest='tags',
choices=PLAYBOOK_TAGS,
required=True,
action='append',
help='Ansible tag'
)
run.add_argument(
'--playbook',
dest='playbook',
help='Ansible playbook'
)
run.add_argument(
'--use-registry',
dest='useRegistry',
action='store_true',
help='Use registred roles'
)
run.add_argument(
'--role',
dest='roles',
action='append',
help='Ansible role'
)
run.add_argument('args', nargs=argparse.REMAINDER)
###################################
## PLAYBOOK command
playbook = subparsers.add_parser('playbook')
playbook.add_argument(
'--tag',
dest='tags',
choices=PLAYBOOK_TAGS,
required=True,
action='append',
help='Ansible tag'
)
playbook.add_argument(
'--use-registry',
dest='useRegistry',
action='store_true',
help='Use registred roles'
)
playbook.add_argument(
'--role',
dest='roles',
action='append',
help='Ansible tag'
)
playbook.add_argument('args', nargs=argparse.REMAINDER)
###################################
## LIST command
list = subparsers.add_parser('list')
list.add_argument(
'--tag',
dest='tags',
choices=PLAYBOOK_TAGS,
required=True,
action='append',
help='Ansible tag'
)
list.add_argument('args', nargs=argparse.REMAINDER)
###################################
## ADD command
add = subparsers.add_parser('add')
add.add_argument(
'--tag',
dest='tags',
choices=PLAYBOOK_TAGS,
required=True,
action='append',
help='Ansible tag'
)
add.add_argument(
'--priority',
type=int,
default=100,
dest='priority',
help='Priority for role [default 100, 1 is most important]'
)
add.add_argument('role', metavar='roles', nargs='+', help='Ansible roles')
add.add_argument('args', nargs=argparse.REMAINDER)
## Execute
args = parser.parse_args()
main(args)

View File

@ -0,0 +1,16 @@
# Install crontab files
if [[ -d "/opt/docker/etc/cron" ]]; then
mkdir -p /etc/cron.d/
find /opt/docker/etc/cron -type f | while read CRONTAB_FILE; do
# fix permissions
chmod 0644 -- "$CRONTAB_FILE"
# add newline, cron needs this
echo >> "$CRONTAB_FILE"
# Install files
cp -a -- "$CRONTAB_FILE" "/etc/cron.d/$(basename "$CRONTAB_FILE")"
done
fi

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_CRON_OPTS" ]]; then SERVICE_CRON_OPTS=""; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/cron.d/"
exec /usr/sbin/crond -f $SERVICE_CRON_OPTS

View File

@ -0,0 +1,37 @@
# Create dnsmasq.d directory if not exists
mkdir -p -- /etc/dnsmasq.d/
# Enable /etc/dnsmasq.d/
go-replace --mode=lineinfile --once \
-s 'conf-dir' -r 'conf-dir=/etc/dnsmasq.d/,*.conf' \
-- /etc/dnsmasq.conf
## clear dns file
echo > /etc/dnsmasq.d/webdevops.conf
if [ ! -f /etc/resolv.conf.original ]; then
cp -a /etc/resolv.conf /etc/resolv.conf.original
## set forward servers
cat /etc/resolv.conf.original | grep nameserver | sed 's/nameserver /server=/' > /etc/dnsmasq.d/forward.conf
## set dnsmasq to main nameserver
echo "nameserver 127.0.0.1" > /etc/resolv.conf
fi
# Add own VIRTUAL_HOST as loopback
if [[ -n "${VIRTUAL_HOST+x}" ]]; then
# split comma by space
VIRTUAL_HOST_LIST=${VIRTUAL_HOST//,/$'\n'}
# replace *.domain for dns specific .domain wildcard
VIRTUAL_HOST_LIST=${VIRTUAL_HOST_LIST/\*./.}
# no support for .*
VIRTUAL_HOST_LIST=${VIRTUAL_HOST_LIST/.\*/.}
for DOMAIN in $VIRTUAL_HOST_LIST; do
echo "address=/${DOMAIN}/127.0.0.1" >> /etc/dnsmasq.d/webdevops.conf
done
fi

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_DNSMASQ_OPTS" ]]; then SERVICE_DNSMASQ_OPTS=""; fi
if [[ -z "$SERVICE_DNSMASQ_USER" ]]; then SERVICE_DNSMASQ_USER="root"; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/dnsmasq.d/"
exec dnsmasq --keep-in-foreground --user="$SERVICE_DNSMASQ_USER" $SERVICE_DNSMASQ_OPTS

View File

@ -0,0 +1,12 @@
# setup user env
FPM_POOL_CONF="/opt/docker/etc/php/fpm/pool.d/application.conf"
## Setup container uid
if [[ -n "$CONTAINER_UID" ]]; then
echo "Setting php-fpm user to $CONTAINER_UID"
go-replace --mode=line --regex \
-s '^[\s;]*user[\s]*=' -r "user = $CONTAINER_UID" \
-s '^[\s;]*group[\s]*=' -r "group = $CONTAINER_UID" \
--path=/opt/docker/etc/php/fpm/ \
--path-pattern='*.conf'
fi

View File

@ -0,0 +1,38 @@
#
# Workaround for old php-fpm versions which don't have clear_env setting
#
VARIABLE_LIST="; Workaround for missing clear_env feature in PHP-FPM"
# For each exported variable
for envVariable in $(printenv|cut -f1 -d=); do
case "$envVariable" in
"_"|"PATH"|"PWD")
## ignore this variables
;;
*)
## get content of variable
envVariableContent="${!envVariable}"
## php-fpm requires that env variable has to be filled with content
if [[ -n "$envVariableContent" ]]; then
## quote quotes
envVariableContent=${envVariableContent//\"/\\\"}
## add to list
VARIABLE_LIST="${VARIABLE_LIST}"$'\n'"env[${envVariable}] = \"${envVariableContent}\""
fi
;;
esac
done
# Replace ;#CLEAR_ENV_WORKAROUND# with environment variable list for all php-fpm pool files
go-replace \
-s ";#CLEAR_ENV_WORKAROUND#" -r "$VARIABLE_LIST" \
--path=/opt/docker/etc/php/fpm/pool.d/ \
--path-pattern='*.conf' \
--ignore-empty

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_PHPFPM_OPTS" ]]; then SERVICE_PHPFPM_OPTS=""; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/php-fpm.d/"
exec /usr/local/bin/php-fpm --nodaemonize $SERVICE_PHPFPM_OPTS

View File

@ -0,0 +1,30 @@
# force new copy of hosts there (otherwise links could be outdated)
mkdir -p /var/spool/postfix/etc
cp -f /etc/hosts /var/spool/postfix/etc/hosts
cp -f /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
cp -f /etc/services /var/spool/postfix/etc/services
go-replace --mode=line --regex -s '^[\s]*myhostname[\s]*=.*' -r "myhostname = $HOSTNAME"
# General
go-replace --mode=lineinfile --regex \
-s '^[\s]*myhostname[\s]*=.*.*' -r "myhostname = $HOSTNAME" \
-s '^[\s]*inet_interfaces[\s]*=.*' -r "inet_interfaces = 127.0.0.1" \
-- /etc/postfix/main.cf
## REPLAYHOST
if [[ -n "${POSTFIX_RELAYHOST+x}" ]]; then
go-replace --mode=lineinfile --regex \
-s '^[\s]*relayhost[\s]*=.*' -r "relayhost = $POSTFIX_RELAYHOST" \
-- /etc/postfix/main.cf
fi
## MYNETWORKS
if [[ -n "${POSTFIX_MYNETWORKS+x}" ]]; then
go-replace --mode=lineinfile --regex \
-s '^[\s]*mynetworks[\s]*=.*' -r "mynetworks = $POSTFIX_MYNETWORKS" \
-- /etc/postfix/main.cf
fi
# generate aliases db
newaliases || :

View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
# postfix-wrapper.sh, version 0.1.0
#
# You cannot start postfix in some foreground mode and
# it's more or less important that docker doesn't kill
# postfix and its chilren if you stop the container.
#
# Use this script with supervisord and it will take
# care about starting and stopping postfix correctly.
#
# supervisord config snippet for postfix-wrapper:
#
# [program:postfix]
# process_name = postfix
# command = /path/to/postfix-wrapper.sh
# startsecs = 0
# autorestart = false
#
# Init vars
if [[ -z "$SERVICE_POSTFIX_OPTS" ]]; then SERVICE_POSTFIX_OPTS=""; fi
source /opt/docker/bin/config.sh
trap "postfix stop" SIGINT
trap "postfix stop" SIGTERM
trap "postfix reload" SIGHUP
includeScriptDir "/opt/docker/bin/service.d/postfix.d/"
# start postfix
postfix start $SERVICE_POSTFIX_OPTS
# lets give postfix some time to start
sleep 3
# wait until postfix is dead (triggered by trap)
if [[ -f /var/spool/postfix/pid/master.pid ]]; then
while kill -0 "$(cat /var/spool/postfix/pid/master.pid 2>/dev/null)" &>/dev/null; do
sleep 5
done
fi

View File

@ -0,0 +1,7 @@
# Init ssh privilege separation directory
mkdir -p /var/run/sshd
chown root:root /var/run/sshd
chmod 755 /var/run/sshd
# generate host keys
ssh-keygen -A

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_SSH_OPTS" ]]; then SERVICE_SSH_OPTS=""; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/ssh.d/"
exec /usr/sbin/sshd -D $SERVICE_SSH_OPTS

View File

@ -0,0 +1 @@
# placeholder

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_SUPERVISOR_OPTS" ]]; then SERVICE_SUPERVISOR_OPTS=""; fi
if [[ -z "$SERVICE_SUPERVISOR_USER" ]]; then SERVICE_SUPERVISOR_USER="root"; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/supervisor.d/"
exec supervisord -c /opt/docker/etc/supervisor.conf --logfile /dev/null --pidfile /dev/null --user "$SERVICE_SUPERVISOR_USER" $SERVICE_SUPERVISOR_OPTS

View File

@ -0,0 +1,10 @@
# If /dev/log is either a named pipe or it was placed there accidentally,
# e.g. because of the issue documented at https://github.com/phusion/baseimage-docker/pull/25,
# then we remove it.
if [ ! -S /dev/log ]; then rm -f /dev/log; fi
if [ ! -S /var/lib/syslog-ng/syslog-ng.ctl ]; then rm -f /var/lib/syslog-ng/syslog-ng.ctl; fi
if [[ ! -p /docker.stdout ]]; then
# Switch to file (tty docker mode)
go-replace -s 'pipe("/docker.stdout")' -r 'file("/docker.stdout")' -- /opt/docker/etc/syslog-ng/syslog-ng.conf
fi

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Init vars
if [[ -z "$SERVICE_SYSLOG_OPTS" ]]; then SERVICE_SYSLOG_OPTS=""; fi
source /opt/docker/bin/config.sh
includeScriptDir "/opt/docker/bin/service.d/syslog-ng.d/"
exec syslog-ng -F --no-caps -p /var/run/syslog-ng.pid $SYSLOGNG_OPTS $SERVICE_SYSLOG_OPTS

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -o pipefail ## trace ERR through pipes
set -o errtrace ## trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
if [[ "$#" -ne 1 ]]; then
echo "Usage: $0 <file>"
exit 1
fi
SOURCE_FILE="$1"
BACKUP_FILE="$(dirname "$1")/.$(basename "$1").bak"
if [[ -f "$BACKUP_FILE" ]]; then
## Backup file exists
## -> container was restarted
## -> restoring configuration
cp -a -- "$BACKUP_FILE" "$SOURCE_FILE"
else
## Backup file DOESN'T exists
## -> container first startup
## -> backup configuration
cp -a -- "$SOURCE_FILE" "$BACKUP_FILE"
fi

View File

@ -0,0 +1,77 @@
#!/usr/bin/env bash
IMAGE_FAMILY=$(docker-image-info family)
# Installation
case "$IMAGE_FAMILY" in
Debian|Ubuntu)
apt-install \
python-minimal \
python-setuptools \
python-pip \
python-paramiko \
python-jinja2 \
python-dev \
libffi-dev \
libssl-dev \
build-essential
pip install --upgrade pip
hash -r
pip install --no-cache-dir ansible
# Cleanup
apt-get purge -y -f --force-yes \
python-dev \
build-essential \
libssl-dev \
libffi-dev
chmod 750 /usr/local/bin/ansible*
;;
RedHat)
yum-install \
epel-release \
PyYAML \
python-jinja2 \
python-httplib2 \
python-keyczar \
python-paramiko \
python-setuptools \
python-setuptools-devel \
libffi \
python-devel \
libffi-devel
easy_install pip
pip install --upgrade pip
hash -r
pip install --no-cache-dir ansible
# Cleanup
yum erase -y python-devel
chmod 750 /usr/bin/ansible*
;;
Alpine)
apk-install \
python \
python-dev \
py-setuptools \
py-crypto \
py2-pip \
py-cparser \
py-cryptography \
py-markupsafe \
py-cffi \
py-yaml \
py-jinja2 \
py-paramiko
pip install --upgrade pip
hash -r
pip install --no-cache-dir ansible
# Cleanup
apk del python-dev
chmod 750 /usr/bin/ansible*
;;
esac
docker-image-cleanup

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
source /opt/docker/bin/config.sh
rootCheck "$0"
if [[ "$#" -eq 0 ]]; then
echo "Usage: $0 '<cronjob line>'"
exit 1
fi
# create crontab file
touch /etc/cron.d/webdevops-docker
chmod 0644 /etc/cron.d/webdevops-docker
for CRONJOB_LINES in "$@"; do
echo "$CRONJOB_LINES" >> /etc/cron.d/webdevops-docker
done
# Add required newline at end
echo >> /etc/cron.d/webdevops-docker

View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
# Defaults
PHP_INI_FILE="/opt/docker/etc/php/php.ini"
PHP_VALUE_RAW=0
PHP_KEY=
PHP_VALUE=
for arg in "$@"; do
case "$arg" in
--raw)
PHP_VALUE_RAW=1
shift
;;
esac
done
if [[ "$#" -le 2 ]]; then
echo "Usage: $(basename "$0") [--raw] <setting> <value>"
exit 1
fi
PHP_SETTING_KEY=$1
shift
PHP_SETTING_VALUE="$@"
if [[ "$PHP_VALUE_RAW" -eq 0 ]]; then
case "$PHP_SETTING_VALUE" in
''|*[!0-9]*)
# non numeric
PHP_SETTING_VALUE="\"${PHP_SETTING_VALUE}\""
;;
esac
fi
echo "$(basename "$0"): Setting php setting: ${PHP_SETTING_KEY} = ${PHP_SETTING_VALUE}"
echo "${PHP_SETTING_KEY} = ${PHP_SETTING_VALUE}" >> "$PHP_INI_FILE"

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
# wrapper
exec /opt/docker/bin/provision "$@"

View File

@ -0,0 +1,89 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
if [[ "$#" -le 1 ]]; then
echo "Usage: $0 <command> <service>"
exit 1
fi
SERVICE_COMMAND=$1
shift
for SERVICE in "$@"; do
RUN_FILE="/opt/docker/bin/service.d/${SERVICE}.sh"
SERVICE_FILE="/opt/docker/etc/supervisor.d/${SERVICE}.conf"
PROVISION_FILE="/opt/docker/provision/service.d/${SERVICE}.sh"
case "$SERVICE_COMMAND" in
enable)
# Run on demand installation/provisioning
if [[ -f "$PROVISION_FILE" ]]; then
echo "Running provisioning for ${SERVICE}, please wait..."
## execute scripts
. "$PROVISION_FILE"
## remove directory (one run time)
rm -f -- "$PROVISION_FILE"
fi
## Enable service
if [[ -f "$SERVICE_FILE" ]]; then
go-replace --mode=lineinfile \
-s 'autostart =' -r 'autostart = true' \
-- "$SERVICE_FILE"
else
echo "[ERROR] Service '${SERVICE}' not found (tried ${SERVICE_FILE})"
exit 1
fi
;;
disable)
## Disable service
if [[ -f "$SERVICE_FILE" ]]; then
go-replace --mode=lineinfile \
-s 'autostart =' -r 'autostart = false' \
-- "$SERVICE_FILE"
else
echo "[ERROR] Service '${SERVICE}' not found (tried ${SERVICE_FILE})"
exit 1
fi
;;
install)
# Run on demand installation/provisioning
if [[ -f "$PROVISION_FILE" ]]; then
echo "Running provisioning for ${SERVICE}, please wait..."
## execute scripts
. "$PROVISION_FILE"
## remove directory (one run time)
rm -f -- "$PROVISION_FILE"
fi
;;
run)
if [[ -f "$RUN_FILE" ]]; then
exec "$RUN_FILE"
else
echo "[ERROR] Service '${SERVICE}' not found (tried ${RUN_FILE})"
exit 1
fi
;;
stop|start|restart|status|pid|check)
service "${SERVICE}" "$SERVICE_COMMAND"
;;
*)
echo "[ERROR] $SERVICE_COMMAND is not a valid command"
exit 1
;;
esac
done

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
exec docker-service disable "$@"

View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
exec docker-service enable "$@"

View File

@ -0,0 +1,86 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
# Root check
if [ "$(/usr/bin/whoami)" != "root" ]; then
echo "[ERROR] Must be run as root"
exit 1
fi
function serviceHelp() {
echo "Usage: $(basename "$0") <servicename> <stop|start|restart|pid|status|check>"
}
function getServicePid() {
local serviceName="$1"
local servicePid=$(supervisorctl pid "${serviceName}:${serviceName}d")
if [[ -z "$servicePid" ]] || [[ "$servicePid" == "0" ]]; then
echo "not running"
exit 1
fi
echo $servicePid
}
# Param check
if [ "$#" -lt 2 ]; then
echo "[ERROR] Missing parameters"
serviceHelp
exit 1
fi
#############################
# Param init
#############################
SERVICENAME="$1"
ACTION="$2"
#############################
# Service aliases
#############################
case "$SERVICENAME" in
apache2|httpd)
SERVICENAME="apache"
;;
esac
#############################
# Action runner
#############################
case "$ACTION" in
stop|start|restart|status)
exec supervisorctl "$ACTION" "${SERVICENAME}:${SERVICENAME}d"
;;
pid)
echo $(getServicePid "${SERVICENAME}")
;;
check)
FIRST_PID=$(getServicePid "${SERVICENAME}")
sleep 5
SECOND_PID=$(getServicePid "${SERVICENAME}")
if [[ "$FIRST_PID" == "$SECOND_PID" ]]; then
echo "ok"
exit 0
else
echo "not running"
exit 1
fi
;;
*)
echo "[ERROR] Invalid action"
serviceHelp
exit 1
;;
esac

View File

@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
function versionCompare () {
if [[ $1 == $2 ]]
then
echo -n '='
return
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
echo -n '>'
return
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
echo -n '<'
return
fi
done
echo -n '='
}
versionCompare "$1" "$2"

View File

@ -0,0 +1,12 @@
/var/log/php5-fpm/fpm.log
/var/log/php5-fpm/access.log
/var/log/php5-fpm/slow.log
/var/log/php5-fpm/error.log {
missingok
notifempty
sharedscripts
delaycompress
postrotate
/bin/kill -SIGUSR1 `cat /var/run/php5-fpm.pid` 2>/dev/null || true
endscript
}

View File

@ -0,0 +1,38 @@
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
/bin/kill -HUP `cat /var/run/syslog-ng.pid 2> /dev/null` > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslog-ng.pid 2> /dev/null` > /dev/null
supervisorctl restart syslog-ng-stdout > /dev/null
endscript
}

View File

@ -0,0 +1 @@
; placeholder

View File

@ -0,0 +1,34 @@
; -------------------------------------
; Docker Webdevops PHP configuration
; -------------------------------------
; this file will overwrite default php.ini settings
display_errors = 0
log_errors = 1
short_open_tag = Off
variables_order = 'GPCS'
request_order = 'GP'
allow_url_fopen = On
allow_url_include = Off
memory_limit = 512M
max_execution_time = 300
max_input_time = 300
post_max_size = 50M
upload_max_filesize = 50M
max_input_vars = 5000
expose_php = Off
date.timezone = UTC
mysql.default_host = mysql
mysqli.default_host = mysql
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 7963
opcache.fast_shutdown = 1

View File

@ -0,0 +1,20 @@
[supervisord]
nodaemon=true
[unix_http_server]
file = /.supervisor.sock
chmod = 0700
chown = root:root
username = root
password = {SHA}e982f17bcbe0f724063b708a4f76db211a999304
[supervisorctl]
serverurl = unix:///.supervisor.sock
username = root
password = docker
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[include]
files = /opt/docker/etc/supervisor.d/*.conf

View File

@ -0,0 +1,14 @@
[group:cron]
programs=crond
priority=25
[program:crond]
command = /opt/docker/bin/service.d/cron.sh
process_name=%(program_name)s
startsecs = 0
autostart = false
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,14 @@
[group:dnsmasq]
programs=dnsmasqd
priority=15
[program:dnsmasqd]
command = /opt/docker/bin/service.d/dnsmasq.sh
process_name=%(program_name)s
startsecs = 0
autostart = false
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,15 @@
[group:php-fpm]
programs=php-fpmd
priority=20
[program:php-fpmd]
command = /opt/docker/bin/service.d/php-fpm.sh
process_name=%(program_name)s
startsecs = 0
autostart = true
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,15 @@
[group:postfix]
programs=postfixd
priority=30
[program:postfixd]
directory = /etc/postfix
command = /opt/docker/bin/service.d/postfix.sh
process_name=%(program_name)s
startsecs = 0
autostart = false
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,14 @@
[group:ssh]
programs=sshd
priority=30
[program:sshd]
command = /opt/docker/bin/service.d/ssh.sh
process_name=%(program_name)s
startsecs=0
autostart = false
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,13 @@
[group:syslog]
programs=syslogd
priority=10
[program:syslogd]
command = /opt/docker/bin/service.d/syslog-ng.sh
process_name=%(program_name)s
autostart = false
autorestart = true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

View File

@ -0,0 +1,48 @@
@version: 3.5
template t_isostamp {
# syslog-t_isostamp START
template("[SYSLOG] $MSGHDR$MSG\n");
# syslog-t_isostamp END
};
options {
# syslog-options START
file-template(t_isostamp);
chain_hostnames(off);
flush_lines(0);
use-dns(no);
use_fqdn(no);
owner("root");
group("adm");
perm(0640);
stats_freq(0);
# syslog-options START
};
source s_src {
# syslog-s_src START
unix-stream("/dev/log");
internal();
# syslog-s_src END
};
filter f_filter {
# syslog-f_filter START
not facility(auth, authpriv);
# syslog-f_filter END
};
destination d_all {
# syslog-d_all START
pipe("/docker.stdout");
# syslog-d_all END
};
log {
# syslog-log START
source(s_src);
filter(f_filter);
destination(d_all);
# syslog-log START
};

View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Link main entrypoint script to /entrypoint
ln -sf /opt/docker/bin/entrypoint.sh /entrypoint
# Link entrypoint cmd shortcut conf directory to /entrypoint.cmd
ln -sf /opt/docker/bin/entrypoint.d /entrypoint.cmd
# Create /entrypoint.d
mkdir -p /entrypoint.d
chmod 700 /entrypoint.d
chown root:root /entrypoint.d

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash

View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
PHP_VERSION=$(php -r 'echo phpversion();' | cut -d '-' -f 1)
IMAGE_FAMILY=$(docker-image-info family)

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Remove /usr/sbin/service (images have custom service script)
rm -rf /usr/sbin/service
# Remove existing supervisor configuration
rm -rf -- /etc/supervisor*
# Link supervisor configuration script
ln -sf /opt/docker/etc/supervisor.conf /etc/supervisord.conf

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Add group
addgroup -g "$APPLICATION_GID" "$APPLICATION_GROUP"
# Add user
adduser -D -u "$APPLICATION_UID" -h "/home/application" -s /bin/bash -G $APPLICATION_GROUP "$APPLICATION_USER"

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
PHP_CLEAR_ENV_AVAILABLE=1
PHP_ETC_DIR=/usr/local/etc/php
PHP_MAIN_CONF=/usr/local/etc/php-fpm.conf
PHP_POOL_CONF=www.conf
PHP_POOL_DIR=/usr/local/etc/php-fpm.d
PHP_FPM_BIN=/usr/local/sbin/php-fpm
PHP_MOD_INI_DIR=/usr/local/etc/php/conf.d

View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Create /app folder
mkdir -p /app
chown "$APPLICATION_USER":"$APPLICATION_GROUP" /app

View File

@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Rename pool file file to application.conf
if [[ ! -f "/opt/docker/etc/php/fpm/pool.d/application.conf" ]]; then
# Move php-fpm pool directory file to /opt/docker/etc/php/
mv -- "$PHP_POOL_DIR" /opt/docker/etc/php/fpm/pool.d
mv -- "/opt/docker/etc/php/fpm/pool.d/${PHP_POOL_CONF}" /opt/docker/etc/php/fpm/pool.d/application.conf
fi
# Remove php-fpm pool directory
rm -rf -- "$PHP_POOL_DIR"
# Symlink php-fpm pool file to original destination
ln -sf -- /opt/docker/etc/php/fpm/pool.d "$PHP_POOL_DIR"
# Configure php-fpm pool (application.conf)
go-replace --mode=lineinfile --regex \
-s '^[\s;]*catch_workers_output[\s]*=' -r 'catch_workers_output = yes' \
-s '^[\s;]*access.format[\s]*=' -r 'access.format = "[php-fpm:access] %R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"' \
-s '^[\s;]*access.log[\s]*=' -r 'access.log = /docker.stdout' \
-s '^[\s;]*slowlog[\s]*=' -r 'slowlog = /docker.stderr' \
-s '^[\s;]*php_admin_value\[error_log\][\s]*=' -r 'php_admin_value[error_log] = /docker.stderr' \
-s '^[\s;]*php_admin_value\[log_errors\][\s]*=' -r 'php_admin_value[log_errors] = on' \
-s '^[\s;]*listen.allowed_clients[\s]*=' -r ";listen.allowed_clients" \
-- /opt/docker/etc/php/fpm/pool.d/application.conf
# Fix user setting
go-replace --mode=line --regex \
-s '^[\s;]*user[\s]*=' -r "user = $APPLICATION_USER" \
-s '^[\s;]*group[\s]*=' -r "group = $APPLICATION_GROUP" \
--path=/opt/docker/etc/php/fpm/ \
--path-pattern='*.conf'
if [[ "$PHP_CLEAR_ENV_AVAILABLE" -eq 1 ]]; then
# Clear env setting available, disable clearing of environment variables
go-replace --mode=lineinfile --regex \
-s '^[\s;]*clear_env[\s]*=' -r 'clear_env = no' \
-- /opt/docker/etc/php/fpm/pool.d/application.conf
rm -f /opt/docker/bin/service.d/php-fpm.d/11-clear-env.sh
else
# Append clear env workaround in php-fpm pool (old php-fpm versions)
echo ';#CLEAR_ENV_WORKAROUND#' >> /opt/docker/etc/php/fpm/pool.d/application.conf
fi

View File

@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Link main php-fpm binary
ln -sf -- "$PHP_FPM_BIN" /usr/local/bin/php-fpm
# Move php-fpm main file to /opt/docker/etc/php/fpm/ and create symlink
if [[ ! -f /opt/docker/etc/php/fpm/php-fpm.conf ]]; then
mv -- "$PHP_MAIN_CONF" /opt/docker/etc/php/fpm/php-fpm.conf
else
rm -f -- "PHP_MAIN_CONF"
fi
ln -sf -- /opt/docker/etc/php/fpm/php-fpm.conf "$PHP_MAIN_CONF"
# Configure php-fpm main (all versions)
go-replace --mode=lineinfile --regex \
--lineinfile-after='\[global\]' \
-s '^[\s;]*error_log[\s]*=' -r 'error_log = /docker.stderr' \
-s '^[\s;]*pid[\s]*=' -r 'pid = /var/run/php-fpm.pid' \
-- /opt/docker/etc/php/fpm/php-fpm.conf
if [[ "$(version-compare "$PHP_VERSION" "5.5.999")" == "<" ]]; then
# listen on public IPv4 port
# no ipv6 sockets available for old php version
go-replace --mode=line --regex \
-s '^[\s;]*listen[\s]*=' -r 'listen = 0.0.0.0:9000' \
--path=/opt/docker/etc/php/fpm/ \
--path-pattern='*.conf'
else
# listen on public IPv6 port
go-replace --mode=line --regex \
-s '^[\s;]*listen[\s]*=' -r 'listen = [::]:9000' \
--path=/opt/docker/etc/php/fpm/ \
--path-pattern='*.conf'
fi
if [[ "$(version-compare "$PHP_VERSION" "5.99.999")" == "<" ]]; then
# Configure php-fpm main (php 5.x)
go-replace --mode=lineinfile --regex \
--lineinfile-after='\[global\]' \
-s '^[\s;]*daemonize[\s]*=' -r 'daemonize = no' \
-- /opt/docker/etc/php/fpm/php-fpm.conf
fi

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
case "$IMAGE_FAMILY" in
Debian|Ubuntu|Alpine)
# Register webdevops ini
ln -sf "/opt/docker/etc/php/php.webdevops.ini" "${PHP_ETC_DIR}/conf.d/98-webdevops.ini"
# Register custom php ini
ln -sf "/opt/docker/etc/php/php.ini" "${PHP_ETC_DIR}/conf.d/99-docker.ini"
;;
esac

View File

@ -0,0 +1,45 @@
#!/usr/bin/env bash
echo "Installing ionCube loader"
DOWNLOAD_URL="http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz"
TMP_FILE="/tmp/ioncube_loaders.tar.gz"
echo "Downloading ..."
curl -sS ${DOWNLOAD_URL} -o ${TMP_FILE}
echo "Unpacking ..."
tar -xzf ${TMP_FILE} -C /tmp
PHP_VERSION=`php -v | head -1 | grep -o 'PHP [0-9].[0-9]' | sed -r 's/PHP //g'`
PHP_EXTENSION_DIR=`php -i | grep -o -m 1 'extension_dir .* =' | sed -r 's/extension_dir => //g' | sed -r 's/ =//g'`
MOD_INI="${PHP_MOD_INI_DIR}/00-ioncube.ini"
SO_FILE="${PHP_EXTENSION_DIR}/ioncube_loader_lin_${PHP_VERSION}.so"
echo "PHP-VERSION: ${PHP_VERSION}"
echo "PHP-EXTENSION-DIR: ${PHP_EXTENSION_DIR}"
if [[ ! -f "/tmp/ioncube/ioncube_loader_lin_${PHP_VERSION}.so" ]]; then
echo "There is no ioncube available for PHP${PHP_VERSION}, skipping installation"
else
echo "Installing ${SO_FILE}"
cp "/tmp/ioncube/ioncube_loader_lin_${PHP_VERSION}.so" ${SO_FILE}
echo "Writing module ini"
echo "[ioncube]" > ${MOD_INI}
echo "zend_extension = ${SO_FILE}" >> ${MOD_INI}
echo "; priority=01" >> ${MOD_INI}
echo "Cleaning up"
rm -rf $TMP_FILE
rm -rf /tmp/ioncube
echo "Enabling ionCube PHP module"
case "$IMAGE_FAMILY" in
Debian|Ubuntu)
# Enable ionCube (if available)
if [[ -f "${PHP_ETC_DIR}/mods-available/00-ioncube.ini" ]]; then
ln -sf "${PHP_ETC_DIR}/mods-available/00-ioncube.ini" "${PHP_ETC_DIR}/cli/conf.d/00-ioncube.ini"
ln -sf "${PHP_ETC_DIR}/mods-available/00-ioncube.ini" "${PHP_ETC_DIR}/fpm/conf.d/00-ioncube.ini"
fi
;;
esac
fi

View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Remove default cronjobs
rm -f -- \
/etc/cron.daily/logrotate \
/etc/cron.daily/apt-compat \
/etc/cron.daily/dpkg \
/etc/cron.daily/passwd \
/etc/cron.daily/0yum-daily.cron \
/etc/cron.daily/logrotate \
/etc/cron.hourly/0yum-hourly.cron \
/etc/periodic/daily/logrotate

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
## remove logs (each bootstrap)
rm -rf -- /var/log/*
rm -rf -- /var/tmp/*
rm -rf -- /tmp/*
rm -rf -- /root/.profile

Some files were not shown because too many files have changed in this diff Show More