One-Click Speedup für Apache-VHosts 0

Posted by fwoeck
on Thursday, July 23

Mit diesen allgemeinen Apache2-Optionen lässt sich relativ schnell und schmerzlos eine Verbesserung der Ladezeiten erreichen: Kompression und Expiration-Headers.

Die beiden verantwortlichen Module müssen aktiviert werden:

a2enmod expires
a2enmod deflate

und die globale Sektion der apache2.conf erweitert:

# gzip html, css and js
AddOutputFilterByType DEFLATE text/html text/css application/x-javascript application/javascript

# far future expires headers
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)?d{10}$">
  ExpiresDefault "access plus 10 years" 
</FilesMatch>

Zu beachten wäre, dass die statischen Dateien aufgrund der langen Lebensdauer nicht aus dem Cache der Browser verschwinden werden – es sei denn, man zwingt sie dazu!

Weblinks

speed-up-your-apachepassenger-rails-app-in-2min

Astrails "safe" kann jetzt auch PostgreSQL 0

Posted by fwoeck
on Saturday, June 06

Das safe-gem der Firma Astrails führt regelmäßige revisionierte Backups von Ordnern und Datenbanken durch. Es bietet einem dabei eine kompakte DSL und kann die Daten wahlweise verschlüsseln und auf S3-Buckets duplizieren.

Kürzlich ist der Support für PostgreSQL-Datenbanken dazugekommen und damit eignet sich die Sache vielleicht für unser Firmenwiki. Ich habe als ersten Test meinen EC2-Host mit diesem Blog aufgetakelt, den ich bisher nur mit manuellen tars und mysqldumps gesichert hatte.

die Installation

Man nimmt direkt die github-Version und erzeugt eine default-Konfiguration:

# gem install astrails-safe --source http://gems.github.com/
Successfully installed astrails-safe-0.1.9
1 gem installed
Installing ri documentation for astrails-safe-0.1.9...
Installing RDoc documentation for astrails-safe-0.1.9...

# astrails-safe /root/my-backup.conf
ERROR: Created default /root/my-backup.conf. Please edit and run again.

Konfiguration

Es folgt eine Beispielkonfiguration in Ausschnitten – das default-File ist gut kommentiert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
safe do

  local do
    path "/mnt/backup/:kind"
  end

  s3 do
    key "my-Amazon-Key-here"
    secret "my-secret-Amazon-secret-here"
    bucket "the-bucket-name"
    path "backups/:kind/" # this is default
  end

  gpg do
    key "fw@bm.net"
  end

  keep do
    local 4 # keep 4 local backups
    s3 20 # keep 20 S3 backups
  end

  mysqldump do
    options "-ceKq --single-transaction --create-options"

    user "root"
    password "p4ssw0rd"
    socket "/var/run/mysqld/mysqld.sock"

    database :mephisto

  end

  tar do

    archive "etc-files" do
      files "/etc"
    end

    archive "root-files" do
      files "/root"
    end

    archive "mephisto" do
      files "/var/www/mephisto/"
      exclude ["/var/www/mephisto/log", "/var/www/mephisto/tmp"]
    end

  end
end

Wie man sieht, ist das Ganze recht übersichtlich. Damit die gpg-Verschlüsselung funktioniert, benötigen wir ein Schlüsselpaar:

gpg-Schlüsselpaar erzeugen

Anfangs hatte ich die symmetrische Verschlüsselung mit einem Passwort versucht, aber das hat mit der Version 1.9 des gem nicht so recht geklappt – wenn man ein Schlüsselpaar spendiert, funktioniert es aber prima. Das Paar erzeugt man am Besten auf einem anderen Rechner und kopiert nur den öffentlichen Schlüssel auf den Backup-Host.

> gpg --key-gen
...
> gpg -a --export fw@bm.net > fw@bm.net.pub
> scp fw@bm.net.pub root@sat.bm.net:/root/

Auf dem Backup-Host (hier sat.bm.net) wird der öffentliche Schlüssel in den Schlüsselring des Backup-Users importiert (hier root) und als vertrauenswürdig eingestuft:

# gpg --import fw@bm.net.pub
gpg: key 45CA9403: public key "F.W. fw@bm.net" imported
gpg: Total number processed: 1
gpg:               imported: 1

# gpg --edit-key fw@bm.net
...
Command> trust
...
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
...
Command> quit

Wer möchte, kann auf dem lokalen Rechner noch eine Kopie des privaten Schlüssels anfertigen – nur für den Fall:

$ gpg -a --export-secret-key fw@bm.net > fw@bm.net.key

die Automation

Das wär’s schon. Es fehlt nur noch die Automation via crond – z.B. morgens, etwa um drei Uhr:

10 3 * * * /opt/ruby-enterprise/bin/astrails-safe /root/my-backup.conf >/dev/null 2>&1

Weblinks

  1. postgress-and-svndump-support-for-astrails-safe-s3-backup
  2. github.com/astrails/safe

ruby- (und Rails-) Projekte mit dem vim debuggen 0

Posted by fwoeck
on Wednesday, June 03

Anton Astashov hat kürzlich ein Plugin für vim veröffentlicht, mit dem man ruby- und Rails-Projekte aus dem Editor heraus debuggen kann. Mit

:Rdebugger

startet man den Mechanismus. Im Falle eines Railsprojektes wird dann ein Mongrel im development-Modus durch den Debugger gestartet. Auf den kann man wie üblich mit dem Webbrowser zugreifen. Hat man Breakpoints gesetzt, so hält der Prozess an der Stelle an und vim zeigt sie im Hauptfenster.

Nun kann man sich die aktiven Variablen ansehen und schrittweise durch den Quelltext gehen:

Installation

Damit die Sache funktioniert, muss der vim mit “1” antworten, wenn man ihn dies fragt:

:echo has("signs") && has("clientserver") && v:version > 700

Weder der eingebaute vim in Leopard noch der port-vim bringen im Moment eine Unterstützung für das Feature clientserver mit, aber die gvim- und MacVim-Varianten, die ich in Ubuntu und OsX ausprobiert habe, funktionierten beide klaglos.

Außerdem wird das ruby-debug-ide gem genötigt.

Zur Plugininstallation klont man das github-repo:

git clone git://github.com/astashov/vim-ruby-debugger.git

und kopiert dann einige Dateien in vims Pluginverzeichnis:

