Skip to content

Commit 2e26c03

Browse files
author
Ric Harvey
committed
First build for nginx nodeJS
1 parent cccb4e1 commit 2e26c03

File tree

7 files changed

+354
-0
lines changed

7 files changed

+354
-0
lines changed

Dockerfile

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
FROM ubuntu:14.04
2+
MAINTAINER Ric Harvey <[email protected]>
3+
4+
# Surpress Upstart errors/warning
5+
RUN dpkg-divert --local --rename --add /sbin/initctl
6+
RUN ln -sf /bin/true /sbin/initctl
7+
8+
# Let the conatiner know that there is no tty
9+
ENV DEBIAN_FRONTEND noninteractive
10+
11+
# Add sources for latest nginx
12+
RUN apt-get install -y wget
13+
RUN wget -q http://nginx.org/keys/nginx_signing.key -O- | sudo apt-key add -
14+
RUN echo deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx >> /etc/apt/sources.list
15+
RUN echo deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx >> /etc/apt/sources.list
16+
17+
# Update System
18+
RUN apt-get update
19+
RUN apt-get -y upgrade
20+
21+
# Basic Requirements
22+
RUN apt-get -y install nginx pwgen python-setuptools curl git unzip vim
23+
24+
# Install NodeJS
25+
RUN curl -sL https://deb.nodesource.com/setup | sudo bash -
26+
RUN sudo apt-get install -y nodejs
27+
28+
# tweak nginx config
29+
RUN sed -i -e"s/worker_processes 1/worker_processes 5/" /etc/nginx/nginx.conf # gets over written by start.sh to match cpu's on container
30+
RUN sed -i -e"s/keepalive_timeout\s*65/keepalive_timeout 2/" /etc/nginx/nginx.conf
31+
RUN sed -i -e"s/keepalive_timeout 2/keepalive_timeout 2;\n\tclient_max_body_size 100m/" /etc/nginx/nginx.conf
32+
RUN sed -i "s/.*conf\.d\/\*\.conf;.*/&\n include \/etc\/nginx\/sites-enabled\/\*;/" /etc/nginx/nginx.conf
33+
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
34+
35+
# nginx site conf
36+
RUN rm -Rf /etc/nginx/conf.d/*
37+
RUN mkdir -p /etc/nginx/sites-available/
38+
RUN mkdir -p /etc/nginx/sites-enabled/
39+
RUN mkdir -p /etc/nginx/ssl/
40+
ADD ./nginx-site.conf /etc/nginx/sites-available/default.conf
41+
RUN ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/default.conf
42+
43+
# Add Default Node Server
44+
ADD ./server.js /usr/share/nginx/html/server.js
45+
ADD ./package.json /usr/share/nginx/html/package.json
46+
RUN mkdir /usr/share/nginx/html/public
47+
Add ./ngineered.png /usr/share/nginx/html/public/ngineered.png
48+
49+
# Supervisor Config
50+
RUN /usr/bin/easy_install supervisor
51+
RUN /usr/bin/easy_install supervisor-stdout
52+
ADD ./supervisord.conf /etc/supervisord.conf
53+
54+
# Start Supervisord
55+
ADD ./start.sh /start.sh
56+
RUN chmod 755 /start.sh
57+
58+
# Expose Ports
59+
EXPOSE 443
60+
EXPOSE 80
61+
62+
CMD ["/bin/bash", "/start.sh"]

README.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
## Introduction
2+
This is a Dockerfile to build a container image for nginx and php-fpm, with the ability to pull website code from git. The container can also use environment variables to configure your web application using the templating detailed in the special features section.
3+
4+
### Git reposiory
5+
The source files for this project can be found here: [https://github.com/ngineered/nginx-php-fpm](https://github.com/ngineered/nginx-php-fpm)
6+
7+
If you have any improvements please submit a pull request.
8+
9+
### Docker hub repository
10+
The Docker hub build can be found here: [https://registry.hub.docker.com/u/richarvey/nginx-php-fpm/](https://registry.hub.docker.com/u/richarvey/nginx-php-fpm/)
11+
12+
## Nginx Versions
13+
- Mainline Version: **1.7.9**
14+
- Stable Version: **1.6.2**
15+
- *Latest = Mainline Version*
16+
17+
## Installation
18+
Pull the image from the docker index rather than downloading the git repo. This prevents you having to build the image on every docker host.
19+
20+
```
21+
docker pull richarvey/nginx-pfp-fpm:latest
22+
```
23+
To pull the Stable Version:
24+
25+
```
26+
docker pull richarvey/nginx-pfp-fpm:stable
27+
```
28+
## Running
29+
To simply run the container:
30+
31+
```
32+
sudo docker run --name nginx -p 8080:80 -d richarvey/nginx-php-fpm
33+
```
34+
You can then browse to http://<docker_host>:8080 to view the default install files.
35+
### Volumes
36+
If you want to link to your web site directory on the docker host to the container run:
37+
38+
```
39+
sudo docker run --name nginx -p 8080:80 -v /your_code_directory:/usr/share/nginx/html -d richarvey/nginx-php-fpm
40+
```
41+
### Pulling code from git
42+
One of the nice features of this container is its ability to pull code from a git repository with a couple of environmental variables passed at run time.
43+
44+
**Note:** You need to have your SSH key that you use with git to enable the deployment. I recommend using a special deploy key per project to minimise the risk.
45+
46+
To run the container and pull code simply specify the GIT_REPO URL including *git@* and then make sure you have a folder on the docker host with your id_rsa key stored in it:
47+
48+
```
49+
sudo docker run -e '[email protected]:ngineered/ngineered-website.git' -v /opt/ngddeploy/:/root/.ssh -p 8080:80 -d richarvey/nginx-php-fpm
50+
```
51+
52+
To pull a repository and specify a branch add the GIT_BRANCH environment variable:
53+
54+
```
55+
sudo docker run -e '[email protected]:ngineered/ngineered-website.git' -e 'GIT_BRANCH=stage' -v /opt/ngddeploy/:/root/.ssh -p 8080:80 -d richarvey/nginx-php-fpm
56+
```
57+
### Linking
58+
Linking to containers also exposes the linked container environment variables which is useful for templating and configuring web apps.
59+
60+
Run MySQL container with some extra details:
61+
62+
```
63+
sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=yayMySQL -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress_user -e MYSQL_PASSWORD=wordpress_password -d mysql
64+
```
65+
66+
This exposes the following environment variables to the container when linked:
67+
68+
```
69+
MYSQL_ENV_MYSQL_DATABASE=wordpress
70+
MYSQL_ENV_MYSQL_ROOT_PASSWORD=yayMySQL
71+
MYSQL_PORT_3306_TCP_PORT=3306
72+
MYSQL_PORT_3306_TCP=tcp://172.17.0.236:3306
73+
MYSQL_ENV_MYSQL_USER=wordpress_user
74+
MYSQL_ENV_MYSQL_PASSWORD=wordpress_password
75+
MYSQL_ENV_MYSQL_VERSION=5.6.22
76+
MYSQL_NAME=/sick_mccarthy/mysql
77+
MYSQL_PORT_3306_TCP_PROTO=tcp
78+
MYSQL_PORT_3306_TCP_ADDR=172.17.0.236
79+
MYSQL_ENV_MYSQL_MAJOR=5.6
80+
MYSQL_PORT=tcp://172.17.0.236:3306
81+
82+
```
83+
84+
To link the container launch like this:
85+
86+
```
87+
sudo docker run -e '[email protected]:ngineered/ngineered-website.git' -v /opt/ngddeploy/:/root/.ssh -p 8080:80 --link some-mysql:mysql -d richarvey/nginx-php-fpm
88+
```
89+
### Enabling SSL or Special Nginx Configs
90+
As with all docker containers its possible to link resources from the host OS to the guest. This makes it really easy to link in custom nginx default config files or extra virtual hosts and SSL enabled sites. For SSL sites first create a directory somewhere such as */opt/deployname/ssl/*. In this directory drop you SSL cert and Key in. Next create a directory for your custom hosts such as */opt/deployname/sites-enabled*. In here load your custom default.conf file which references your SSL cert and keys at the location, for example: */etc/nginx/ssl/xxxx.key*
91+
92+
Then start your container and connect these volumes like so:
93+
94+
```
95+
sudo docker run -e '[email protected]:ngineered/ngineered-website.git' -v /opt/ngddeploy/:/root/.ssh -v /opt/deployname/ssl:/etc/nginx/ssl -v /opt/deplyname/sites-enabled:/etc/nginx/sites-enabled -p 8080:80 --link some-mysql:mysql -d richarvey/nginx-php-fpm
96+
```
97+
98+
## Special Features
99+
100+
### Templating
101+
This container will automatically configure your web application if you template your code. For example if you are linking to MySQL like above, and you have a config.php file where you need to set the MySQL details include $$_MYSQL_ENV_MYSQL_DATABASE_$$ style template tags.
102+
103+
Example:
104+
105+
```
106+
<?php
107+
database_name = $$_MYSQL_ENV_MYSQL_DATABASE_$$;
108+
database_host = $$_MYSQL_PORT_3306_TCP_ADDR_$$;
109+
...
110+
?>
111+
```
112+
113+
### Using environment variables
114+
If you want to link to an external MySQL DB and not using linking you can pass variables directly to the container that will be automatically configured by the container.
115+
116+
Example:
117+
118+
```
119+
sudo docker run -e '[email protected]:ngineered/ngineered-website.git' -e 'GIT_BRANCH=stage' -e 'MYSQL_HOST=host.x.y.z' -e 'MYSQL_USER=username' -e 'MYSQL_PASS=password' -v /opt/ngddeploy/:/root/.ssh -p 8080:80 -d richarvey/nginx-php-fpm
120+
```
121+
122+
This will expose the following variables that can be used to template your code.
123+
124+
```
125+
MYSQL_HOST=host.x.y.z
126+
MYSQL_USER=username
127+
MYSQL_PASS=password
128+
```
129+
To use these variables in a template you'd do the following in your file:
130+
131+
```
132+
<?php
133+
database_host = $$_MYSQL_HOST_$$;
134+
database_user = $$_MYSQL_USER_$$;
135+
database_pass = $$_MYSQL_PASS_$$
136+
...
137+
?>
138+
```
139+
### Template anything
140+
Yes ***ANYTHING***, any variable exposed by a linked container or the **-e** flag lets you template your config files. This means you can add redis, mariaDB, memcache or anything you want to your application very easily.

