How to build a CDN Server

How to setup a static content CDN with Linux (Centos 7)

1. First update the system software packages to the latest version.

#yum -y update

2. Next, install Nginx HTTP server from the EPEL repository using the YUM package manager as follows.

# yum install epel-release
# yum install nginx

3. Once Nginx web server installed, you can start it first time and enable it to start automatically at system boot.

# systemctl start nginx
# systemctl enable nginx

4. By default, CentOS 7 built-in firewall is set to block Nginx traffic. To allow web traffic on Nginx, update the system firewall rules to permit inbound packets on HTTP and HTTPS using the commands below.

# firewall-cmd –zone=public –permanent –add-service=http
# firewall-cmd –zone=public –permanent –add-service=https
# firewall-cmd –reload

otherwise remove the firewalld and flush the iptables to open all connection for testing purpose. (Dont do this on Production Server)

# yum remove firewalld && iptables -F

5. Now you can verify Nginx server by going to the following URL, a default nginx page will be shown.

http://SERVER_DOMAIN_NAME_OR_IP (in this case my server ip are so i type in the browser and i will saw a test page of nginx like below.

Nginx Important Files and Directories

  • The default server root directory (top level directory containing configuration files): /etc/nginx.
  • The main Nginx configuration file: /etc/nginx/nginx.conf.
  • Server block (virtual hosts) configurations can be added in: /etc/nginx/conf.d.
  • The default server document root directory (contains web files): /usr/share/nginx/html.

6. Now we going to setup the Cache for static content with nginx.

cd /etc/nginx/conf.d/ #changes directory

vim cdn.conf #create a config file with below content.

upstream cdn {
server; #origin (this is the web server been create earlier)

proxy_cache_path /mnt/nginx/cdn levels=1:2 keys_zone=cdn_cache:10m max_size=10g
inactive=60m use_temp_path=off; 
#cache setting

server {
listen 80;
server_name;  #your domain name ie:
access_log /var/log/nginx/cdn.access.log; #your cdn access log
error_log /var/log/nginx/cdn.error.log; #your cdn error log

location ~* .(mp4|gif|jpg|png|html|htm|css|js|ico|swf|pdf)$ { 
#in root location, every file content these file format will be serve as a cache # this line must be include on cdn server and origin backend server.
proxy_redirect off;
# (we dont need rewrite when proxy to upstream)
proxy_pass http://cdn;
#proxy_pass to the upstream that we set.
proxy_set_header Host $http_host;
#An unchanged “Host” request header field can be passed like this
expires 5m;
#cache will be expire in 5minutes
proxy_cache cdn_cache;
#proxy pass to the cache rules we setup on top of the config file
proxy_cache_revalidate on;
#cache will be revalidate with the origin server if it is expire
add_header Johnson-CDN-Cache $upstream_cache_status;
#with this header you can know the status of the content been cache or MISS. (can check via inspect element, network)

location / {
proxy_redirect off;
# (we dont need rewrite when proxy to upstream)
real_ip_header X-Real-IP;
real_ip_recursive on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy pass the origin client ip to the upstream server
proxy_pass http://cdn;
#proxy_pass to the upstream that we set.
proxy_set_header Host $http_host;
#An unchanged “Host” request header field can be passed like this

save and quit the file.

8. create a cache directory /mnt/nginx/cdn (cache storage)

mkdir /mnt/nginx/cdn
chown -R nginx.nginx /mnt/nginx/

Conclusion: This is only a cdn server in a single point of country, what you need to do is just point your domain to the cdn server and the cdn server will upstream internally to the backend origin server.

if you wish to have different country and different server to serve your client, you will need something call nginx geo module.

otherwise please reach us at

Thank you.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *