Så sätter du upp en blixtsnabb WordPress-server

Uppdaterat 2013: OBS, denna guide är inte längre aktuell. Jag har skrivit en ny guide här:

FS Datas blogg, Guide till en blixtsnabb WordPress-server

Som du kanske vet så körde jag tidigare en stäng beta med världens bästa och snabbaste WordPress-hantering i molnet, under namnet Kaizr. Nu är denna tjänst lagd på is, men jag tycker det vore synd om min erfarenhet från denna tid gick helt förlorad.

Nu var Kaizr en, tekniskt sett, rätt så avancerad lösning, som bäst kommer till nytta i ett riktigt moln (dvs hos Amazon, Rackspace osv, inte i något svenskt låtsasmoln). Men det går att använda delar av Kaizr, t ex för att sätta upp en blixtsnabb WordPress-server.

Vilken bra idé! Det är dags för Sveriges första crowdsourcade serverinstallation.

Det här är en installation med fokus på en så snabb WordPress-server som möjligt, som alla får använda och bidra till. Jag är givetvis inte felfri, om jag får in förslag till förändringar/förbättringar så kommer det en uppdaterad version här framöver.

OBS: Notera att fokus för denna installation är snabbhet. Du bör själv vidta åtgärder för att säkra upp din server. Jag tar inget ansvar för eventuella fel eller problem som kan uppstå om du följer dessa instruktioner (även om jag svarar på era kommentarer så gott jag kan).

Serverinstallationen gäller för Ubuntu 10.10. Det går säkert att köra Debian eller motsvarande Linux-dist, utan större förändringar.

Världens snabbaste WordPress-server: Ubuntu, Nginx, PHP-FPM & MySQL

Alla kommandon och filer är markerade med en code-tagg här nedan. Jag förutsätter att du har grundläggande administrationskunskaper, så du kan navigera runt och hantera textfiler. Alla kommandon körs även med root-privilegier på servern. För enkelhetens skull utelämnar jag alla sudo-kommandon.

1. Börja med att uppdatera och uppgradera din server. Om du får frågor här så är det bara att välja standardalternativet.

# apt-get update && apt-get -y upgrade

2. Sen installerar vi lite saker som våra programvaror (främst PHP) är beroende utav. Denna lista går säkert att korta ner.

# apt-get -y install make bison flex gcc patch autoconf subversion locate unzip
# apt-get -y install build-essential libtool libpcrecpp0 libpcre3-dev libxml2-dev libmysqlclient16-dev libcurl4-openssl-dev libfreetype6-dev libgd2-xpm-dev libjpeg62-dev libpng12-dev libmcrypt-dev libmhash-dev libpspell-dev libming-dev libmm-dev libtidy-dev libxslt1-dev libevent-dev libc-client-dev autoconf2.13

3. Därefter installerar vi PHP med ett gäng olika tillägg. De viktigaste i sammanhanget är tilläggen för PHP-FPM och Xcache

# apt-get -y install php5 php5-cgi php5-cli php5-common php5-curl php5-fpm php5-gd php5-imap php5-mcrypt php5-mhash php5-mysql php5-pspell php5-remctl php5-sqlite php5-suhosin php5-svn php5-tidy php5-xcache php5-xmlrpc php5-xsl php-pear
# /etc/init.d/php5-fpm stop

4. Sedan installerar vi den ryska webbservern Nginx.

# echo "deb http://ppa.launchpad.net/nginx/development/ubuntu maverick main" >> /etc/apt/sources.list
# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
# apt-get update
# apt-get install nginx
# /etc/init.d/nginx stop

På vissa VPS:er/servrar är Apache installerat som standard. För att undvika konflikter med Nginx, avinstallera samtliga Apache-relaterade program. Exakt kommando kan variera, beroende på vad som är installerat på din server, här är ett exempel:

# apt-get remove apache2 apache2-doc apache2-mpm-prefork apache2-utils apache2.2-bin apache2.2-common

5. Och så installerar vi MySQL. Glöm inte bort lösenordet som du anger under installationen.

# apt-get install -y mysql-server

