Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit 30bdef5

Browse files
committed
Initial commit of source files.
0 parents  commit 30bdef5

File tree

16 files changed

+1073
-0
lines changed

16 files changed

+1073
-0
lines changed

Dockerfile

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# =============================================================================
2+
# jdeathe/centos-ssh-apache-php-fcgi
3+
#
4+
# CentOS-6, Apache 2.2, PHP 5.3, PHP memcached 1.0, PHP APC 3.1, Composer
5+
#
6+
# =============================================================================
7+
FROM jdeathe/centos-ssh-apache-php
8+
9+
MAINTAINER James Deathe <james.deathe@gmail.com>
10+
11+
# -----------------------------------------------------------------------------
12+
# FastCGI support
13+
# -----------------------------------------------------------------------------
14+
RUN yum --setopt=tsflags=nodocs -y install \
15+
fcgi \
16+
mod_fcgid \
17+
&& rm -rf /var/cache/yum/* \
18+
&& yum clean all
19+
20+
# -----------------------------------------------------------------------------
21+
# Add a "Message of the Day" to help identify container if logging in via SSH
22+
# -----------------------------------------------------------------------------
23+
RUN echo '[ CentOS-6 / Apache / PHP (FastCGI) ]' > /etc/motd
24+
25+
# -----------------------------------------------------------------------------
26+
# Apache mime_magic module should be disabled with FastCGI
27+
# -----------------------------------------------------------------------------
28+
RUN sed -i \
29+
-e 's~^LoadModule mime_magic_module modules/mod_mime_magic.so~#LoadModule mime_magic_module modules/mod_mime_magic.so~g' \
30+
/etc/httpd/conf/httpd.conf
31+
32+
# -----------------------------------------------------------------------------
33+
# Enable the pathinfo fix
34+
# -----------------------------------------------------------------------------
35+
RUN sed -i \
36+
-e 's~^;cgi.fix_pathinfo=1~cgi.fix_pathinfo = 1~g' \
37+
/etc/php.ini
38+
39+
# -----------------------------------------------------------------------------
40+
# Enable Apache MPM worker
41+
# -----------------------------------------------------------------------------
42+
RUN sed -i \
43+
-e 's~#HTTPD=/usr/sbin/httpd.worker~HTTPD=/usr/sbin/httpd.worker~g' \
44+
/etc/sysconfig/httpd
45+
46+
# -----------------------------------------------------------------------------
47+
# Disable mod_php
48+
# -----------------------------------------------------------------------------
49+
RUN mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf.off
50+
RUN touch /etc/httpd/conf.d/php.conf
51+
RUN chmod 444 /etc/httpd/conf.d/php.conf
52+
53+
# -----------------------------------------------------------------------------
54+
# Add the PHP Wrapper script
55+
# -----------------------------------------------------------------------------
56+
RUN mkdir -p /var/www/app/bin
57+
ADD var/www/app/bin/php-wrapper /var/www/app/bin/
58+
59+
# -----------------------------------------------------------------------------
60+
# Replace the PHP Standard bootstrap
61+
# -----------------------------------------------------------------------------
62+
ADD etc/services-config/httpd/apache-bootstrap.conf /etc/services-config/httpd/
63+
RUN ln -sf /etc/services-config/httpd/apache-bootstrap.conf /etc/apache-bootstrap.conf
64+
65+
ADD etc/apache-bootstrap /etc/
66+
RUN chmod +x /etc/apache-bootstrap
67+
68+
# -----------------------------------------------------------------------------
69+
# Set permissions (app:app-www === 501:502)
70+
# -----------------------------------------------------------------------------
71+
#RUN chown -R 501:502 /var/www/app
72+
#RUN chmod 775 /var/www/app
73+
RUN chmod -R 750 /var/www/app/bin
74+
75+
# -----------------------------------------------------------------------------
76+
# Add to the template directory
77+
# -----------------------------------------------------------------------------
78+
RUN cp -rpf /var/www/app/bin /var/www/.app-skel/bin
79+
80+
# -----------------------------------------------------------------------------
81+
# Copy files into place
82+
# -----------------------------------------------------------------------------
83+
ADD etc/services-config/httpd/conf.d/fcgid.conf /etc/httpd/conf.d/
84+
RUN ln -sf /etc/services-config/httpd/conf.d/fcgid.conf /etc/httpd/conf.d/fcgid.conf
85+
86+
EXPOSE 80 8443 443
87+
88+
CMD ["/usr/bin/supervisord", "--configuration=/etc/supervisord.conf"]

README.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
centos-ssh-apache-php-fcgi
2+
==========================
3+
4+
Docker Image including CentOS-6, Apache 2.2, PHP 5.3, PHP memcached 1.0, PHP APC 3.1, Composer.
5+
6+
The Dockerfile can be used to build a base image that can be run as-is or used as the bases for other more specific builds.
7+
8+
Included in the build is the EPEL repository and SSH, vi, elinks (for fullstatus support), APC, Memcache and Composer are installed along with python-pip, supervisor and supervisor-stdout.
9+
10+
[Supervisor](http://supervisord.org/) is used to start httpd (and optionally the sshd) daemon when a docker container based on this image is run. To enable simple viewing of stdout for the sshd subprocess, supervisor-stdout is included. This allows you to see output from the supervisord controlled subprocesses with `docker logs <docker-container-name>`.
11+
12+
SSH is not required in order to access a terminal for the running container the prefered method is to use Command Keys and the nsenter command. See [command-keys.md](command-keys.md) for details on how to set this up.
13+
14+
If enabling and configuring SSH access, it is by public key authentication and, by default, the [Vagrant](http://www.vagrantup.com/) [insecure private key](https://github.com/mitchellh/vagrant/blob/master/keys/vagrant) is required.
15+
16+
## Quick Example
17+
18+
Run up a container named ```apache-php.app-1.1.1``` from the docker image ```jdeathe/centos-ssh-apache-php``` on port 8080 of your docker host.
19+
20+
```
21+
$ docker run -d \
22+
apache-php.app-1.1.1 \
23+
-p 8080:80 \
24+
--env SERVICE_UNIT_APP_GROUP=app-1 \
25+
--env SERVICE_UNIT_LOCAL_ID=1 \
26+
--env SERVICE_UNIT_INSTANCE=1 \
27+
--env APACHE_SERVER_NAME=app-1.local \
28+
--env APACHE_SERVER_ALIAS=app-1 \
29+
--env DATE_TIMEZONE=UTC \
30+
-v /var/services-data/apache-php/app-1:/var/www/app \
31+
jdeathe/centos-ssh-apache-php:latest
32+
```
33+
34+
Now point your browser to ```http://<docker-host>:8080``` where "```<docker-host>```" is the host name of your docker server and, if all went well, you should see the "Hello, world!" page.
35+
36+
![Hello World Screen Shot](images/hello-world.png?raw=true)
37+
38+
## Instructions
39+
40+
### (Optional) Configuration Data Volume
41+
42+
Create a "data volume" for configuration, this allows you to share the same configuration between multiple docker containers and, by mounting a host directory into the data volume you can override the default configuration files provided.
43+
44+
Make a directory on the docker host for storing container configuration files. This directory needs to contain everything from the directory [etc/services-config](etc/services-config)
45+
46+
```
47+
$ mkdir -p /etc/services-config/apache-php.app-1.1.1
48+
```
49+
50+
Create the data volume, mounting our docker host's configuration directory to */etc/services-config/ssh* in the docker container. Docker will pull the busybox:latest image if you don't already have it available locally.
51+
52+
```
53+
$ docker run \
54+
--name volume-config.apache-php.app-1.1.1 \
55+
-v /etc/services-config/ssh.pool-1:/etc/services-config/ssh \
56+
-v /etc/services-config/apache-php.app-1.1.1/supervisor:/etc/services-config/supervisor \
57+
-v /etc/services-config/apache-php.app-1.1.1/httpd:/etc/services-config/httpd \
58+
-v /etc/services-config/apache-php.app-1.1.1/ssl/certs:/etc/services-config/ssl/certs \
59+
-v /etc/services-config/apache-php.app-1.1.1/ssl/private:/etc/services-config/ssl/private \
60+
busybox:latest \
61+
/bin/true
62+
```
63+
64+
### Running
65+
66+
To run the a docker container from this image you can use the included [run.sh](run.sh) and [run.conf](run.conf) scripts. The helper script will stop any running container of the same name, remove it and run a new daemonised container on an unspecified host port. Alternatively you can use the following.
67+
68+
```
69+
$ docker stop apache-php.app-1.1.1 && \
70+
docker rm apache-php.app-1.1.1
71+
$ docker run -d \
72+
--name apache-php.app-1.1.1 \
73+
-p 8080:80 \
74+
-p 8580:8443 \
75+
--env SERVICE_UNIT_INSTANCE=app-1 \
76+
--env SERVICE_UNIT_LOCAL_ID=1 \
77+
--env SERVICE_UNIT_INSTANCE=1 \
78+
--env APACHE_SERVER_NAME=app-1.local \
79+
--env APACHE_SERVER_ALIAS=app-1 \
80+
--env DATE_TIMEZONE=UTC \
81+
--volumes-from volume-config.apache-php.app-1.1.1 \
82+
-v /var/services-data/apache-php/app-1:/var/www/app \
83+
jdeathe/centos-ssh-apache-php:latest
84+
```
85+
86+
Now you can verify it is initialised and running successfully by inspecting the container's logs
87+
88+
```
89+
$ docker logs apache-php.app-1.1.1
90+
```
91+
92+
The output of the logs should show the Apache modules being loaded and auto-generated password for the Apache user and group, (if not try again after a few seconds).
93+
94+
#### Runtime Environment Variables
95+
96+
There are several environmental variables defined at runtime these allow the operator to customise the running container which may become necessary when running several on the same docker host, when clustering docker hosts or to simply set the timezone.
97+
98+
##### 1. SERVICE_UNIT*
99+
100+
The ```SERVICE_UNIT``` environmental variables are used to set a response header named ```X-Service-Uid``` that lets you identify the container that is serving the content. This is useful when you have many containers running on a single host using differnt ports (i.e with differnet ```SERVICE_UNIT_LOCAL_ID``` values) or if you are running a cluster and need to identify which host the content is served from (i.e with different ```SERVICE_UNIT_INSTANCE``` values). The three values should map to the last 3 dotted values of the container name; in our case that is "app-1.1.1"
101+
102+
```
103+
...
104+
--env SERVICE_UNIT_APP_GROUP=app-1 \
105+
--env SERVICE_UNIT_LOCAL_ID=1 \
106+
--env SERVICE_UNIT_INSTANCE=1 \
107+
...
108+
```
109+
110+
##### 2. APACHE_SERVER*
111+
112+
The ```APACHE_SERVER_NAME``` and ```APACHE_SERVER_ALIAS``` environmental variables are used to set the VirtualHost ```ServerName``` and ```ServerAlias``` values respectively. In the following example the running container would respond to the host names ```app-1.local``` or ```app-1```:
113+
114+
```
115+
...
116+
--env APACHE_SERVER_NAME=app-1.local \
117+
--env APACHE_SERVER_ALIAS=app-1 \
118+
...
119+
```
120+
121+
from your browser you can then access it with ```http://app-1.local:8080``` assuming you have the IP address of your docker mapped to the hostname using your DNS server or a local hosts entry.
122+
123+
##### 3. DATE_TIMEZONE
124+
125+
The default timezone for the container, and the PHP app, is UTC however the operator can set an appropriate timezone using the ```DATE_TIMEZONE``` variable. The value should be a timezone identifier, like UTC or Europe/London. The list of valid identifiers is available in the PHP [List of Supported Timezones](http://php.net/manual/en/timezones.php).
126+
127+
To set the timezone for the UK and account for British Summer Time you would use:
128+
129+
```
130+
...
131+
--env DATE_TIMEZONE=Europe/London \
132+
...
133+
```
134+
135+
### Custom Configuration
136+
137+
If using the optional data volume for container configuration you are able to customise the configuration. In the following examples your custom docker configuration files should be located on your local host within a "config" directory relative to your working directory - i.e: *./config/apache-php.app-1.1.1*
138+
139+
#### services-config/httpd/apache-bootstrap.conf
140+
141+
The bootstrap script initialises the app. It sets up the Apache service user + group, generates passwords, enables Apache modules and adds/removes SSL support.
142+
143+
##### 1. Service User
144+
145+
Use the ```SERVICE_USER*``` variables in your custom apache-bootstrap.conf file to override this and to also define a custom username and/or group.
146+
147+
```
148+
SERVICE_USER=apacheUser
149+
SERVICE_USER_GROUP=apacheGroup
150+
SERVICE_USER_PASSWORD=userPassword123
151+
SERVICE_USER_GROUP_PASSWORD=userGroupPassword123
152+
```
153+
154+
##### 2. Apache Modules
155+
156+
The variable ```APACHE_LOAD_MODULES``` defines all Apache modules to be loaded from */etc/httpd/conf/http.conf*. The default is the minimum required so you may need to add more as necessary. To add the "mod\_rewrite" Apache Module you would add it's identifier ```rewrite_module``` to the array as follows.
157+
158+
```
159+
APACHE_LOAD_MODULES="
160+
authz_user_module
161+
log_config_module
162+
expires_module
163+
deflate_module
164+
headers_module
165+
setenvif_module
166+
mime_module
167+
status_module
168+
dir_module
169+
alias_module
170+
rewrite_module
171+
"
172+
```
173+
174+
##### 3. SSL Support
175+
176+
By default SSL support is disabled but a second port, (mapped to 8443), is available for traffic that has been been through upstream SSL termination (SSL Offloading). If you want the container to support SSL directly then set ```APACHE_MOD_SSL_ENABLED=true``` this will then generate a self signed certificate and will update Apache to accept traffic on port 443.
177+
178+
*Note:* The included helper script [run.sh](run.sh) will automatically map the docker host port 8580 to 443 but if you are running docker manually can use the following.
179+
180+
```
181+
$ docker stop apache-php.app-1.1.1 && \
182+
docker rm apache-php.app-1.1.1
183+
$ docker run -d \
184+
--name apache-php.app-1.1.1 \
185+
-p 8080:80 \
186+
-p 8580:443 \
187+
--env SERVICE_UNIT_APP_GROUP=app-1 \
188+
--env SERVICE_UNIT_LOCAL_ID=1 \
189+
--env SERVICE_UNIT_INSTANCE=1 \
190+
--env APACHE_SERVER_NAME=app-1.local \
191+
--env APACHE_SERVER_ALIAS=app-1 \
192+
--env DATE_TIMEZONE=UTC \
193+
--volumes-from volume-config.apache-php.app-1.1.1 \
194+
-v /var/services-data/apache-php/app-1:/var/www/app \
195+
jdeathe/centos-ssh-apache-php:latest
196+
```
197+
198+
#### services-config/ssl/certs/localhost.crt
199+
200+
You may need to override the default auto-generated self signed certificate. To do this you can add the SSLCertificateFile to your config directory using the filename ```localhost.crt``` for example:
201+
202+
```
203+
./config/services-config/ssl/certs/localhost.crt
204+
```
205+
206+
*Note:* You must also specify the associated SSLCertificateKeyFile in this case.
207+
208+
#### services-config/ssl/private/localhost.key
209+
210+
To override the SSLCertificateKeyFile add it to your config directory using the filename ```localhost.key``` for example:
211+
212+
```
213+
./config/services-config/ssl/private/localhost.key
214+
```
215+
216+
*Note:* You must also specify the associated SSLCertificateFile in this case.
217+
218+
#### services-config/supervisor/supervisord.conf
219+
220+
The supervisor service's configuration can also be overriden by editing the custom supervisord.conf file. It shouldn't be necessary to change the existing configuration here but you could include more [program:x] sections to run additional commands at startup.

apache-php.app-1.1.1@8080.service

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# -----------------------------------------------------------------------------
2+
# Create a data container for the configuration volume:
3+
# docker run -v /config --name volume-config.<service-name> busybox /bin/true
4+
#
5+
# To install:
6+
# sudo cp <container-path>/<service-name>@<port>.service /etc/systemd/system/
7+
# sudo systemctl daemon-reload
8+
# sudo systemctl enable /etc/systemd/system/<service-name>@<port>.service
9+
#
10+
# Start using:
11+
# sudo systemctl restart <service-name>@<port>.service
12+
# -----------------------------------------------------------------------------
13+
14+
[Unit]
15+
Description=CentOS-6 / Apache / PHP (FastCGI) // app-1.1.1
16+
After=etcd.service
17+
After=docker.service
18+
Requires=docker.service
19+
Requires=etcd.service
20+
21+
[Service]
22+
Restart=on-failure
23+
RestartSec=30
24+
TimeoutStartSec=1200
25+
26+
# Create a data container for the configuration volume
27+
ExecStartPre=/bin/sudo /bin/bash -c \
28+
"if [ ! \"busybox\" == \"$(/usr/bin/docker images | /bin/grep -e '^busybox[ ]\{1,\}' | /bin/grep -o 'busybox')\" ]; then \
29+
if [ -f /var/services-packages/busybox.latest-1.0.0.tar.xz ]; then \
30+
/usr/bin/xz -dc /var/services-packages/busybox.latest-1.0.0.tar.xz | /usr/bin/docker load; \
31+
else \
32+
/usr/bin/docker pull busybox:latest; \
33+
fi; \
34+
fi; \
35+
if [ ! \"volume-config.%p\" == \"$(/usr/bin/docker ps -a | /bin/grep -v -e \\\"volume-config.%p/.*,.*\\\" | /bin/grep -e '[ ]\{1,\}'volume-config.%p | /bin/grep -o volume-config.%p)\" ]; then \
36+
/usr/bin/docker run \
37+
--name volume-config.%p \
38+
-v /etc/services-config/ssh.pool-1:/etc/services-config/ssh \
39+
-v /etc/services-config/%p/supervisor:/etc/services-config/supervisor \
40+
-v /etc/services-config/%p/httpd:/etc/services-config/httpd \
41+
-v /etc/services-config/%p/ssl/certs:/etc/services-config/ssl/certs \
42+
-v /etc/services-config/%p/ssl/private:/etc/services-config/ssl/private \
43+
busybox:latest \
44+
/bin/true; \
45+
fi"
46+
47+
# Initialisation: Pull or build image if required
48+
ExecStartPre=/bin/sudo /bin/bash -c \
49+
"if [ ! \"jdeathe/centos-ssh-apache-php-fcgi\" == \"$(/usr/bin/docker images | /bin/grep -e '^jdeathe/centos-ssh-apache-php-fcgi[ ]\{1,\}' | /bin/grep -o 'jdeathe/centos-ssh-apache-php-fcgi')\" ]; then \
50+
if [ -f /var/services-packages/jdeathe/centos-ssh-apache-php-fcgi.centos-6-1.0.0.tar.xz ]; then \
51+
/usr/bin/xz -dc /var/services-packages/jdeathe/centos-ssh-apache-php-fcgi.centos-6-1.0.0.tar.xz | /usr/bin/docker load; \
52+
else \
53+
/usr/bin/docker pull jdeathe/centos-ssh-apache-php-fcgi:latest; \
54+
fi; \
55+
fi"
56+
57+
# Startup: Remove existing container (and stop if running) so it is re-created on startup but not removed on exit - to allow debugging if required
58+
ExecStart=/bin/sudo /bin/bash -c \
59+
"if [ \"%p\" == \"$(/usr/bin/docker ps -a | /bin/grep -v -e \\\"%p/.*,.*\\\" | /bin/grep -e '[ ]\{1,\}'%p | /bin/grep -o %p)\" ]; then \
60+
if [ \"%p\" == \"$(/usr/bin/docker ps | /bin/grep -v -e \\\"%p/.*,.*\\\" | /bin/grep -e '[ ]\{1,\}'%p | /bin/grep -o %p)\" ]; then \
61+
/usr/bin/docker stop %p; \
62+
fi; \
63+
/usr/bin/docker rm %p; \
64+
fi; \
65+
/usr/bin/docker run \
66+
--privileged \
67+
--name %p \
68+
-p %i:80 \
69+
-p 8580:8443 \
70+
--env SERVICE_UNIT_INSTANCE=app-1 \
71+
--env SERVICE_UNIT_LOCAL_ID=1 \
72+
--env SERVICE_UNIT_INSTANCE=1 \
73+
--env APACHE_SERVER_NAME=app-1.local \
74+
--env APACHE_SERVER_ALIAS=app-1 \
75+
--env DATE_TIMEZONE=UTC \
76+
--volumes-from volume-config.%p \
77+
-v /var/services-data/apache-php/app-1:/var/www/app \
78+
jdeathe/centos-ssh-apache-php-fcgi:latest"
79+
80+
ExecStartPost=/usr/bin/etcdctl set /services/apache-php/app-1/1.1 %H:%i
81+
82+
ExecStop=/usr/bin/docker stop --time 10 %p
83+
ExecStopPost=/usr/bin/etcdctl rm /services/apache-php/app-1/1.1
84+
85+
[Install]
86+
WantedBy=multi-user.target

0 commit comments

Comments
 (0)