> cd ./vim-ruby-debugger
> cp -r vim/* ~/.vim/plugin/

Im Hilfetext des Plugins in vim stehen deutliche mehr Informationen, als auf der Hauptseite des github-Projekts:

:helptags ~/.vim/doc
:help ruby-debugger

Entgegen der Voreinstellung habe ich mir die Tastenkürzel auf die Alt-Taste verlegt. In der ~/.vimrc:

map <A-b>  :call g:RubyDebugger.toggle_breakpoint()<CR>
map <A-v>  :call g:RubyDebugger.open_variables()<CR>
map <A-m>  :call g:RubyDebugger.open_breakpoints()<CR>
map <A-s>  :call g:RubyDebugger.step()<CR>
map <A-n>  :call g:RubyDebugger.next()<CR>
map <A-c>  :call g:RubyDebugger.continue()<CR>
map <A-e>  :call g:RubyDebugger.exit()<CR>
map <A-d>  :call g:RubyDebugger.remove_breakpoints()<CR>

let g:ruby_debugger_fast_sender = 1

Die Letzte Zeile ist nötig, um die Benutzung eines Socket-Scripts in C zu aktivieren, dass vermutlich etwas schneller ist, als der übliche Weg (siehe Hilfetext).

Weblinks

github.com/astashov/vim-ruby-debugger

integrity 0.1.10 + rack 1.0.0 + thin 1.2.2 + sinatra 0.9.1.3 0

Posted by fwoeck
on Friday, May 29

Ich hoffe, dass sich die Aktualität dieses Artikels bald erledigt: kurz gefasst, die aktuelle gem-Version von Thin basiert auf rack 1.0.0, die aktuelle integrity-Version auf sinatra 1.9.1.1, welches selbst rack 0.9.x benötigt. Wenn man rack oder Thin oder beide updated, entstehen ein paar Probleme.

Dies ist – soweit ich es jetzt noch zusammenbekomme – wie ich auf meinem Ubuntu-Testserver eine (vermutlich) lauffähige Version zusammengefrickelt habe:

Eine sinatra-Version von SR (s.u.) clonen

Von http://github.com/sr/sinatra/tree/layout-local das git://github.com/sr/sinatra.git clonen und den branch layout-local auschecken:

> git checkout -b layout-local
> vi lib/sinatra/base.rb

dort musste ich für mein REE-1.8.6… die Zeile #46:

inject(0) { |len, part| len + part.bytesize }.to_s
gegen
inject(0) { |len, part| len + part.length }.to_s
ersetzen. Das ist natürlich nicht das Gleiche …

Anschließend noch ein

> rake install

Die letzte integrity-Version clonen

Von http://github.com/integrity/integrity/tree/master den git://github.com/integrity/integrity.git clonen:

> git clone git://github.com/integrity/integrity.git
> cd integrity
> vi integrity.gemspec  # 0.9.1.1 > 0.9.1.3
> gem uninstall integrity
> gem build integrity.gemspec 
> gem install integrity-0.1.10.gem

In der .gemspec muss die Abhängigkeit auf die Version 0.9.1.3 gesetzt werden, damit integrity auch die aktuelle sinatra-Version aufruft.

Weblinks

  1. irclogger.com/integrity/2009-05-19
  2. github.com/integrity/integrity/tree/master
  3. github.com/sr/sinatra/tree/layout-local
  4. http://integrityapp.com/

Hintergrunddienste ordentlich versorgen 0

Posted by fwoeck
on Friday, May 22

Für Railsprozesse, die im Hintergrund asynchron Dinge erledigen sollen, sind ein paar Dinge ganz hilfreich:

  1. Subroutinen zeitlich zu begrenzen und ggf. auftretende Fehler abzufangen
  2. den Dienst selbst auf Steuersignale horchen zu lassen (hier Sig-Term)
  3. adäquate Logeinträge zu prodizieren.

Der folgende Schnipsel zeigt an einer Pdf-Konvertierung, wie man’s machen kann. Er kann als Daemon (in Zusammenhang mit dem daemons-gem) gestartet werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env ruby

# You might want to change this
ENV["RAILS_ENV"] ||= "production"

require File.dirname(__FILE__) + "/../../config/environment"

$running = true
Signal.trap("TERM") do 
  $running = false
end

while($running) do
  
  pdfs = QAttachment.all.select {|qa| qa.content_type == 
           'application/pdf' && qa.answer.andand.value_str.blank?}

  pdfs.each do |f| 
    if File.readable?(f.public_filename)
      begin
        timeout(60) do
          f.answer.value_str = `pdftotext -enc UTF-8 -q "#{f.public_filename}" -`
        end
        f.answer.value_str = 'PDF-ERROR' if f.answer.value_str.blank?
      rescue Timeout::Error
        f.answer.value_str = 'PDF-ERROR'
      end
      f.answer.save
      ActiveRecord::Base.logger.info "Pdf-Conversion failed for Attachment
          #{f.answer.id} at #{Time.now}.\n" if f.answer.value_str == 'PDF-ERROR'
    else
      f.destroy
    end
  end

  sleep 10
end

Gotcha: Selenium-Tests ohne Netzwerk 0

Posted by fwoeck
on Thursday, May 21

Wenn ich mein Ubuntu-Laptop so ganz ohne Netzwerkverbindung starte – kein LAN/WAN, entsteht ein nerviges Phänomen: der Firefox, der von Selenium bei einem Integrationstest gestartet wird, hält sich für schlau und startet im Offline-Modus.

Kein Problem, würde man denken: es wird ja eh nur auf der 127.0.0.1 getestet. Ha! Auch lokale Seiten lassen sich nicht aufrufen und ergo meldet Selenium einen Sessionfehler.

Das Anlegen von dummy-Gateways, DNS-Servern etc. hat da nichts gebracht (wie kriegt der Browser eigentlich raus, dass kein WAN da ist?). Aber: wenn man den NetworkManager beendet, ist auf einmal alles gut:

sudo /etc/init.d/NetworkManager stop

YAML-Files mit UTF-8-Encoding schreiben 0

Posted by fwoeck
on Sunday, May 10

Einmal monatlich möchte(!) ich die Liste aller abgehakten Todos aus der Tracks – Todoliste in unser Zeit-Buchungssystem übertragen. Der kürzeste Weg (es hat keine Web-API) besteht, soweit ich es sehe darin, die einzelnen Tasks nach Datum und Bereich zu gruppieren und als YAML-Datei auszugeben. Der Rest ist Copy-Paste. Leider unterstützt die gewöhnliche ”.to_yaml”-Methode das UTF-8 nur unzulänglich:

>> puts "Wühlmaus".to_yaml
--- "W\xC3\xBChlmaus"

Das ya2yaml-gem schafft Abhilfe:

>> require 'ya2yaml';

>> puts "Wühlmaus".ya2yaml
--- Wühlmaus

Jetzt klappt auch der Export:

1
2
3
4
5
6
7
#!/usr/bin/env /var/www/tracks/script/runner
require 'ya2yaml'

puts Project.find_by_name(ARGV[0]).todos(:oder => 'completed_at ASC').select {|t| 
      t.state == "completed"}.group_by {|t| t.completed_at.to_s[/^2009-([^ ]+) .+$/,1]}.
      map {|k,v| {k => v.group_by {|t| t.context.name }.map {|l,m| {l => m.map{|o| 
      [o.description, o.notes].join(" | ")[/^(.+?)( \| )?$/,1].strip}}}}}.ya2yaml
/var/www/tracks(master) > ./bcs.rb "2009-04" 
--- 
- 
  04-07: 
    - 
      ? "Admin. Infrastruktur" 
      : 
        - Übertragen Fileserverkonf. nach TM
    - 
      Customer-Service:
      ...

Machtspielchen: Posix-Userrechte und ruby 0

Posted by fwoeck
on Wednesday, April 29

Bei Systemdiensten und ähnlichen Abläufen ist es oft hilfreich, den Prozess mit root-Zugriff anzustoßen und ihn so zu konstruieren, dass er später selbsttätig seine Rechte degradiert. Ein Beispiel wäre ein Netzwerdienst, der root-Rechte benötigt, um sich an einen privilegierten TCP-Port zu binden (0..1024), dessen arbeitende Teile dann aber unter einer anderen Userid laufen, um einen möglichen Schaden bei Fremdeinwirkung zu begrenzen.

Ruby bietet das Modul Process an, mit der sich die verschiedenen Ids manipulieren lassen, unter der ein Prozess läuft. Es sind im einzelnen

  1. die reale Id (Process.uid), das ist die, mit der der Prozess ursprünglich gestartet wurde
  2. die effektive Id (Process.euid), also die, die konkret (effektiv) für die Berechtigung zu einer bestimmten Aktion herangezogen wird
  3. die gespeicherte (saved) Id, die verwendet wird, um einen Prozess, dessen Userrechte verändert wurden wieder auf seinen ursprünglichen Level zu befördern

Die Letzte von den dreien ist, soweit ich es sehe nichts, was man in diesem Kontext unmittelbar anfasst.

ein Beispiel

Die folgende Shell wird mit root-Rechten gestartet – reale und effektive Userid sind Anfangs 0. Setzt man die euid, so verändern sich die faktischen Rechte der Shell. Die UID bleibt aber 0 und man kann später zu ihr zurückkehren:

# irb

> Process.uid
=> 0

> Process.euid
=> 0

> `cat /root/id_rsa-gsg-keypair`
=> "-----BEGIN RSA PRIVATE KEY-----\nftu97MIIEAwr05 ...

> require 'etc';

> Etc.getpwnam("me")
=> #<struct Struct::Passwd name="me", passwd="x", uid=1000, gid=1000, ... >

> Process.euid = 1000
=> 1000

> Process.uid
=> 0

> `cat /root/id_rsa-gsg-keypair`;
cat: /root/id_rsa-gsg-keypair: Permission denied

ohne Rückticket

Möchte man den Rechteverlust unumkehrbar machen, so ist auf posixkonformen Systemen (z. B. Linux) die Funktion Process::Sys.setuid angesagt. Sie setzt alle drei Rechte auf eine beliebige Uid, sofern man dazu berechtigt, aka root ist:

# irb

> Process::Sys.setuid(1000);

> Process.uid
=> 1000

> Process.euid
=> 1000

> `cat /root/id_rsa-gsg-keypair`;
cat: /root/id_rsa-gsg-keypair: Permission denied

> Process::Sys.setuid(0)
Errno::EPERM: Operation not permitted

> Process.euid = 0
Errno::EPERM: Operation not permitted

> Process.uid = 0
Errno::EPERM: Operation not permitted ...

Eine etwas ausführlichere Beschreibung, vor allem auch in Bezug auf andere Plattformen findet man hier:

Weblink

  1. 5-things-you-dont-know-about-user-ids-that-will-destroy-you

Clientseitige Cachekontrolle 0

Posted by fwoeck
on Monday, April 27

Es spielt einem der Browser was das Caching von dynamischen Inhalten angeht ja manches Mal einen Streich. Auf der unten genannten Website wird eine kurze Übersicht über das Verhalten unterschiedlicher Browservarianten beim Drücken der Refresh-Taste gegeben und vor allem auch erwähnt, welchen Effekt die Kombination ctrl-F5 hat.

  • Internet Explorer 6 and 7 do both send only cache refresh hints on ctrl+F5. On ctrl+F5 they both send the header field ‘Cache-Control’ set to ‘no-cache’.
  • Firefox 3 do send the header field ‘Cache-Control’ with the value ‘max-age=0? if the user press f5. If you press ctrl+f5 Firefox sends the ‘Cache-Control’ with ‘no-cache’ (hey it do the same as IE!) and send also a field ‘Pragma’ which is also set to ‘no-cache’.
  • Firefox 2 does send the header field ‘Cache-Control’ with the value ‘max-age=0? if the user press f5. ctrl+f5 does not work.
  • Opera/9.62 does send ‘Cache-Control’ with the value ‘max-age=0? after f5 and ctrl+f5 does not work.
  • Safari 3.1.2 behaves like Opera above.
  • Chrome does something quite different: ‘Cache-Control’ is always set to ‘max-age=0?, no matter if you press enter, f5 or ctrl+f5. Except if you start Chrome and enter the url and press enter.

about:cache

Interessant ist beim Firefox außerdem die Adresse about:cache, die eine Liste der speicher- und plattenbasierten Caches mit deren Inhalten aufzeigt.

Weblink

  1. techblog.tilllate.com/clientside-cache-control

mod_rewrite: 13 Beispiele 0

Posted by fwoeck
on Sunday, April 26

Auf seiner Website gibt DK Lynn eine Einführung in die Verwendung von mod_rewrite. Außer dem Link seien hier noch der pdf-Ausdruck und ein mod_rewrite-Cheat-sheet angegeben.

Material

  1. apache-mod_rewrite-examples
  2. 13_Realworld_Examples.pdf
  3. mod_rewrite-cheat-sheet-v2.pdf

Dateien scheffeln mit cpio 0

Posted by fwoeck
on Friday, April 24

Weil ich das jedes Mal wieder nachschlagen muss, schreib ich’s grad auf:

Wichtige Flags:

  1. v – verbose
  2. d – erzeugt Verzeichnisse beim Restore
  3. u – überschreibt bestehende Dateien
  4. a – liest die Timestamps beim Backup
  5. m – schreibt die Timestamps beim Restore
  6. p – copy-pass-Modus

Standardbenutzung

Ein Archiv erzeugen:

cd /quellverz
find . -depth -mtime -8 -print | cpio -ova > backup.cpio

und restaurieren:

cd /zielverz
cpio -ivdm < backup.cpio

(ACLs bleiben erhalten)

Copy-pass-Modus

Mit dem Copy-pass-Modus (p) lassen sich Files on-the-fly kopieren, ohne ein Archiv zu erzeugen. Z.B. hier, kopiere alle Dateien, deren Veränderungen jünger sind, als die der Datei ~/a_file.tm:

cd /quellverz
find . -depth -newer ~/a_file.tmp -print | cpio -pvduam /zielverz

GPG-Schlüssel manuell in die Ubuntu-Paketverwaltung einfügen 0

Posted by fwoeck
on Wednesday, April 22

Gelegentlich laufe ich in diese Situation:

# apt-get update && apt-get upgrade
...
GPG error: http://ppa.launchpad.net intrepid Release: Die folgenden Signaturen konnten nicht überprüft werden, weil ihr öffentlicher Schlüssel nicht verfügbar ist: NO_PUBKEY 28A8205077558DD0

Ich hatte ein alternatives Paketrepo ausgewählt, war aber zu schlampig, den Schlüssel zu importieren. Gelegentlich gelegentlich ist die Suche danach dann etwas nervig.

Falls man dem Schlüssel traut(!), bekommt man ihn i.d.R. auch auf Umwegen über einen öffentlichen Schlüsselserver und kann ihn mit gpg der apt-Verwaltung zur Verfügung stellen:

# gpg --keyserver hkp://subkeys.pgp.net --recv-keys 28A8205077558DD0
# gpg --export --armor 28A8205077558DD0 |  sudo apt-key add -

# apt-get update && apt-get upgrade

sudo und der Fall des verlorenen Pfads 0

Posted by fwoeck
on Monday, April 20

Auf meiner Ubuntu-Entwicklermaschine (Ubuntu 8.10) verwende ich eine ruby-Enterprise-Version, die sich in /opt/ruby-enterprise niedergelassen hat und ihr eigenes gem mitbringt.

Will ich von meinem Useraccount aus gems installieren, z.B.:

$ sudo gem install rspec

dann klappt das auch, aber wie Wunder wird die Aktualisierung mit einem

$ gem list --local

nicht angezeigt. Nähere Untersuchung bringt dies zu Tage:

$ which gem
/opt/ruby-enterprise/bin/gem

$ sudo which gem
/usr/local/bin/gem

Aha! Der Grund ist, dass Ubuntu die Umgebung ($ env) des Users kraft dieser Zeile in der Datei /etc/sudoers:

Defaults env_reset

einfach tilgt: das debian-gem wird aufgerufen und das hat seine eigene gem-Verwaltung. Folgender Zusatz bewirkt Besserung (eingefügt mit sudo visudo):

Defaults env_keep = "COLORS DISPLAY SHELL TERM PATH JRUBY_HOME EDITOR
    LANG HISTCONTROL RUBYOPT OUTPUT_CHARSET LC_ALL JAVA_HOME RAILS_ENV"

die /etc/environment

Zusätzlich kann man in der Datei /etc/environment noch den REE-Pfad einfügen, so dass die Allgemeinheit auch etwas davon hat:

PATH="/opt/ruby-enterprise/bin:/usr/local/sbin:/usr/local/bin:
    /usr/sbin:/usr/bin:/sbin:/bin"

die /etc/apache2/envvars und /etc/crontab

Wo ich grade dabei bin: betreibt man einen Apache mit Passenger und ruby-Enterprise, dann kann es sinnvoll sein, den rechten Pfad auch in die Umgebungsvariablen des Apache zu stecken, falls man beim Aufruf von Skripten aus dem Webserver heraus sicherstellen möchte, dass die richtige ruby-Version verwendet wird.

Dies tut man in der /etc/apache2/envvars. Ein zusätzliches

export PATH="/opt/ruby-enterprise/bin:/usr/local/sbin:/usr/local/bin:
    /usr/sbin:/usr/bin:/sbin:/bin"

an der Stelle reicht hin. Eine weitere Stelle wo’s gelegentlich fehlt ist die /etc/crontab. Auch hier ein:

PATH=/opt/ruby-enterprise/bin:...

Alternativen

Wo wir schon soviel geändert haben, lohnt sich vielleicht ein Blick auf das Kommando update-alternatives. Es soll durch geschickte Symlinks mehrere alternative Versionen ähnlicher Programme verwaltbar machen. Mit einem

sudo update-alternatives --install /usr/bin/ruby ruby /opt/ruby-enterprise/bin/ruby 100

habe ich folgendes hinbekommen (ohne vorherige Pfadvererbung):

~ > ruby --version
ruby 1.8.6 (2008-08-08 patchlevel 286) [i686-linux]

~ > sudo ruby --version
ruby 1.8.6 (2008-08-08 patchlevel 286) [i686-linux]

~ > /usr/bin/ruby1.8 --version
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

Die letzte ist die Ubuntu-eigene. Das klappt also – beim gem-Kommando war ich bis jetzt allerdings nicht erfolgreich. Nähere Informationen dazu finden sich in den

Weblinks

  1. multiple-versions-of-ruby-on-ubuntu-2
  2. multiple-versions-of-ruby-on-ubuntu-3

Awstats für Ubuntu 8.10 konfigurieren 0

Posted by fwoeck
on Monday, April 20

Nicht der letzte Schrei, aber funktioniert: Awstats für die Zugriffsstatistik. Ein paar Schritte sind schon nötig; der unten referenzierte Blog von Sami Dalouche hat mir sehr geholfen.

Beginnen wir mit den Paketen!

Paketinstallation aus dem Repo

# apt-get install awstats

die apache2-Konfiguration

Damit die Logfiles den rechten Ort und das rechte Format haben:

ErrorLog /var/log/apache2/mephisto-error.log
CustomLog /var/log/apache2/mephisto-access.log combined

...kommt in die VHost-Conf – hier für mein Blog.

Die Aktivierung des Perl-Cgi-Scripts kommt erstmal direkt in die root-Seite des default-Hosts – brrr. Schränken wir den Zugriff mal auf unsere IP-Adresse ein. In der /etc/apache2/sites-available/default:

VirtualHost *:80>
    ServerName sat.bm.net
    UseCanonicalName Off
    ServerAdmin  webmaster@localhost
    DocumentRoot /var/www/
    Alias /awstats-icon/ /usr/share/awstats/icon/
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory /var/www/>
        Options None
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
    <Directory /usr/lib/cgi-bin/>
        Options +ExecCGI
        AllowOverride None
    </Directory>
    <Location /cgi-bin/>
        Order deny,allow
        Deny from all
        Allow from 217.128.34.18
        Allow from localhost
    </Location>
</VirtualHost>

das File /etc/awstats/awstats.conf

In diesem Fall verwende ich nur einen einzigen Host zur Analyse, ansonsten könnte man pro Quelle vermutlich noch separate Config-Files aufstellen. Also im /etc/awstats/awstats.conf:

LogFile="/var/log/apache2/mephisto-access.log" 
SiteDomain="bm.net" 
HostAliases="rnotes.bm.net" 
DirData="/srv/data/stats/mephisto"

die Pfade einrichten

Wir brauchen noch einen Ort, wo die Auswertungsdaten landen, und der muss vom Webserver zumindest lesbar sein:

# mkdir -p /srv/data/stats/mephisto
# chown -R www-data. /srv/data/stats

einen Cronjob bauen

Schließlich muss der awstats-Prozess angestoßen werden – ein mal pro Tag reicht mir. Im File /etc/cron.daily/awstats:

#!/bin/sh
/usr/share/doc/awstats/examples/awstats_updateall.pl 
    -awstatsprog=/usr/lib/cgi-bin/awstats.pl now > /dev/null

...und das Ganze ausführbar machen:

# chmod a+x /etc/cron.daily/awstats

Daten vor der Rotation schützen

Logrotate könnte unter Umständen die apache-Logs wegrotieren, bevor awstats zugeschlagen hat. Daher fügen wir ein prerotate-Skript in die /etc/logrotate.d/apache2 ein:

prerotate
  /etc/cron.daily/awstats
endscript

Test und Start

Damit wir gleich was Vernünftiges sehen, kann man einmal zu Beginn den cronjob manuell anschmeißen. Dann sollte der Aufruf der eingerichteten Website – hier http://sat.bm.net/cgi-bin/awstats.pl eine hübsche Übersicht geben. Hey, schon vier Besucher!

Weblinks

  1. awstats.sourceforge.net
  2. howto-apache2-awstats-setup-on-debianubuntu-edgy-eft
  3. setting-up-awstats-to-parse-nginx-log-files-served-from-apache

5-Minuten SEO für das Blog 0

Posted by fwoeck
on Sunday, April 19

Nachdem ich grade dieses Blog veröffentlicht habe, braucht es natürlich eine minimale SEO-Behandlung. Diese Links habe ich benutzt:

  1. dmoz.org: Ein Webindex, für den man seine Website registrieren kann. Die Aufnahme wird manuell geprüft und die großen Suchmaschinen werten die Anwesenheit in dieser Liste vermutlich positiv.
  2. Googles KeywordTool analysiert die Website inhaltlich und macht gewichtete Metatag-Vorschläge.
  3. Googles Insights zeigt hübsche Statistiken über die historische und räumliche Verteilung von Suchanfragen. Unten abgebildet sieht man z.B., dass sich die Requests zu Thema “cucumber” relativ konstant über die letzten Jahre, aber immer sehr punktuell zur Jahresmitte häufen und zwar vor allem auf Jamaika – was sagt uns das?
  4. Der Metatag-Generator von de.linkvendor.com baut einem die nötigen Html-Zeilen zusammen, wenn man seine Wörter schon zusammengesucht hat.
  5. Die Google Webmastertools: Gute Sache, erlaubt die Registrierung der eigenen Seite inkl. Upload einer XML-Sitemap (z.B. den RSS-Feed) und gibt nützliche Hinweise.
  6. Schließlich der Google-Sitestatus, der einfach Aufschluss darüber gibt, ob die eigene Seite bei Googlens im Index ist.

Weblinks

  1. www.dmoz.org
  2. adwords.google.de/select/KeywordToolExternal
  3. www.google.com/insights
  4. de.linkvendor.com/meta-tag-generator
  5. www.google.com/webmasters/tools
  6. www.google.com/sitestatus
  7. www.google.com/analytics/reporting