nginx-site.conf

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
server {
2+
listen 80; ## listen for ipv4; this line is default and implied
3+
listen [::]:80 default ipv6only=on; ## listen for ipv6
4+
5+
# Make site accessible from http://localhost/
6+
server_name localhost;
7+
8+
# Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html
9+
sendfile off;
10+
11+
location / {
12+
proxy_pass http://localhost:3000;
13+
proxy_http_version 1.1;
14+
proxy_set_header Upgrade $http_upgrade;
15+
proxy_set_header Connection 'upgrade';
16+
proxy_set_header Host $host;
17+
proxy_cache_bypass $http_upgrade;
18+
}
19+
20+
location /public {
21+
root /usr/share/nginx/html/public;
22+
}
23+
24+
#error_page 404 /404.html;
25+
26+
# redirect server error pages to the static page /50x.html
27+
#
28+
error_page 500 502 503 504 /50x.html;
29+
location = /50x.html {
30+
root /usr/share/nginx/html;
31+
}
32+
33+
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
34+
access_log off;
35+
log_not_found off;
36+
expires 5d;
37+
}
38+
39+
# deny access to . files, for security
40+
#
41+
location ~ /\. {
42+
access_log off;
43+
log_not_found off;
44+
deny all;
45+
}
46+
47+
}

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "node-server-example",
3+
"version": "0.0.1",
4+
"description": "Hello World Example served by express",
5+
"main": "server.js",
6+
"dependencies": {
7+
"express": "*"
8+
},
9+
"devDependencies": {},
10+
"scripts": {
11+
"test": "echo \"Error: no test specified\" && exit 1",
12+
"start": "node server.js"
13+
},
14+
"repository": "",
15+
"author": "Richard Harvey",
16+
"license": "AGPL"
17+
}