6. Till slut så konfigurerar vi lite småsaker på servern, främst relaterade till Nginx/PHP.

# cd /etc/nginx
# mv fastcgi_params fastcgi_params.old
# nano fastcgi_params

Lägg in följande innehåll:

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $http_x_forwarded_for;
fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 32k;
fastcgi_buffers 32 32k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

I samma mapp skapar vi även en fil som hanterar omskrivningar för WordPress, både med och utan WP Super Cache.

# nano wordpress_params.supercache

Lägg in följande innehåll:

if (-f $request_filename) {
break;
}
set $supercache_file '';
set $supercache_uri $request_uri;

if ($request_method = POST) {
set $supercache_uri '';
}
if ($query_string) {
set $supercache_uri '';
}
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
set $supercache_uri '';
}
if ($supercache_uri ~ ^(.+)$) {
set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
}
if (-f $document_root$supercache_file) {
rewrite ^(.*)$ $supercache_file break;
}
if (!-e $request_filename) {
rewrite ^.+?(/wp-.*) $1 last;
rewrite ^.+?(/.*.php)$ $1 last;
rewrite ^ /index.php last;
}
error_page 404 = //index.php?q=$uri;

Till sist så startar vi även tjänsterna för Nginx och PHP-FPM.

# /etc/init.d/nginx start
# /etc/init.d/php5-fpm start

Nu är serverinstallationen klar (men som sagt, glöm inte att säkra upp allt ordentligt).

Här är alla kommandon för att stoppa, starta och starta om tjänsterna på servern:

# /etc/init.d/nginx stop
# /etc/init.d/nginx start
# /etc/init.d/nginx restart
# /etc/init.d/php5-fpm stop
# /etc/init.d/php5-fpm start
# /etc/init.d/php5-fpm restart
# /etc/init.d/mysql stop
# /etc/init.d/mysql start
# /etc/init.d/mysql restart

Lägg upp en sajt på din blixtsnabba WordPress-server

Nu ska vi sätta upp en sajt på servern. Det är blir en egen ”virtual host”, som kör med en egen användare (till skillnad från t ex WordPress Multi-Site, där vi har en gemensam användare/virtual host för alla sajter). Detta underlättar vid felsökning, kvotahantering och bidrar även till ökad säkerhet.

1. Börja med att skapa en användare och en databas. Jag använder sulo_se som namn på användaren och sulo.se som domän på sajten.

# adduser sulo_se

Notera understrecket i användarnamnet. Inga punkter här inte.

mysql -u root -p
CREATE DATABASE sulo_se;
GRANT ALL PRIVILEGES ON sulo_se.* TO "sulo_se"@"%" IDENTIFIED BY "lösenord";
FLUSH PRIVILEGES;
EXIT;

2. Nu sätter vi upp en PHP-konfiguration för sajten.

# cd /etc/php5/fpm/pool.d/
# mv www.conf ../
# nano sulo.se.conf

Lägg in följande innehåll:

[sulo.se]
listen = 127.0.0.1:9000
listen.backlog = -1
listen.owner = sulo_se
listen.group = sulo_se
listen.mode = 0666
user = sulo_se
group = sulo_se
pm = dynamic
pm.max_children = 10
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 50
request_slowlog_timeout = 60s
slowlog = /var/log/php-fpm.log.slow

Det här är en rätt så sparsmakad och resurssnål konfiguration. Du bör verkligen läsa kommentarerna i www.conf för mer info.

Om du t ex vill lägga till ytterligare sajter, efter denna, så måste du välja en annan port för listen, t ex från 9000 till 9001. Detta måste även synkas med konfigurationen av Nginx (här nedan). Om du vill öka kapaciteten på sajten (ta emot fler samtidiga besökare) så kan du skruva upp antalet servrar.

3. Konfigurera Nginx för din sajt

# cd /etc/nginx/sites-enabled
# nano sulo.se

Lägg in följande innehåll:

server {
listen 80;
server_name sulo.se *.sulo.se;
server_name_in_redirect off;
client_max_body_size 64M;
access_log /home/sulo_se/sulo.se/logs/access.log;
error_log /home/sulo_se/sulo.se/logs/error.log;

location / {
root /home/sulo_se/sulo.se;
index index.php;
rewrite ^.*/files/(.*) /wp-includes/ms-files.php?file=$1 last;
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
}

location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/sulo_se/sulo.se/$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}

Här kan du t ex se listen-direktivet från konfigurationen av PHP-FPM (som ska öka om du lägger till ytterligare sajter). Det är värt att notera att vi lägger lite loggar, för enkel åtkomst, under /logs på din domän (t ex www.sulo.se/logs/). Du kan givetvis flytta eller lösenordsskydda dem om du vill.

4. Allra sist hämtar vi ner och installerar WordPress.

Du kan givetvis välja en nyare version av WordPress om en sådan finns. Vi passar likaså på att installera det svenska språkstödet.

# mkdir /home/sulo_se/sulo.se && cd /home/sulo_se/sulo.se
# svn co http://core.svn.wordpress.org/tags/3.0.4/ .
# mkdir wp-content/languages && cd wp-content/languages/
# wget http://svn.automattic.com/wordpress-i18n/sv_SE/tags/3.0.4/messages/sv_SE.mo
# cd -
# mkdir logs
# mv wp-config-sample.php wp-config.php
# nano wp-config.php

Ange dina databasuppgifter och spara filen. För att aktivera det svenska språkstödet, uppdatera följande variabel:

define ('WPLANG', 'sv_SE');

Till sist sätter vi rätt ägare på WordPress-installationen.

# cd /home/sulo_se
# chown -Rf sulo_se:sulo_se *

Därefter är det bara att starta om Nginx och PHP-FPM (se kommandon ovan). Sen kan du surfa in på sidan (förutsatt att domänen pekar till din server) och köra igång med din blixtsnabba WordPress-server.

Övrigt/tips på länkar & leverantörer

Förutom Google så finns det bra dokumentation här: Nginx, PHP-FPM och MySQL

När det gäller kapaciteten till din server så bör du åtminstone ha 1 GB RAM-minne. Även om t ex Nginx kräver mindre resurser än Apache så älskar WordPress (och PHP) RAM-minne. Glöm inte bort att vi även kör en databasserver här.

Jag har själv testat serverinstallationen med samtliga VPS:er hos FS Data och de funkar till 100 %. Det fungerar säkert även med VPS:er/servrar hos andra leverantörer, om än att det ger bonuspoäng i min bok om du väljer FS Data. ;)

Har du några frågor eller är något galet i serverinstallationen? Lämna en kommentar! Får du ihop allt och är skitnöjd med din nya WordPress-server? Bjud mig på en öl nästa gång vi ses!

