Löschen
Auflisten
Starten
Starten als Dienst und neu bauen
|
docker-compose up -d --build |
Beenden
In Container springen; der Servicename ist der Name der Containerdefinition im docker-compose.yaml File
|
docker-compose exec Servicename bash |
.env
Variablen können in ein .env File parallel zur docker-compose.yml angelegt werden
Der Inhalt muss wie folgt aufgebaut werden
|
VAR_NAME=value VAR_NAME_2=value2 |
Innerhalb der docker-compose.yml kann wie untenstehend darauf zugegriffen werden.
|
version: '3' services: webtools: user: ${VAR_NAME} |
Um innerhalb des Dockerfiles auf die Variable zuzugreifen, muss diese in den Args Block der Docker-compose.yml
|
version: '3' services: webtools: environment: user: ${VAR_NAME} |
Dann kann die Variable im Dockerfile verwendet werden
|
ARG VAR_NAME RUN echo $VAR_NAME |
Letzencrypt Zertifikat erstellen
automatisch per cron
|
./letsencrypt-auto certonly --renew-by-default --standalone --rsa-key-size 4096 -d domain.de -d www.domain.de |
manuell, auf einen anderen System
|
./letsencrypt-auto certonly -a manual --rsa-key-size 4096 -d domain.de -d www.domain.de |
Nun dem Dialog folgen. Es muss noch eine html Datei auf dem Webserver erstellt werden.
Mobile Geräte arbeiten mit unterschiedlichen Bilschirmauflösungen, damit aber Anwendungen und auch Webseiten auf allen Geräten unabhängig davon dargestellt werden, arbeitet zB der Browser nicht direkt mit diesen Auflösungen.
Als Beispiel zur Verdeutlichung nutzen ich ein
Samsung Galaxy S6 5,1 Zoll mit einer Auflösung von 1440px * 2560px, und ein
Samsung Galaxy Note 4 5,7 Zoll mit einer Auflösung von 1440px * 2560px, und einen
FullHD Monitor 21 Zoll mit einer Auflösung von 1980px * 1080px.
In unserer Webanwendung nutzen wir folgendes css mit zwei MediaQueries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
body { width: 100%; height: 100%; background-color: gray; } @media screen and (max-width: 1200px) { body { background-color: red; } } @media screen and (max-width: 450px) { body { background-color: yellow; } } @media screen and (max-width: 350px) { body { background-color: green; } } |
Der Hintergrund wird auf grau gesetzt, wenn der Bildschirm kleiner wird, wird der Hintergrund bei <= 1200px rot und bei <= 450px gelb und bei <= 350px grün eingefärbt.
Wie sieht nun die Darstellung auf den verschiedenen Geräten aus?
Die Smartphones halten wir dabei im Querformat.
Das Verhalten des Monitors:
Bei der Darstellung dieses Codes im Browser wird das Browserfenster in meinen Monitor grau sein, verkleinere ich es wird es erst einmal rot und bei weiterer Verkleinerung grün.
Das Verhalten der Smartphones, Querformat:
Obwohl wir bei den Smartphones die selbe Displayauflösung haben, erhalten diese sich dennoch anders:
Galaxy S6 – der Browser zeigt ein grünes Bild
Galaxy Note 4 – der Browser zeigt ein gelbes Bild
Warum ist das so?
Hier kommt die Pixeldichte ins Spiel
ldpi (120dpi) = Faktor 0.75
mdpi (160dpi) = Faktor 1.0
HDpi (240dpi) = Faktor 1.5
xhdpi (320dpi) = Faktor 2.0
xxhdpi (480dpi) = Faktor 3.0
xxxhdpi (640dpi) = Faktor 4.0
Das Galaxy S6 hat eine Pixeldichte vom Faktor 4.0 das ergibt einen Bildschirmbreite im Querformat mit der der Browser arbeitet von 640dp = 2560px/4.
Beim Galaxy Note 4 ist die Pixeldichte etwas kleiner, nämlich 3.0, das ergibt dann
480dp = 2560px/4.
Der Browser interpretiert ein dp als ein px.
Hier die Html-Datei zum selber testen:
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
|
<!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Auflösungstest</title> <style> body { width: 100%; height: 100%; background-color: gray; } @media screen and (max-width: 1200px) { body { background-color: red; } } @media screen and (max-width: 450px) { body { background-color: yellow; } } @media screen and (max-width: 350px) { body { background-color: green; } } </style> </head> <body> </body> </html> |
dp ist eine abstrakte Einheit, sie varieiert nach der Pixeldichte.
Eine Linie mit einer Höhe von einen Pixel, wird auf einen Display mit 160dpi tatsächlich 1 Pixel hoch sein, auf einen Display mit 320dpi wird diese tatsächlich 2 Pixel hoch sein.
Der Browser jedoch hat nur die Anweisung eine Linie von 1 Pixel zu zeichen.
Daten backupen
|
JSON.stringify(localStorage) |
Daten wiederherstellen
|
Object.keys(objectdata).forEach(function(key) { localStorage.setItem(key, objectdata[key]); } |
Wir haben ein Element mit einen Außenabstand. Nun möchte ich ein Element in diesen Element (zB Headergrafik) aber relativ auf die komplette Bildschirmbreite setzen.
Das ganze geht ganz einfach, man muss nur die Einheit „vw“ statt „%“ verwenden.
vw: view width
vh: view height
|
.fullSize { position: relative; width: 100vw; // Korrektur des linken randes left: -15px; } |
Einrichtung
Für die Entwicklung von Angular benötigen wir node.js und npm.
Wenn dies in den entsprechenden Versionen vorhanden ist installieren wir uns angular.
|
npm install -g @angular/cli |
Das erste Projekt
Nun starten wir unser Projekt, auch dies geht einfach über die Konsole.
|
-- projekt anlegen ng new my-test -- projekt starten cd my-test/ ng serve --open |
Anlegen von Komonenten
Einzelne Komponenten können auch über die Konsole erstellt werden, das ist auch sehr sinnvoll, da wir uns so die händischen „includes“ sparen.
|
-- neue componente anlegen -- ng generate component name ng g c login |
Routing
Wahrscheinlich benötigt die Anwendung auch ein Routing, hiefür bietet sich des RouterModule an.
Auch das ist schnell erledigt.
In der app.module einen Array mit Routen definieren, die Componenten müssen natürlich vorher definiert werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
var routes = [ { path: "", component: HomeComponent, }, { path: "login", component: LoginComponent, }, { path: "home", component: HomeComponent }, { path: "admin", component: AdminComponent }, { path: '**', component: PageNotFoundComponent }, ] |
Im Bereich Imports müssen diese nun gesetzt werden
|
@NgModule ... imports: [ ... RouterModule.forRoot(routes) ]; |
In der html Datei der App Componente muss nun noch die Ausgabe des Routings erfolgen.
Dafür genügt es an der Stelle wo der Content ausgegeben werden soll, die Directive router-outlet einzubinden.
|
<router-outlet></router-outlet> |
geladen werden.
2 Wege Data Binding in Forms
Um das 2-Wege-Data-Binding in Formularen zu nutzen benötigen wir noch das FormsModule.
Auch dies setzen wir in der app.module.
|
@NgModule ... imports: [ ... FormsModule ]; |
Die Verwendung im input tag des Forms sieht dann wie folgt aus:
|
<input type="text" [(ngModel)]="Username" /> |
Angular ohne NodeJS auf dem Produktivsystem einsetzen
Während sich für die Entwicklung der Angular App der Einsatz von
durchaus lohnt, kann man die Anwendung für das Produktivsystem gebaut werden.
Rest mittels HttpClient
Es ist relativ einfach in einer Componente einen Rest Call abzusetzen.
|
constructor(protected http: HttpClient) { } ngOnInit() { this.http.get<UserResponse>('meineUrl').subscribe(data => { console.log(data); }); } |
Voraussetzung das dies funktioniert ist der Import des Modules „HttpClientModule“.
Dazu einfach in der app.module folgende Einträge setzen:
|
import {HttpClientModule} from '@angular/common/http'; .... @NgModule({ declarations: [ ... ], imports: [ .... HttpClientModule, .... ], }) |
Docker Image aus dem Reository laden
Docker Image starten
|
// -d läuft im Hintergrund docker run -d dockerImageName //durch "-i" (interactive) und "-t" (tty) können wir die Console des Docker Images steuern docker run -i -t dockerImageName /bin/bash |
Ports mittels docker run
|
-p 8000:8888 Port LocalSystem:DockerContainer -p port weiterleiten -P alle ports für zb Kommunikation zw Containern |
Daten des Hostsystems einbinden
|
-v /mein/ordner/im/host:/ordner/im/docker |
Arbeiten mit Containern
Mit jeden docker run wird aus einem Image ein Container erstellt. Sollte dieser an der Konsole nachbearbeitet worden sein und ich beende diesen, kann ich den ihm mittels docker run nicht wieder starten, denn dann erstellt docker wieder einen neuen Container aus dessen Image.
Den veränderten Container kann ich mittels
|
docker container restart ContainerID |
starten. Eine Auflistung aller Container erhalte ich mittels
Wenn ich an die Console meines laufenden Containers möchte, kann ich diese über
|
docker exec -it ContainerID /bin/bash |
erreichen.
Natürlich kann ich aus meinen modifizierten Container auch ein neues Image generieren. Dazu muss ich einfach meine Änderungen am Container in ein Image committen
|
docker commit -m "mein Kommentar" containerID neuerDockerImageName |
Laufende Docker Instanzen anzeigen
Verfügbare Docker Images anzeigen
Laufende Docker Instanz beenden
Alle Docker Instanzen beenden
|
docker stop $(docker ps -a -q) |
Alle Container löschen
|
docker rm $(docker ps -a -q) |
Alle Images löschen
|
docker rmi $(docker images -q) |
Unbenutzte Docker Daten löschen
Apache Weiterleitung auf Docker Container
Im Beispiel läuft über meine-domain.de/d-nginx ein Nginx Server
|
-- module aktivieren a2enmod proxy a2enmod proxy_http <VirtualHost *:80> ... <Location /> Order allow,deny Allow from all Require all granted </Location> ProxyPass /d-nginx http://localhost:81/ ProxyPassReverse /d-nginx http://localhost:81/ ... </VirtualHost> |
Mittels sysv-rc können die Dienste in den entsprechenden Runlevels konfiguriert und eingesehen werden.
|
apt-get install sysv-rc-conf <pre> Manuell an der Console kann man zB. Mysql wie folgt automatisch starten <pre> sudo update-rc.d mysql defaults |
Einen Ordner per ssh mounten
|
// Verzeichnis anlegen in das ich meinen Ordner mounten möchte mkdir /home/user/localMountFolder sshfs <Username>@<Adresse des entfernten Servers>:/entferntes/Verzeichnis localMountFolder // aushängen fusermount -u /home/user/localMountFolder |
Wenn das Passwort vergessen wurde, kann man sich mittels Live CD einen Zugang verschaffen.
Nachdem das System gebootet wurde sind folgende Schritte in der Shell notwendig:
|
# wir machen uns ersteinmal zum root user sudo -i # nun mounten wir das entsprechende Laufwerk mount /dev/sda1 /mnt/ # jetzt ändern wir das root des Systems chroot /mnt/ /bin/bash # jetzt bekommt unser Benutzer ein neues Passwort passwd MeinBenutzername |
svn switch des Repositories
|
svn switch Pfad/neuer/Branch svn switch --relocate pfad/from/repository path/to/repository |
svn gelöschte Dateien als gelöscht markieren
|
svn status | grep '^!' | awk '{print $2}' | xargs svn delete |
svn kopieren – zB neuer Branch oder Tag
|
svn copy file:///pfad/zum/svn-projekt/branches/1.0 file:///pfad/zum/svn-projekt/branches/2.0 -m "mein Kommentar" |
Eine gelöschte Datei aus dem Repository wiederherstellen
|
svn copy protokoll://repository/pfad/zur/datei@1097 dateiname |
Branch von Revision erzeugen
|
svn copy -rREVNUMBER protokoll://repository/pfad/From protokoll://repository/pfad/To |
Es gibt verschiedene Möglichkeiten einen Wert aus einem Select in eine Variable zu speichern.
Dennoch gibt es unterschiedliche Ergebnisse.
SELECT INTO
|
SELECT ID INTO @MeineID FROM Table WHERE Short = "MeinName"; |
Ein großer Nachteil von SELECT INTO ist, die Variable wird nur gesetzt, wenn das SELECT einen return Wert hat.
Wurde die Variable bereits vorab gesetzt und in meiner SELECT INTO Query es gab keinen Return Wert, dann bleibt die Variable auf dem alten Wert. Das kann schwerwiegende Folgen für weitere Operationen haben.
Deshalb empfinde ich es besser SET zu verwenden.
|
SET @MeineID = (SELECT ID FROM Table WHERE Name = "MeinName"); |
Hier wird die Variable immer gesetzt, ist meine Query erfolglos, ist der Wert null. Egal welchen Wert sie vorher hatte.
Wie kann ich eine Procedure debuggen?
Ich persönlich nutze dazu gern eine eigene Procedure die eine Tabelle beschreibt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
DELIMITER $$ DROP PROCEDURE IF EXISTS DEBUG_PROCEDURE; CREATE PROCEDURE DEBUG_PROCEDURE (Identifier VARCHAR(255), Name VARCHAR(255), Value VARCHAR(255)) BEGIN CREATE TABLE IF NOT EXISTS `TMP_DEBUG` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(50) NULL DEFAULT NULL, `name` VARCHAR(50) NULL DEFAULT NULL, `value` VARCHAR(50) NULL DEFAULT NULL, `time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1; INSERT INTO TMP_DEBUG (`identifier`, `name`, `value`) VALUES (Identifier, Name, Value); END$$ DELIMITER ; |
Nun kann ich in jeder Procedure mit CALL einen Debug Eintrag erzeugen.
|
CALL DEBUG_PROCEDURE("ProcedureName", "Name der Var", "Value"); |
Wie kann ich eine Prozedur in MySQL anlegen?
Eine Procedure kann dazu verwendet werden mehrere SQL Befehle anzustoßen.
Um eine Procedure anzulegen, kann ich diverse SQL Tools nutzen, oder sebst ein SQL zum Erstellen anlegen.
Wenn ich mich für das eigene sql entscheide muss ich für das CREATE Kommando einen eigenen Delimiter verwenden.
Warum? Der Delimiter dient dazu das Ende des Befehles für den SQL Server zu markieren. Da eine Procedure mehrere Kommandos enthält, welche mit dem Semikolon abgeschlossen werden, würde der Server es nach dem ersten Semikolon einen SQL Befehl erkennen und ausführen. Das wiederum würde einen Fehler erzeugen.
Um dies zu umgehen setze ich vor der Erstellung der Procedure meinen Delimiter auf zB $$ und am Ende wieder auf ;.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
-- ich setze meinen Delimiter auf $$ DELIMITER $$ -- eventuell gibt es eine alte Version meiner Prozedure, daher lösche ich diese DROP PROCEDURE IF EXISTS MY_FIRST_PROCEDURE; -- nun erzeuge ich meine Procedure CREATE PROCEDURE MY_FIRST_PROCEDURE (VariableA VARCHAR(255), VariableB VARCHAR(255)) BEGIN -- hier kann nun ganz normaler sql ausgeführt werden -- SELECT, UPDATE, DELETE, Aufruf von Funtionen und Prozeduren -- innerhalb er Prozedure verwende ich den Standard Delimiter SELECT CONCAT('Hallo ', VariableA, ' ', VariableB); -- am Ende den gesetzten Delimiter END$$ -- nun setze ich den Delimiter auf Standard zurück DELIMITER ; |
Ausführen kann ich diese Prozedure wie folgt:
|
CALL MY_FIRST_PROCEDURE("Vorname", "Nachname"); |
Hier entsteht eine kleine Ansammlung an Befehlen.
Installierte Linux Distribution ermitteln:
|
uname -a lsb_release -a cat /etc/issue |
Spracheinstellungen jetzt setzten
Consolenhistory
|
history history -c // History löschen history -d NNN // einen Historyeintrag löschen befehl // Vorangestelltes Leerzeichen -> erscheint nicht in History |
Speicherauslastung
Ordnergrößen
Festplattenbelegung
Zertifikat einer url prüfen:
|
curl --insecure -v https://www.meineDomain.de 2>&1 | awk '/^\* SSL/ { ssl=1 } /^\*/ { if (ssl) print }' |
oder
|
openssl s_client -showcerts -connect www.meineDomain.de:443 |
Welche Anwendung läuft auf Port xyz
netstat -tanp | grep [Portnummer]
Um die Debug-Ausgabe eines Bash-Scriptes zu aktivieren, reicht es direkt in den Script
einzufügen. Ab diesen Moment wird die Debug-Ausgabe aktiviert.
Deaktivieren kann man diese Ausgabe genauso einfach
Um die lokale Entwicklungsumgebung zu modifizieren, kann man einfach eine php Datei preloaden.
Dies kann man einfach mit php Mitteln tun:
|
if(file_exists("prepend.php")) { include_once("prepend.php"); } |
Oder per .htaccess:
|
php_value auto_prepend_file "/mein/Pfad/prepend.php" |
Ein Vorteil für die .htaccess-Variante sehe ich darin, das man sich das online unnütze file_exists spart.
Weiterhin hat man auch den Vorteil, das man die Einstellungen projektübergreifend setzen kann, da die .htaccess die gesetzten Werte ja vererbt.
Genauso gibt es auch die Möglichkeit des ladens einer Datei am Ende:
|
php_value auto_append_file "/mein/Pfad/append.php" |
Mit dem Mail Kommando kann man eine Mail vom Terminal aus zu senden
Danach den Betreff eingeben, dies mit Enter bestätigen.
Nun kann noch der Text eingegeben werden.
Den Dialog beendet man abschließend mit
Sollte es Zeichensatzprobleme bei SSH Verbindungen geben, so ĺiegt dies an unterschiedlich gesetzten Zeichensätzen.
Das Problem kann behoben werden, wenn der auf dem Zielsystem gesetzte Zeichensatz auch auf dem Lokalen System gesetzt wird.
So ermittelt man den gesetzten Zeichensatz:
Und so kann ich den Zeichensatz setzen:
Oftmals hat man das Problem, das nach dem entwickeln doch noch Debug Ausgaben in der Javascript Console erscheinen.
Gerade bei komplexeren Javascript Bibliotheken möchte man eventuell auch die Konsolenausgaben nicht alle löschen um beim späteren weiterentwickeln nicht alle logzeilen neu zu erfinden oder diese ständig ein- und auskommentieren.
Dazu schaffe ich mir gern eine eigene Logfunktionalität.
Hierfür benötige ich zwei Variablen.
useLog diese kann true oder false sein und gibt an ob ich das Logging aktiviere oder deaktivere
customConsole ist mein LogObjekt
Wenn die Variable useLog auf true gesetzt ist, wird einfach meine Variable customConsole auf die window.console gesetzt.
Ist useLog auf false gesetzt wird das komplette Logging deaktiviert.
|
var useLog = false; var useLog = false; if(useLog === true) { var customConsole = window.console; } else { var customConsole = { group : function () {}, log : function () {}, groupEnd: function () {} }; } |
Nun kann ich in meinen Script meine schaltbare Logausgabe verwenden.
Ist useLog auf false gesetzt wird keine Ausgabe erzeugt.
|
customConsole.log("Meine Logausgabe") |
Exportieren
Einzelne MySQL Datenbank exportieren
|
mysqldump -u username -p database_name > dump.sql |
Die Struktur einer MySQL Datenbank exportieren
|
mysqldump -u username -p --no-data database_name > dump.sql |
Die Daten aus einer MySQL Datenbank exportieren
|
mysqldump -u username -p --no-create-info database_name > dump.sql |
Mehrere MySQL Datenbanken exportieren
|
mysqldump -u username -p --databases db_name1 [db_name2 ...] > dump.sql |
Alle Mysql Datenbanken in eine Datei exportieren
|
mysqldump -u username -p --all-databases --skip-lock-tables > alldatabases.sql |
Importieren
MySQL Datenbank importieren
|
mysql -u username -p -D MeineDB < database.sql |
Eine Datenbank aus der Datei „alldatabases.sql“ importieren
|
mysql -u username -p --one-database destdbname < alldatabases.sql |
Sonstiges
Fehler übergehen -f force
Einen Teil eines Strings suchen und ersetzen:
|
UPDATE MeineTabelle SET MeinFeld = REPLACE(MeinFeld, 'suchstring', 'replacestring') |
Oft ist es hilfreich ein Swapfile zu nutzen.
Man kann dies relativ einfach anlegen.
Als erstes erstellen wir eine Datei mit einer festen Größe für das Swapfile
bs = steht für Blocksize
count = Anzahl der Blöcke
Größe der Datei = bs*count
|
dd if=/dev/zero of=/pfad/zum/swapfile bs=1M count=1024 |
Wir bereiten die Datei für den Einsatz als Swap vor. – Das gilt auch für Swap Partitionen
|
mkswap /pfad/zum/swapfile |
Nun aktivieren wir den neuen Swap-Speicher
|
swapon /pfad/zum/swapfile |
Damit das Swapfile automatisch beim reboot geladen wird, konfigurieren wir noch die /etc/fstab
|
/pfad/zum/swapfile swap swap defaults 0 0 |
Sollte ein altes Swapfile, was nun nicht mehr benötigt wird, vorhanden sein, dann kann man dieses deaktivieren und abschließend löschen.
Der alte Eintrag in der fstab muss natürlich auch entfernt werden.
|
swapoff /pfad/zum/alten/swapfile |
Jedes Zertifikat besteht aus einem privaten und einen öffentlichen Key.
Die Dateinamen sollten so gewählt werden, das diese nachher durch diesen zugeordnet werden können.
Wir erstellen den privaten Key
|
openssl genrsa -out /pad/cert.key 1024 |
Anschließend erstellen wir aus dem privaten Key eine Zertifizierungsanforderungsdatei (csr)
|
openssl req -new -key /pad/cert.key -out /pad/cert.csr |
Für die Erstellung der csr-Datei wird man nun gebeten einige Informationen auszufüllen.
Besonders wichtig ist die Angabe von:
|
Common Name (e.g. server FQDN or YOUR name) []: |
Hier muss der komplette Domainname eingegeben werden, für den das Zertifikat gültig ist. Wenn die Domain mit www erreichbar ist, dann muss hier auch www im Domainnamen aufgeführt sein!
Für Testserver reicht hier auch ein localhost.
Nun erstellen wir das Zertifikat, die Gültigkeitsdauer gibt die Angabe in Tagen an.
|
openssl x509 -req -days 3650 -in /pad/cert.csr -signkey /pad/cert.key -out /pad/cert.crt |
Um unseren Server mit https auszustatten benötigen wir ein Zertifikat, dieses bekommen wir zB. unserem Hoster oder einem Anbieter wie zB. StartSSL.
Wenn es sich um einen Testserver handelt, kann man sich auch selbst ein Zertifikat erstellen, allerdings wird dieses von den Internetbrowsern dann bemängelt.
Nun richten wir dieses Zertifikat in unserem Apache ein.
Als erstes stellen wir sicher das das SSL Modul aktiviert ist.
Anschließend prüfen wir, ob der Webserver auch auf dem Port 443 arbeitet, dazu muss folgender Eintrag in der ports.conf aktiviert sein.
|
vi /etc/apache2/ports.conf |
|
<IfModule mod_ssl.c> Listen 443 </IfModule> |
Nun bearbeiten wir noch unsere Konfiguration der Domain, die mit SSL arbeiten soll.
Alle aktivierten Konfigurationen findet man im Verzeichnis sites-enabled. Wir editieren hier die entsprechende, in unserem Fall die 000-default
|
vi /etc/apache2/sites-enabled/000-default |
|
<VirtualHost *:443> DocumentRoot /Pfad/htdocs <Directory /Pfad/htdocs> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> SSLEngine on SSLCertificateKeyFile /Pfad/Zum/Zertifikat.key SSLCertificateFile /Pfad/Zum/Zertifikat.crt </VirtualHost> |
Abschließend starten wir den Apache mit folgendem Befehl neu:
Wer Composer auf seinem Server nutzen möchte, kann ihn wie folgt einrichten:
|
curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer |
Nun sollte Composer auf dem Server verfügbar sein.
Als nächstes richten wir uns ein Projektordner ein, in diesen erstellen wir die Datei composer.json mit folgenden Beispielinhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
{ "name": "Name meiner Anwendung", "description": "Beschreibung", "bin-dir": "bin", "license": "MIT", "require": { "monolog/monolog": "1.*", "symfony/yaml": "3.0.*@dev", "smarty/smarty": "~3.1" }, "autoload": { "psr-4": { "Name\\Namespace\\": "src/folder" } }, "require-dev": { "phpdocumentor/phpdocumentor": "dev-master", "phpunit/phpunit": "^4.6" } } |
Mit einen einfachen
installieren wir nun unserer konfigurierten Pakete.
Unter Umständen können wir nicht alles aus den Repositories von GitHub laden. Dazu benötigen wir einen API Token.
Erzeugen können wir diesen, indem wir uns einen GitHub Account einrichten. Nun können wir dort unter „Settings->Personal access tokens->Generate new Token“ einen neuen Token erstellen.
Diesen Token geben wir bei Aufforderung durch den Composer an der Shell einfach ein, oder wir Konfigurieren Composer so, das dieser den Token schon kennt.
|
composer config github-oauth.github.com GITHUB-TOKEN |
Ihr habt einen WordPress Blog. Damit man individuelle Anpassungen wie Themes oder eigene Erweiterungen komfortabel einarbeiten kann, sollte man sich die WordPress Installation lokal verfügbar machen.
Dazu kopieren wir uns erst einmal die Datenbank und alle Daten des WordPress vom Server auf dem lokalen PC, idealerweise richtet man sich hier auch ein Versionssystem wie Git oder SVN ein.
Als erstes müssen wir die Verbindung zu Datenbank anpassen, diese steht in der wp-config.php.
Hier passen wir folgende Zeilen an:
|
define('DB_NAME', '%%%Name_der_Datenbank%%%'); define('DB_USER', '%%%Datenbankbenutzer%%%'); define('DB_PASSWORD', '%%%Passwort%%%'); |
Diese Datei dürfen wir nun natürlich nicht mehr auf dem Webserver kopieren, sonst ist dieser nicht mehr lauffähig.
Damit unser lokales WordPress nicht ständig auf die Online URLs verlinkt müssen wir eine kleine Anpassung durchführen.
Dazu gehen wir in der Datenbank in die Tabelle wp_options dort passen wir die Einträge siteurl und home auf unsere lokale Pfadangabe an.
Hin und wieder möchte man ein Verzeichnis Online verfügbar machen, welches nicht für jedermann gedacht ist.
Da man dazu nun nicht unbedingt eine Authentifizierungs-Logik schreiben möchte kann man dies auch per .htacces Datei erledigen.
In der Regel kann dies jedes Webhosting-Paket, meist kann man dies dann irgendwo im Kundenbereich konfigurieren.
Hat man einen eigenen Server zu Verfügung, so kann man einfach eine Passwortdatei und eine .htaccess Datei im entsprechenden Verzeichnis anlegen.
Die Passwortdatei erstellen wir wie folgt
|
htpasswd -c %Datei% %User% |
Im folgenden Dialog kann das Passwort eingegeben werden.
|
AuthType Basic AuthName "Geschützter Bereich" AuthUserFile %PasswortDatei% require user %User% |
Sollten die verwendeten SSL Zertifikat des Apache eine Passphrase haben, so kommt es zu ungewollten Fehlern beim Neustart des Servers. Da sie Passphrase beim starten nicht eingegeben werden kann.
Am besten legen wir uns erst einmal eine Sicherungskopie des Zertifikates an:
|
cp %mein.key% %mein.key.bkp% |
Nun können wir die Passphrase entfernen, dazu müssen wir diese kennen, da sie im Prozess abgefragt wird.
|
openssl rsa -in %mein.key% -out %mein.key% |
Anschließend starten wir den Apache neu und können unsere SSL Verbindung testen.
Unter Umständen ist es nötig, einen Rsync-Aufruf mit einer Portangabe zu initiieren.
|
rsync -av -e 'ssh -p 1025' /pfad %User%@%Server%:/pfad/ |
Wer eine Webseite betreibt, die er mittels get-text multilingual aufbaut, der muss auch seine Linux Systemsprachen anpassen.
Zum einen benötigen wir für die Übersetzungen gettext, dies kann man per apt-get installieren.
Sprachen die man zur Verfügung stellen möchte, benötigt man dann auch als Systemsprache, diese kann man jederzeit nachkonfigurieren.
Hier gibt es eine kleine Ansammlung an nützlichen aufrufen rund um die Paketverwaltung.
Auflistung aller installierten Pakete:
Wenn man eine Funktion nicht zur Verfügung hat kann man sein Glück so versuchen:
|
apt-cache search %Funktion% |
Für die Kommunikation zweier Linux Server, z.B. ein Datenbackup mittels rsync, muss man sich zwangsläufig per SSH anmelden.
Hierfür empfiehlt es sich, einen Zugang per Zertifikat zu wählen. Zum einen ist es sehr komfortabel, zum anderen ist es auch viel sicherer. Zumindest wenn man in einen weiteren Schritt den Zugang per Passwort unterbindet bzw. ein sehr sicheres Passwort wählt.
Damit wir uns auf dem entfernten Server einloggen können, benötigen wir dort einen Benutzer der sich per SSH Anmelden darf. Dazu empfehle ich den Server wie folgt zu konfigurieren: Linux SSH Root Zugang verbieten.
Wenn diese Voraussetzung erfüllt sind, kann ich mich wie folgt verbinden.
|
ssh %EntfernterBenutzer%@%EntfernterServer% |
Allerdings wird jetzt noch eine Passwort abgefragt.
Damit wir zukünftig kein Passwort mehr angeben müssen, erstellen wir ein Schlüsselpaar.
Nun müssen wir den Public Key auf den entfernten Server übertragen.
|
ssh-copy-id -i ~/.ssh/id_rsa.pub %EntfernterBenutzer%@%EntfernterServer% # Sollte SSH nicht auf dem Standardport laufen, kann man die diesen wie folgt mit angeben ssh-copy-id -i ~/.ssh/id_rsa.pub '-p %SSHPort% %EntfernterBenutzer%@%EntfernterServer%' # Wenn ssh-copy-id nicht zur Verfügung steht, kann der Schlüssel auch per cat übertragen werden cat ~/.ssh/*.pub | ssh %EntfernterBenutzer%@%EntfernterServer% 'cat>>.ssh/authorized_keys' |
Nun können wir den passwortlosen Zugriff testen
|
ssh %EntfernterBenutzer%@%EntfernterServer% |
Sollte es Probleme geben, können wir uns wie folgt Details zum Verbindungsaufbau anzeigen lassen.
|
ssh -v %EntfernterBenutzer%@%EntfernterServer% |
Das alte Passwort kann man auf dem Zielserver wie folgt deaktivieren
|
passwd %EntfernterBenutzer% -d |
In aller Regel erhaltet ihr von eurem Hoster ein vorgefertigtes Image. In meinen Fall ist es ein Debian 7.
Damit nicht jeder Zugang zu eurem Server erlangt, solltet ihr euch ausschließlich mit einem eigenen Benutzer per ssh anmelden. Eine Anmeldung mit dem Root-Benutzer solltet ihr verbieten. Die Root-Rechte erlangen wir in Zukunft erst nach einem Ummelden des Benutzers.
Als erstes installieren wir Sudo.
Und OpenSSH-Server
Nun legen wir eine Gruppe an, in der alle Benutzer Mitglied werden, welche sich am Server anmelden können.
Anschließend erstellen wir unseren Benutzer.
Damit sich dieser per ssh anmelden kann, müssen wir den neuen Benutzer der Gruppe ssh-users hinzufügen.
|
adduser %USERNAME% ssh-users |
Um später Root-Rechte zu erlangen benötigt dieser auch eine Mitglidschaft in der Gruppe sudo.
Jetzt konfigurieren wir ssh noch so, dass die Mitglieder der Gruppe ssh-users sich per ssh anmelden können.
|
vi /etc/ssh/sshd_config # Zeile hinzufügen: AllowGroups ssh-users |
Nun starten wir den ssh-Dienst neu
Nun können wir mit einer weiteren putty-Session schon einmal den Loginvorgang des neues Users prüfen.
Nach dem erfolgreichen Login melden wir uns wie folgt zum root-Benutzer um:
Wenn das alles funktioniert hat, dann verbieten wir den direkten ssh-Zugang des Root Benutzers.
Dazu öffnen wir wieder die ssh-config und passen folgende Zeile an
|
vi /etc/ssh/sshd_config # Root Login verbieten PermitRootLogin yes |
Auch nach dieser Änderung starten wir den ssh Dienst neu.
Nun ist es nicht mehr möglich sich als Root-Benutzer per ssh an der Konsole anzumelden.