Docker dujiaoka 镜像打包

Dockefile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 需要特定版本
FROM alpine:3.13
# 设置时区
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
# 添加一个用户
RUN adduser -D -g '' app && mkdir -p /run/nginx

WORKDIR /app

# 安装php7, php8可以参考 https://github.com/TrafeX/docker-php-nginx
RUN apk add --no-cache \
  curl \
  nginx \
  bash \
  php7 \
  php7-ctype \
  php7-curl \
  php7-dom \
  php7-fileinfo \
  php7-fpm \
  php7-gd \
  php7-intl \
  php7-mbstring \
  php7-mysqli \
  php7-redis \
  php7-pdo \
  php7-json \
  php7-bcmath \
  php7-pcntl \
  php7-pdo_mysql \
  php7-zip \
  php7-zlib \
  php7-opcache \
  php7-openssl \
  php7-phar \
  php7-session \
  php7-tokenizer \
  php7-xml \
  php7-xmlreader \
  php7-xmlwriter \
  php7-simplexml \
  php7-dom \
  supervisor

# 拷贝配置文件
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/conf.d /etc/nginx/conf.d/
# 这个目录依据上面安装的包不同, 也不一样
ENV PHP_INI_DIR /etc/php7
COPY config/fpm-pool.conf ${PHP_INI_DIR}/php-fpm.d/www.conf
COPY config/php.ini ${PHP_INI_DIR}/conf.d/custom.ini

COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# 为可能的目录赋予用户, 后续所有服务都运行在这个用户下
RUN chown -R app /app /run /var/lib/nginx /var/log/nginx /var/log/php7
# 以app用户身份拷贝php代码
COPY --chown=app . /app
# 删除一些文件
RUN rm -rf /app/.git \
  && rm -rf /app/debian_manual.md \
  && rm -rf /app/README.md \
  && rm -rf /app/LICENSE \
  && rm -rf /app/Dockerfile* \
  && rm -rf /app/docker-compose.yml

COPY --from=composer /usr/bin/composer /usr/bin/composer

