Monday, October 29, 2018

Running php-fpm in Docker based on CentOS 7

Running php-fpm in Docker based on CentOS 7


FROM centos:centos7

RUN curl '' -o \
 && bash \
 && rm -f \
 && yum -y update \
 && yum -y install \
  php71u-common \
  php71u-cli \
  php71u-fpm \
  php71u-opcache \
  php71u-xml \
  php71u-json \
  php71u-pdo \
  php71u-mysqlnd \
  php71u-intl \
  php71u-mbstring \
  php71u-mcrypt \
  php71u-gd \
  php71u-soap \
  php71u-process \
  php71u-pecl-redis \
  php71u-pecl-xdebug \


CMD ["php-fpm", "-F"]

Build the docker image:

# docker build -t junhsieh/php7.1-fpm:0.0.0 .

Some important settings to be changed:

# vim /etc/php-fpm.d/www.conf

; Change ownership:

user = php-fpm
group = php-fpm

; Note: Ubuntu uses www-data user. Add php-fpm user to www-data group if the other container used it.
; # groupadd -g 33 www-data
; # useradd www-data -m -c 'web user' -u 33 -g 33
; # usermod -a -G www-data php-fpm
; # id php-fpm
; Now, restart this container to ensure php-fpm user is in www-data group.

; Bind port 9000 to the all interfaces:

listen = 9000
;listen = [::]:9000

; Note: PHP-FPM has a listen.client_allowed setting which allows you to set a list of IPs that can connect, or leave blank for any IP to connect. However, even with it being left blank, the issue still persisted. Digging into the official PHP-FPM repo, I discovered that you also need to set  listen = [::]:9000 which then began to allow any IP to connect.
; Note:

; Comment out the following line:

;listen.allowed_clients =

; Note: "listen.allowed_clients = any" will not work.
; Note: "listen.allowed_clients = other-container-name" will not work. IP address only.

; Uncomment the following line to debug the issue:

catch_workers_output = yes

; Note: Comment it out on production.

xdebug setting:

### xdebug setting
; Enable xdebug extension module

; Note: php-fpm uses port 9000 as well.



Sunday, October 14, 2018

usermod and groupmod not found in Alpine Linux Docker Image

usermod and groupmod not found in Alpine Linux Docker Image

$ vim Dockerfile

FROM alpine:latest

RUN apk --no-cache add shadow \
  && usermod -u 2500 elasticsearch \
  && groupmod -g 2500 elasticsearch

Monday, October 8, 2018

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Setup A Centralized Log Server Using Rsyslog on Ubuntu 16.04 LTS

Rsyslog Server:

# vim /etc/rsyslog.conf

# provides UDP syslog reception
input(type="imudp" port="514")

# provides TCP syslog reception
input(type="imtcp" port="514")

# vim /etc/rsyslog.d/tmpl.conf

$template TmplAuth, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"
$template TmplMsg, "/var/log/client_logs/%HOSTNAME%/%PROGRAMNAME%.log"

authpriv.* ?TmplAuth
*.info;mail.none;authpriv.none;cron.none ?TmplMsg

# systemctl restart rsyslog

Rsyslog Client:

# vim /etc/rsyslog.conf

*.* @

Note: The @ symbol before the IP address tells rsyslog to use UDP to send the messages. Change this to @@ to use TCP.

# systemctl restart rsyslog

# logger -s " This is my Rsyslog client "

# tree /var/log/client_logs/

The following is a list of RFCs that define the Syslog protocol:

RFC 3195 Reliable Delivery for syslog
RFC 5424 The Syslog Protocol
RFC 5425 TLS Transport Mapping for Syslog
RFC 5426 Transmission of Syslog Messages over UDP
RFC 5427 Textual Conventions for Syslog Management
RFC 5848 Signed Syslog Messages
RFC 6012 Datagram Transport Layer Security (DTLS) Transport Mapping for Syslog


Caused by: No subject alternative names matching IP address XXXXX found

Caused by: No subject alternative names matching IP address XXXXX found 
at Source) ~[na:1.8.0_51] 
at Source) ~[na:1.8.0_51] 

# vim

Hashtable<String, Object> objEnvironment;
    objEnvironment = new Hashtable<String, Object>(11);
    objEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    objEnvironment.put(Context.PROVIDER_URL,  "LDAPS://domain:636");
    objEnvironment.put(Context.SECURITY_AUTHENTICATION, "simple");
    objEnvironment.put(Context.SECURITY_PRINCIPAL, <username>);
    objEnvironment.put(Context.SECURITY_CREDENTIALS, <Password>);
    objEnvironment.put("java.naming.ldap.attributes.binary", <attributes>);
    System.setProperty("", "certificates".concat(File.separator).concat("cacerts"));
    this.objLDAPContext = new InitialLdapContext(objEnvironment, null);

# java main -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

Note: Do not use the -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true option on production server.

Improve LDAP support Endpoint identification has been enabled on LDAPS connections.

To improve the robustness of LDAPS (secure LDAP over TLS ) connections, endpoint identification algorithms have been enabled by default.

Note that there may be situations where some applications that were previously able to successfully connect to an LDAPS server may no longer be able to do so. Such applications may, if they deem appropriate, disable endpoint identification using a new system property: com.sun.jndi.ldap.object.disableEndpointIdentification.

Define this system property (or set it to true) to disable endpoint identification algorithms.


fail to run in alpine docker with error "no such file or directory"

fail to run in alpine docker with error "no such file or directory"

Edit main.go:

# vim main.go

package main

import (

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("Hello World\n")
        fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])

func main() {
        http.HandleFunc("/", handler)
        log.Fatal(http.ListenAndServe(":8080", nil))

Build main.go:

# CGO_ENABLED=0 go build main.go

Note: Static build: GOOS=linux GOARCH=amd64 go build main.go


FROM alpine:latest
RUN apk --no-cache add ca-certificates

COPY main /usr/local/bin

CMD /usr/local/bin/main

Build Docker image:

# docker build -t exp/main:0.0.0 .