Share on Facebook1Tweet about this on Twitter20Share on Google+1Email this to someone
  • http://www.entreprenord.se C. Davén

    Tack för att du delar med dig! Jag har aldrig fått nginx att funka bra med php, men du lär ju veta vad du pratar om… :-)

    (Ett annat sätt att snabba upp WP är förstås att byta till ett snabbt webbhotell om man nu råkar ha sin sida på ett av de långsamma… http://apprikos.se/blogg/surftown-och-space2u-ar-grymt-bra-pa-wordpress)

  • Matias Vangsnes

    Bra Jonathan, hur stor är prestandaskillnaden mellan en vanlig Apacheserver och Nginx?

    • http://sulo.se Jonathan

      Tack! Det finns en hel uppsjö med jämförelser mellan Nginx och Apache på nätet. Här är en rätt så bra samlingssida: http://www.wikivs.com/wiki/Apache_vs_nginx

      Bara en sån sak som att WordPress.com kör Nginx säger rätt så mycket.

      • http://utvbloggen.se Jonas Lejon

        Några kommentarer:

        max_children till 10 bara? Kan eventuellt ställa till problem.
        Samt så rekommenderar jag att sätta expire headers på css, bilder exempelvis och tvinga gzip på lite mer

        • http://sulo.se Jonathan

          Ah, precis den typ av kommentarer jag söker! Rent konkret, vad skulle du rekommendera? Jag uppdaterar gärna denna serverinstallation med förbättringar.

          • http://utvbloggen.se Jonas Lejon

            Detta kör jag i nginx.conf:

            gzip on;
            gzip_disable ”MSIE [1-6].(?!.*SV1)”;
            gzip_http_version 1.0;
            gzip_comp_level 6;
            gzip_vary on;
            gzip_proxied any;
            gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
            gzip_buffers 16 8k;

            Samt för varje server så definierar jag något i stil med:

            location ~* ^.+.(jpg|jpeg|gif|png|js|css)$ {
            access_log off;
            expires 30d;
            }

  • Pingback: Supersnabb server för WordPress #wpse

  • http://jonasnordstrom.se Jonas Nordström

    access-loggen hade jag tagit bort helt om du inte har speciella behov av spårbarhet.

    Jag har inte någon egen conf-fil tillgänglig, men ungefär så här brukar jag göra per wordpress-instans:

    location / {
    index index.php index.htm index.html;
    if (-f $request_filename) {
    expires 30d;
    break;
    }
    try_files $uri $uri/ /index.php;
    }

    location ~ .php$ {
    fastcgi_pass 127.0.0.1:9000;
    include fastcgi.conf;
    }

    Den kan vara lite för aggressiv i ”expires”, men det har fungerat för mig hittills.
    Jag ska se om jag hittar lite mer exempel.
    Jag rekommenderar också att kika på HttpProxyModule för reverse proxy cache.

    • http://apprikos.se Christian Davén

      Jag provade först med detta som en default-rewrite till index.php för att kunna ha snygga URLer (i ramverket Fat-Free Framework, men det funkar nog likadant i WordPress):

      try_files $uri $uri/ /index.php;

      Men det fallerar på att query-variabler inte verkar skickas med. För mig funkar det bättre så här:

      if (!-f $request_filename) {
          rewrite ^(.+)$ /index.php last;
          break;
      }
  • http://östlund.info Henrik

    Ett annat tips kan ju vara att köra memcached (finns wp plugin) eller kanske varnish som cache. Här får man nog testa och se vilket plugin/cache system som är snabbast.

    Varnish och Super cache borde gå att köra ihop.

  • http://www.internetsweden.se Peter Forsman

    Huh.. ”svenskt låtsasmoln” – finns sånt?
    //P

    • http://sulo.se Jonathan

      Oh, ja. Varenda svenskt företag som påstår sig erbjuda molntjänster. Mig veterligen (och jag har rätt så bra koll på marknaden) finns det ingen riktig svensk molntjänst idag.

      • http://johanlinner.se Johan Linnér

        Skulle vara min regnmolnstjänst då… ;)

  • http://www.citynetwork.se Johan Christenson

    Du säger dig ha koll på marknaden och det finns absolut inga svenska molntjänster? Intressant värre Jonathan. Vilken definition på molntjänst bygger du det på? Känner nästan att problemet är på andra hållet – vad är inte en molntjänst med de grundläggande definitionerna. Till och med en vanlig e-posttjänst kan väl även den passa in som en from av SaaS-tjänst?

    Om vi utgår att molnet består av tre delar IaaS, PaaS och SaaS. Har inte tex projektplatsen en typiska dragen för en SaaS tjänst?

    • http://sulo.se Jonathan

      Ja, visst är det intressant? Om mitt påstående stämmer så innebär det t ex att ni på City Network sysslar med falsk marknadsföring. Det du.

      Det finns ett flertal kriterier för en riktig molntjänst. En av de viktigare är t ex det geografiska oberoendet. En riktig molntjänst, såsom Amazon Web Services, har t ex datacenter på flera platser i USA, EU och Asien.

      Ett låtsasmoln däremot, det existerar enbart inom ett begränsat geografiskt område, vilket i praktiken gör det till en ”fräck” VPS-lösning. Här kan vi, mig veterligen som sagt, kategorisera in de svenska leverantörerna.

      IaaS, PaaS och SaaS har i grund och botten inget med molnet att göra.

  • http://www.citynetwork.se Johan Christenson

    Du är för roligt du Jonathan. Du drömmer upp ett eget kritera och kallar alla andra för falska? Så för att vara tydlig – ditt påstående stämmer inte.

    Du förväxlar nog det hela med att en kund skall kunna nå en tjänst från varsomhelst – inte att den måste lagras i varje hörn av världen för att klassas som en molntjänst.

    Om du hostar hos Amazon på Irland så är du fortfarande bara på en plats? Du får inte med automati servrar runt om i världen för att du väljer Amazon? Att en leverantör låter oss välja fler ställen har inte något med konceptet att göra Jonathan.

    Fräck VPS lösning? Du verkar ha missat hela poängen och hänger upp dig på om de fysiska servrarna finns på din gata eller någon annans? Cloud computing har ett antal kriterier som du säger – men det handlar inte om platsen utan om annat.

    Du svarade inte på frågan – så du säger att projektplatsen inte är en molntjänst? Kanske för den inte hostas på den geografiska plats du anser vara ett krav eller?

    Sist men inte minst – var kommer din bitterhet från? Varför all denna negativitet?

    • http://sulo.se Jonathan

      Du får ursäkta mig Johan, men jag förstår inte varför du reagerar så här aggressivt? Om du anser mig ha fel, varför argumenterar du då bara inte för er sak istället? Vad är det t ex som definierar en molntjänst, enligt dig?

      Sist men inte minst, jag är inte bitter. Jag är däremot fostrad att alltid fara med sanning. Och i mina ögon är det något som ni inte gör, med ert påstående om molntjänster. Jag kan dock förstå varför du anser detta vara något negativt. ;)

  • http://www.citynetwork.se Johan Christenson

    Jag tar ditt icke svar som det tydligaste av svar. :-)

  • Niklas

    Hej,

    Har följt din guide, felfritt fram tills steget:
    2. Nu sätter vi upp en PHP-konfiguration för sajten.

    Du säger där att man ska navigera till /etc/php5/fpm/pool.d

    Problemet är att jag inte har en sådan mapp, jag har ej heller en http://www.conf fil.

    Är det något väsentligt jag har missat?
    Värt att notera är kanske att jag inte kör Ubuntu, utan Debian.

    Tack på förhand!

    • http://sulo.se Jonathan

      Hej Niklas, om du saknar denna mapp och filen http://www.conf så har du antagligen inte fått till installationen av PHP (med php-fpm, xcache osv) och Nginx eller så är sökvägarna till dessa annorlunda i Debian.

      Förslagsvis att du försöker söka efter dem på din server. Om du inte hittar dem, installera då om dem igen. Om du får några felmeddelanden vid installationen, återkom då gärna med dem eller testa att googla på dem.

      Min erfarenhet av Debian är dessvärre väldigt begränsad.

  • http://www.afterworkguide.se/ Johannes

    Tack för en väldigt bra guide. Den fick mig in i VPS-träsket och det ångrar jag verkligen inte.

    Jag hade lite problem att få wordpress och WP super cache att fungera fint med xcache, eftersom inbyggt stöd verkar saknas i WP super cache. Det jag i slutändan gjorde var att använda object-cache.php från W3 total cache pluginet och placerade den i wp-content/plugins. WordPress identifierade detta automatiskt. Resultatet tillsammans med WP super cache var en bra boost i ab testet.

    Hur löste du implementationen av xcache?

  • Pingback: Blixtsnabb WordPress-server | blogg.dernebo.se

  • http://jgabor.se Jonathan Gabor

    Några mindre förbättringar:

    root bör sättas i server, ifall man i framtiden vill lägga till fler location så den slipper kolla upp det värdet hela tiden. Inte hela världen om man bara har en location, men lika bra att göra rätt från början.

    En absolut stig för fastcgi_param SCRIPT_FILENAME borde ändras till en ”dynamisk” sådan, ifall man skulle få för sig att flytta sajtens root. Det kan man göra genom att istället ange fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;.

    Läs mer här.

  • Pingback: Kontrollera laddningstiderna på dina WordPress-tillägg | Jonathan Sulo