# 安装依赖, 并删除缓存(否则镜像会很大)
RUN composer config --unset repositories \
  && composer update \
  && composer install --optimize-autoloader -vvv \
  && rm -rf ~/.composer/cache/ \
  && rm -rf /tmp/*

# dujiaoka的storage目录处理, 参考 https://github.com/Apocalypsor/dujiaoka-docker
RUN mv /app/storage /app/storage_bak \
  && sed -i "s?\$proxies;?\$proxies=\'\*\*\';?" /app/app/Http/Middleware/TrustProxies.php \
  && chmod +x /app/start.sh  

# 后面开始以app身份执行
USER app

EXPOSE 8080

ENTRYPOINT ["/app/start.sh"]
HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping || exit 1

start.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/sh

if [ -f "/app/.env" ]; then
  # 如果storage目录是空的, 就把备份目录拷贝过来
	if [ ! -d "/app/storage/app" ]; then
		mv -n storage_bak/* storage/
	fi
# 赋予用户
	if [ -d "/app/storage" ]; then
		chown -R app /app/storage
	fi
# 赋予用户
	if [ -d "/app/public/uploads" ]; then
		chown -R app /app/public/uploads
	fi
# INSTALL环境遍历为false时, 表示不进行安装
	if [ "$INSTALL" != "true" ]; then 
		echo "ok" > /app/install.lock
	fi
# 执行后台任务
	php artisan clear-compiled
	supervisord -c /etc/supervisor/conf.d/supervisord.conf

else
	echo ".env file not found"
fi

conf.d/default.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# Default server definition
server {
    listen [::]:8080 default_server;
    listen 8080 default_server;
    server_name _;

    sendfile off;
    tcp_nodelay on;
    absolute_redirect off;
# dujiaoka是使用 /app/public为根目录的
    root /app/public;
    index index.php index.html;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.php
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    # Redirect server error pages to the static page /50x.html
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/lib/nginx/html;
    }

    # Pass the PHP scripts to PHP-FPM listening on php-fpm.sock
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # Set the cache-control headers on assets to cache for 5 days
    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
        expires 5d;
    }

    # Deny access to . files, for security
    location ~ /\. {
        log_not_found off;
        deny all;
    }

    # Allow fpm ping and status from localhost
    location ~ ^/(fpm-status|fpm-ping)$ {
        access_log off;
        allow 127.0.0.1;
        deny all;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_pass unix:/run/php-fpm.sock;
    }
}

fpm-pool.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
[global]
; Log to stderr
error_log = /dev/stderr

[www]
user = app
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm.sock

; Enable status page
pm.status_path = /fpm-status

; Ondemand process manager
pm = ondemand

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 100

; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
pm.process_idle_timeout = 10s;

; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
pm.max_requests = 1000

; Make sure the FPM workers can reach the environment variables for configuration
clear_env = no

; Catch output from PHP
catch_workers_output = yes

; Remove the 'child 10 said into stderr' prefix in the log and only show the actual message
decorate_workers_output = no

; Enable ping page to use in healthcheck
ping.path = /fpm-ping

nginx.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
worker_processes auto;
error_log stderr warn;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    # Threat files with a unknown filetype as binary
    default_type application/octet-stream;

    # Define custom log format to include reponse times
    log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for" '
                          '$request_time $upstream_response_time $pipe $upstream_cache_status';

    access_log /dev/stdout main_timed;
    error_log /dev/stderr notice;

    keepalive_timeout 65;

    # Write temporary files to /tmp so they can be created as a non-privileged user
    client_body_temp_path /tmp/client_temp;
    proxy_temp_path /tmp/proxy_temp_path;
    fastcgi_temp_path /tmp/fastcgi_temp;
    uwsgi_temp_path /tmp/uwsgi_temp;
    scgi_temp_path /tmp/scgi_temp;

    # Hide headers that identify the server to prevent information leakage
    proxy_hide_header X-Powered-By;
    fastcgi_hide_header X-Powered-By;
    server_tokens off;

    # Enable gzip compression by default
    gzip on;
    gzip_proxied any;
    # Based on CloudFlare's recommended settings
    gzip_types text/richtext text/plain text/css text/x-script text/x-component text/x-java-source text/x-markdown application/javascript application/x-javascript text/javascript text/js image/x-icon image/vnd.microsoft.icon application/x-perl application/x-httpd-cgi text/xml application/xml application/rss+xml application/vnd.api+json application/x-protobuf application/json multipart/bag multipart/mixed application/xhtml+xml font/ttf font/otf font/x-woff image/svg+xml application/vnd.ms-fontobject application/ttf application/x-ttf application/otf application/x-otf application/truetype application/opentype application/x-opentype application/font-woff application/eot application/font application/font-sfnt application/wasm application/javascript-binast application/manifest+json application/ld+json application/graphql+json application/geo+json;
    gzip_vary on;
    gzip_disable "msie6";

    # Include server configs
    include /etc/nginx/conf.d/*.conf;
}

supervisord.conf

这里都不指定user, 这样就会使用Dockerfile里定义的USER

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0
pidfile=/run/supervisord.pid

[program:php-fpm]
command=php-fpm7 -F
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=false
startretries=0

[program:nginx]
command=nginx -g 'daemon off;'
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=false
startretries=0

[program:dujiaoka-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /app/artisan queue:work --tries=3
directory=/app
autostart=true
autorestart=true
startsecs=3
startretries=3
priority=999
numprocs=1
stdout_logfile=/dev/stderr

php.ini

1
2
3
[Date]
date.timezone="Asia/Shanghai"
expose_php= Off
Licensed under CC BY-NC-SA 4.0
记录平时瞎折腾遇到的各种问题, 方便查找
使用 Hugo 构建
主题 Stack 3.29.0Jimmy 设计