Ich habe viele Beiträge gesehen in den beschreiben wird wie man vue oder nuxt apps baut und auf dem Server ausrollt. Leider zeigt keines dieser Postings wie man es mit gitlab ci und einem nginx hinbekommen. Ich versuche hier meine Erfahrungen zusammenzuschreiben in der Hoffnung jemanden den holprigen Weg zu ersparen, den ich gegangen bin.
Vorbereitung
Die App
Zuerst brauchen wir eine nuxt Applikation, die wir ausliefern möchten.
Diese können wir relativ einfach über einen Terminal Befehl erstellen.
npx create-nuxt-app my-website
Das Repository
Um den CI Prozess von Gitlab zu nutzen, reicht ein Kostenloser Account, in dem man ein Neues Repository anlegt oder ein bestehendes benutzt.
Wie man ein neues Anlegt kann man auf der Seite https://docs.gitlab.com/ee/user/project/repository/#create-a-repository nachlesen
Nachdem man dies erledigt hat, muss man einen Private Key hinterlegen. Die CI braucht diesen um Daten via rsync ausliefern zu können.
Wie man ein Key Paar erstellt findet ihr hier. https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key
In meinem Fall wird die Variable SSH_PRIVATE_KEY genannt. Diese Bezeichnung brauchen wir später in unserer Konfiguration
Den Public Key müsst ihr dann auf Euerem Server hinterlegen. Wichtig ist hier das der Key auch dem Benutzer zugeordnet wird der später auch von nginx benutzt wird, um die Seite auszuliefern. Meistens ist dies der www-data Benutzer.
Abschluss der Vorbereitung
So mehr müsst ich auch schon nicht machen denn ab jetzt kommt es nur noch auf die Konfiguration an.
Gitlab CI
Um die Gitlab CI anzusprechen brauchen wir eine Datei im root unseres Projektes.
Diese Datei trägt den Namen .gitlab-ci.yaml.
Sobald Gitlab diese Datei erkennt, wird der CI Runner Aktiv und führt die Darin enthaltenen Befehle aus.
Image
Das Image, dass wir definieren wird für alle Befehle verwendet die nicht ein Explizites image besitzen. Wir verwenden des Node image da dies alles hat was wir zum Bauen unserer Applikation benötigen.
image: node
Variablen
Hier Definieren wir weitere Variablen um sie nicht immer wieder eingeben zu müssen und unsere Datei auch in anderen Projekten verwenden zu können.
variables:
RSYNC: rsync -rtqx --links --safe-links --chmod=Du=rwx,Dgo=rx,Fu=rw,Fog=r --delete
PROD_URL: https://creativeworkspace.de/
PROD_USER: web_www
PROD_SERVER: 159.69.21.63
PROD_PATH: /var/www/clients/client1/web1/web
PROD_PORT: '22'
Cache
Damit gitlab zwischen den Stages die Daten nicht immer neu herunterladen muss und auch ein erneutes Ausführen schneller geht. Lassen wir gitlab den node_modules Ordner speichern. Dies spart uns sehr viel zeit, wenn wir mehrere Builds in kurzen abständen machen.
cache:
paths:
- node_modules/
Die Stages
Damit wir eine Kontrolle haben welcher Prozess von Gitlab in welcher Reihenfolge ausgeführt wird erstellen wir 2 Stages.
Diese Referenzieren wir in unseren Aufgaben die, die Gitlab CI Ausführen soll
stages:
- build
- deploy
Die Aufgaben
Die erste Aufgabe die Gitlab für uns erledigen soll ist das Bauen der Application. Wir speichern uns danach den ordner dist
als Artefakt damit wir diesen dann im 2. Schritt deployen können.
build:
stage: build
before_script:
- npm install
script:
- NODE_ENV=production npm run build
- NODE_ENV=production npm run generate
environment:
name: production
artifacts:
expire_in: 1 hour
name: '${CI_COMMIT_REF_NAME}'
paths:
- dist/
Als nächstes soll Gitlab für uns die Code Ausliefern.
Für diesen Schritt benutze ich nun ein anderes Image das eine RSYNC Kompenente besitzt.
Hier passiert jetzt sehr viel auf einmal. Zuerst Fügen wir unseren generierten SSH Key zum Image hinzu. Anschließend führen wir einen RSYNC auf unseren Server aus. Somit haben wir dann den Inhalt des *dist Ordners auf unserem server in dem Pfad den wir in den Variablen angegeben haben.
deploy:prod:
stage: deploy
image: 1drop/php-73-docker-utils
environment:
name: production
url: https://creativeworkspace.de
before_script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- cd dist/
script:
- $RSYNC -e "ssh -p $PROD_PORT" . $PROD_USER@$PROD_SERVER:$PROD_PATH
only:
- master
Abschluss
Ab jetzt brauchen wir unserem nginx nur noch sagen, dass er die Daten aus diesem Verzeichnis ausliefern soll und fertig :)
Top comments (0)