server.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var express = require('express')
2+
var app = express()
3+
4+
app.get('/', function (req, res) {
5+
res.send('Hello World!')
6+
})
7+
8+
var server = app.listen(3000, function () {
9+
10+
var host = server.address().address
11+
var port = server.address().port
12+
13+
console.log('Example app listening at http://%s:%s', host, port)
14+
15+
})

start.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
3+
# Pull down code form git for our site!
4+
if [ ! -z "$GIT_REPO" ]; then
5+
rm /usr/share/nginx/html/*
6+
if [ ! -z "$GIT_BRANCH" ]; then
7+
git clone -b $GIT_BRANCH $GIT_REPO /usr/share/nginx/html/
8+
else
9+
git clone $GIT_REPO /usr/share/nginx/html/
10+
fi
11+
fi
12+
13+
# Tweak nginx to match the workers to cpu's
14+
15+
procs=$(cat /proc/cpuinfo |grep processor | wc -l)
16+
sed -i -e "s/worker_processes 5/worker_processes $procs/" /etc/nginx/nginx.conf
17+
18+
# Very dirty hack to replace variables in code with ENVIRONMENT values
19+
20+
for i in $(env)
21+
do
22+
variable=$(echo "$i" | cut -d'=' -f1)
23+
value=$(echo "$i" | cut -d'=' -f2)
24+
if [[ "$variable" != '%s' ]] ; then
25+
replace='\$\$_'${variable}'_\$\$'
26+
find /usr/share/nginx/html -type f -exec sed -i -e 's/'${replace}'/'${value}'/g' {} \; ;
27+
fi
28+
done
29+
30+
# Start supervisord and services
31+
/usr/local/bin/supervisord -n

supervisord.conf

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[unix_http_server]
2+
file=/tmp/supervisor.sock ; (the path to the socket file)
3+
4+
[supervisord]
5+
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
6+
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
7+
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
8+
loglevel=info ; (log level;default info; others: debug,warn,trace)
9+
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
10+
nodaemon=false ; (start in foreground if true;default false)
11+
minfds=1024 ; (min. avail startup file descriptors;default 1024)
12+
minprocs=200 ; (min. avail process descriptors;default 200)
13+
14+
; the below section must remain in the config file for RPC
15+
; (supervisorctl/web interface) to work, additional interfaces may be
16+
; added by defining them in separate rpcinterface: sections
17+
[rpcinterface:supervisor]
18+
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
19+
20+
[supervisorctl]
21+
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
22+
23+
[program:nodeserver]
24+
command=/usr/bin/node /usr/share/nginx/html/server.js
25+
directory=/usr/share/nginx/html/
26+
autostart=true
27+
autorestart=true
28+
startretries=3
29+
stderr_logfile=/var/log/webhook/node.err.log
30+
stdout_logfile=/var/log/webhook/node.out.log
31+
user=nginx
32+
33+
[program:nginx]
34+
command=/usr/sbin/nginx
35+
stdout_events_enabled=true
36+
stderr_events_enabled=true
37+
38+
[eventlistener:stdout]
39+
command = supervisor_stdout
40+
buffer_size = 100
41+
events = PROCESS_LOG
42+
result_handler = supervisor_stdout:event_handler

0 commit comments

Comments
 (0)