DEV Community

Cover image for Deploy nuxt.js static mit gitlab-ci
Markus
Markus

Posted on

Deploy nuxt.js static mit gitlab-ci

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
Enter fullscreen mode Exit fullscreen mode

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.

Alt Text

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

Alt Text

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
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

Abschluss

Ab jetzt brauchen wir unserem nginx nur noch sagen, dass er die Daten aus diesem Verzeichnis ausliefern soll und fertig :)

Top comments (0)