Jump to content
thirty bees forum
  • entry
    1
  • comments
    31
  • views
    3,560

nginx configuration for thirtybees


You might find this nginx configuration useful if you want to run your thirtybees on nginx + php-fpm

 

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/default;

    # use original IP address changed by cloudflare
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 2400:cb00::/32;
    set_real_ip_from 2405:8100::/32;
    set_real_ip_from 2405:b500::/32;
    set_real_ip_from 2606:4700::/32;
    set_real_ip_from 2803:f800::/32;
    set_real_ip_from 2a06:98c0::/29;
    set_real_ip_from 2c0f:f248::/32;

    real_ip_header CF-Connecting-IP;

    # root
    location / {
        try_files  $uri  $uri/  /index.php?$args;
        index index.php;
    }

    location ~ /.git/ {
        deny all;
    }

    location ~* \.tpl$ {
        deny all;
    }

    location ~* \.(eot|otf|ttf|woff|woff2)$ {
	  add_header Access-Control-Allow-Origin *;
	  expires max;
    }

    # Rewriting for images pretty url - both jpg and webp formats
    location ~* \.(eot|gif|ico|jpg|jpeg|otf|pdf|png|svg|swf|ttf|woff|webp)$ {
        rewrite ^/([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$1$2$3.jpg break;
        rewrite ^/([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3$4.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4$5.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg break;
        rewrite ^/c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2$3.jpg break;
        rewrite ^/c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg break;

        rewrite ^/([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$1$2$3.webp break;
        rewrite ^/([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$1$2$3$4.webp break;
        rewrite ^/([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$1$2$3$4$5.webp break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$4/$1$2$3$4$5$6.webp break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.webp break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.webp break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.webp break;
        rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.webp$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.webp break;
        rewrite ^/c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.webp$ /img/c/$1$2$3.webp break;
        rewrite ^/c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.webp$ /img/c/$1$2.webp break;
 
        allow all;
        try_files  $uri  $uri/  /index.php?$args;
    }

    # php rewriting
    location ~ \.php$ {

        # Installer is using /install/sandbox/anything.php url to test rewritting capabilities
        # it should rewrite to /install/sandbox.test.php file
        rewrite ^/(.*)/sandbox/anything.php$ /$1/sandbox/test.php break;

        try_files  $uri  $uri/  /index.php?$args;
        index  index.html index.htm index.php;

        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_intercept_errors on;
        fastcgi_read_timeout 360s;
        fastcgi_buffers 8 64k;
        fastcgi_buffer_size 64k;
        include fastcgi_params;
    }
}

 

  • Like 3

31 Comments


Recommended Comments



dynambee

Posted

Thank you for this, it's really helpful.

Do you think running nginx + php-fpm will be noticeably faster than using the more traditional nginx + apache + php-fpm? Are there any downsides to using just nginx + php-fpm?

datakick

Posted

Well, I don't see what apache brings to the table. Nginx can take care of url rewriting, ssl, gzip, serving static assets, etc. There's nothing left for apache to handle. Unless you need some special mods (mod_security, etc). I don't need those, so I'm perfectly happy to not use it. 

Petter

Posted

I'm running old Prestashop 1.6.1.7 and is considering to move to Thirtybees.

Anyway, running on a 10 year's old HP  Prolinant ML350G6, that I purchased used for € 150,-   - Ubuntu 16.04, Nginx compiled with pagespeed and percona server,  gives me a constant 97-100% score from google page speed insights

I recently discovered brotli compression module for  nginx  - and I can say that brotli  compression is a "MUST"  all pages is loading much faster and the website feels much more "snappy"

How to Install Nginx with Brotli Compression on Ubuntu 18.04 LTS

Build ngx_pagespeed From Source - Automated Install

datakick

Posted

Thanks @Petter for the tip, I'll definitely try this nginx extension myself

michael

Posted

Hello @datakick

Does Thirtybees support WebP images?

Is there any module?

 

Please have a look at centminmod LEMP it is very poverful and out of box LEMP.

 

 

datakick

Posted

39 minutes ago, michael said:

Hello @datakick

Does Thirtybees support WebP images?

Is there any module?

Yes, it does. No modules are necessary. Just theme support is required

michael

Posted (edited)

From my knowledge.

Easiest way is to use Cloudflare Pro or higher paid plan and enable Polish with webP on the fly conversion. Cloudflare free plan doesn't support webP nor does it support Nginx level webP

Cloudflare can't properly cache webP files and different between supported webP browsers and non-supported like Safari if done at Nginx level.

With Cloudflare pro and higher it make automatically conversion to WebP.

Do you agree with it?

How your config works?

 

Which Cloudflare plan do you use?

 

# use original IP address changed by cloudflare

for what it is this option? How it works?

Edited by michael
datakick

Posted

I use free plan + native thirtybees webp support. Cloudflare has no problems with caching .webp.

michael

Posted

 use original IP address changed by cloudflare

what is for? what is the purpose?

 

 

Petter

Posted (edited)

Ubuntu 16.04:

 

bash <(curl -f -L -sS https://ngxpagespeed.com/install) \
     --ngx-pagespeed-version latest-beta --nginx-version latest

 

--with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin/nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/usr/local/src/ngx_brotli    

 

Configuration summary
  + using threads
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/share/nginx"
  nginx binary file: "/usr/sbin/nginx"
  nginx modules path: "/usr/share/nginx/modules"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/run/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/lib/nginx/body"
  nginx http proxy temporary files: "/var/lib/nginx/proxy"
  nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
  nginx http uwsgi temporary files: "/var/lib/nginx/uwsgi"
  nginx http scgi temporary files: "/var/lib/nginx/scgi"

Edited by Petter
Petter

Posted (edited)

Hmm, did you mean Nginx config ?  - my reply was for compile config,,,

Edited by Petter
Petter

Posted

nginx  site available:

 

server {
    listen 80;
    #listen [::]:80;            # Uncomment this line if you also want to enable IPv6 support
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

 


# Redirect non-https traffic to https
  if ($scheme != "https") {
   return 301 https://$host$request_uri;
 } # managed by Certbot
    server_name  example.com  www.example.com  *.example.com;

 

    root /var/www/example;
    access_log /var/log/nginx/example.access.log;
    error_log /var/log/nginx/example.error.log;
    server_tokens off;
 
     index index.php; # Letting nginx know which files to try when requesting a folder
    #index /example/index.php; # Letting nginx know which files to try when requesting a folder
 
 
    location = /favicon.ico {
        log_not_found off;      # PrestaShop by default does not provide a favicon.ico
        access_log off;         # Disable logging to prevent excessive log sizes

#################


 }

##################   
pagespeed on;
underscores_in_headers on;
pagespeed RewriteLevel CoreFilters;
#pagespeed ForceCaching on;
pagespeed EnableFilters prioritize_critical_css;
pagespeed EnableFilters inline_google_font_css;
pagespeed GoogleFontCssInlineMaxBytes 6000;
#pagespeed EnableFilters extend_cache_images;
pagespeed EnableFilters extend_cache;
#pagespeed EnableFilters convert_jpeg_to_webp;
pagespeed EnableFilters rewrite_images;
pagespeed DisableRewriteOnNoTransform on;
pagespeed FetchHttps enable;
pagespeed LowercaseHtmlNames on;
pagespeed ModifyCachingHeaders on;
pagespeed PreserveUrlRelativity on;
pagespeed EnableFilters hint_preload_subresources;
pagespeed EnableFilters insert_dns_prefetch;
pagespeed EnableFilters rewrite_css;
pagespeed EnableFilters fallback_rewrite_css_urls;
pagespeed LRUCacheKbPerProcess     8192;
pagespeed LRUCacheByteLimit        16384;

 

 

# Needs to exist and be writable by nginx.  Use tmpfs for best performance.
pagespeed FileCachePath "/var/ngx_pagespeed_cache/";
pagespeed FileCacheSizeKb            102400;
pagespeed FileCacheCleanIntervalMs   3600000;
pagespeed FileCacheInodeLimit        500000;

 


# Ensure requests for pagespeed optimized resources go to the pagespeed handler
# and no extraneous headers get set.
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
  add_header "" "";
}
location ~ "^/pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
     
     location ~*  \.(jpg|jpeg|png|gif|ico|css|js|pdf)$ {
        #expires 30d;
         add_header Cache-Control "public, max-age=30d";

    }
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

   # location ~*  \.(pdf)$ {
    expires 30d;
   # }
 
 
     location = /robots.txt {
         auth_basic off;        # Whatever happens, always let bots know about your policy
         allow all;
         log_not_found off;     # Prevent excessive log size
         access_log off;
    }
      client_max_body_size       16m;
      client_body_buffer_size    256k;
 
    # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }


 # browser caching of static assets        #lagt til 06-Februar 2020 ## endret igjend 10-februar-2020- endringer av fearuers blir ikke tatt opp. virker med d for dager og s for sekunder
location ~*  \.(jpg|jpeg|png|gif|ico|css|js|pdf)$ {
    expires 7s;
}
    ##
    # Gzip Settings
    ##
 
    gzip off;
    gzip_disable "msie6";                                             # Do people still use Internet Explorer 6? In that case, disable gzip and hope for the best!
    gzip_vary on;                                                     # Also compress content with other MIME types than "text/html"
    gzip_types application/json text/css application/javascript;      # We only want to compress json, css and js. Compressing images and such isn't worth it
    gzip_proxied any;
    gzip_comp_level 6;                                                # Set desired compression ratio, higher is better compression, but slower
    gzip_buffers 16 8k;                                               # Gzip buffer size
    gzip_http_version 1.0;                                            # Compress every type of HTTP request
    
     
    rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last;
    rewrite ^/([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$1$2.jpg last;
    rewrite ^/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
    rewrite ^/c/([0-9]+)(-[_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
    rewrite ^/c/([a-zA-Z-]+)(-[0-9]+)?/.+\.jpg$ /img/c/$1.jpg last;
    rewrite ^/([0-9]+)(-[_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;

 

    try_files $uri $uri/ /index.php?$args;
 
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_keep_conn on;
        #include /etc/nginx/fastcgi_params;
         include /etc/nginx/fastcgi.conf; #fea original fil
        #fastcgi_pass 127.0.0.1:9000;                    # When using TCP
         fastcgi_pass unix:/run/php/php7.0-fpm.sock;   # When using unix sockets
         include fastcgi_params;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 256 4k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    }

 

}

Petter

Posted (edited)

pagespeed FileCachePath "/var/ngx_pagespeed_cache/";  is mounted on tmpfs (memory) for best performance.

/P
 

Edited by Petter
michael

Posted

thank you

michael

Posted

Hello @datakick

have you test your solution with older browser or Safari e.g 12, which do not support webP?

"The problem with free Cloudflare it doesn't support HTTP Vary header for cache so when Chrome/Firefox webP supported browser populates Cloudflare cache and then next visitor uses Safari browser which doesn't support webP, then Cloudflare will serve a webP image for Safari user which will be a broken image. "

"Cloudflare cache not supporting HTTP Vary header"

With Chrome and Firefox everything will work. With older Safari no.

 

I have your code, I have changed it little and I see that it not works with Safari 12, with Safari 13 works.

Do not use any emulator or testing websites as there are false positive.

MAC or browser.

 

Have you test it?  Safari browser:

http://appldnld.apple.com/Safari5/041-5487.20120509.INU8B/SafariSetup.exe

 

I am looking a solution:

location ~ (.+)\.(png|jpe?g)$ {
    if ( $http_accept ~* webp ) {
        set $webp "A";
    }
    if ( $request_filename ~ (.+)\.(png|jpe?g)$ ) {
        set $file_without_ext $1;
    }
    if ( -f $file_without_ext.webp ) {
        set $webp "${webp}E";
    }
 
    if ( $webp = AE ) {
        add_header Vary Accept;
        rewrite (.+)\.(png|jpe?g)$ $1.webp break;
    }
}

https://gist.github.com/sergejmueller/7672727

 

 

 

 

 

datakick

Posted

There's no need for any of this.

Thirtybees generates different html content for different browsers. If browser supports webp, the image links in the page will have .webp extension, otherwise image links will have .jpg extension. 

Since dynamic html is not cached by cloudflare, there's no issue at all. Works like a charm

datakick

Posted

5 minutes ago, datakick said:

There's no need for any of this.

Thirtybees generates different html content for different browsers. If browser supports webp, the image links in the page will have .webp extension, otherwise image links will have .jpg extension. 

Since dynamic html is not cached by cloudflare, there's no issue at all. Works like a charm

Oh, I take this back. There's a bug in thirtybees core that actually does not do the check correctly -- so you are right, this config can fail for some old browsers.

michael

Posted

This is not a Thirtybees bug this is a Cloudflare "feature".

Cloudfare anyway will ignore any Vary header.

 

michael

Posted

Cloudflare free will ignore, with Cloudflare pro you should not use webp as it will take care by Cloudflare polish option available in pro.

So with Cloudflare pro you should delete all generated webp.

Cloudflare free - no support Vary header, older browser will not works

I need to test this with Amaozon AWS Cloudfront.

datakick

Posted

I don't really care that cloudflare doesn't support this header, as it's not used in decision process at all. If browser send information that it can handle webp format, it will receive webp images, otherwise it will receive jpeg. For older browser this means they will always receive jpeg. 

If tb webp feature is used (and fixed), it will work regardless if you use cloudflare or not. I

datakick

Posted

This Vary problem would occur when your page contains image url like http://www.domain.com/my-image, and this url returns different content for different user agents. That's not the case with thirtybees. We have different urls like http://www.domain.com/my-image.webp and http://www.domain.com/my-image.jpg so there's no ambiguity for cloudflare at all.

 

 

michael

Posted (edited)

Quote

Oh, I take this back. There's a bug in thirtybees core that actually does not do the check correctly -- so you are right, this config can fail for some old browsers.

How to fix it?

Edited by michael
michael

Posted

Hi @data

Quote

Oh, I take this back. There's a bug in thirtybees core that actually does not do the check correctly -- so you are right, this config can fail for some old browsers.

Please advise if this bug is corrected?

 


Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...