There are two options how to run application. Develop and deploy mode.
Both modes are using same docker volume (same database is loaded).
.env.example in .envclient/.env.development.example in client/.env.development Wenn Sie die App im Entwicklungsmodus ausführen möchtenclient/.env.production.example in client/.env.production Wenn Sie die App im Produktionsmodus ausführen möchten${REACT_APP_GOOGLE_API} zu erhalten, befolgen Sie diese Schritte This will just run db and pgadmin containers. React and server instances are running separately, outside of containers.
${DB_HOST} von .env an: localhostdocker-compose -f docker-compose.dev.yml up -dnpm i && npm run server${REACT_APP_BASE_URL} client/.env.development ${SERVER_PORT} .envcd client && npm i && cd .. && npm run clientlocalhost:3000 erhältlich This will run db, pgadmin, server and build react with disabled redux devtools.
${DB_HOST} von .env zu postgres .docker-compose up -d .localhost:${SERVER_PORT} .Für die korrekte Anwendungsfunktion muss zuerst die Datenbank ausgefüllt werden. Wir werden die Befehlszeile verwenden, um dies zu erreichen.
Navigieren Sie aus dem Root -Verzeichnis zum Verzeichnis, in dem sich exportierte Daten befinden.
cd dummy Kopieren Sie dann Daten in das Ausführen von Postgres Container (für den Entwicklungsmodus verwenden Sie dev_postgres_container ).
docker cp dbexport.sql postgres_container:/
Geben Sie dann den Container ein (für den Entwicklungsmodus verwenden Sie dev_postgres_container ).
docker exec -it postgres_container /bin/bash
Wenn Sie Daten in bereits besiedelte Datenbank importieren möchten, müssen Sie zuerst die vorhandene Tabelle entfernen und dann eine neue erstellen. In Containerkonsole fallen vor der vorhandenen Datenbank. (Überspringen Sie diesen Schritt, wenn Sie noch keine Datenbank erstellt haben)
dropdb -U ${DB_USER} ${DB_NAME}Melden Sie sich als Benutzer bei Postgres Server an.
su - ${DB_USER}Erstellen Sie dann eine neue Datenbank.
createdb ${DB_NAME}Beenden Sie die Postgres Server -Konsole.
exitDatenbank mit neuen Daten füllen.
psql -d ${DB_NAME} -U ${DB_USER} -f dbexport.sql Jetzt können Sie sich bei der Anwendung anmelden. Beide, name und password lautet: admin .
localhost:${DB_PORT}${DB_USER}${DB_PASSWORD}http://localhost:${PGADMIN_PORT}${PGADMIN_EMAIL}${PGADMIN_PASSWORD}postgres${DB_PORT}${DB_NAME}${DB_PASSWORD} Die Docker -Datei befindet sich auf der Stammebene des Projekts und wird nur für den Bereitstellungsmodus verwendet.
# Dockerfile
FROM node:latest
WORKDIR /server
COPY . ./
RUN npm install
RUN npm install --prefix client
CMD npm run build Zunächst wird der neueste Knoten heruntergeladen und /server Working -Verzeichnis wird in neu erstelltem Container erstellt. In dieses Arbeitsverzeichnis wird der gesamte Quellcode kopiert und erwartet von in client/.dockerignore angegebenen Dateien. Diese Dateien werden weggelassen. Anschließend werden Knotenabhängigkeiten in das Arbeitsverzeichnis für Server- und Client -Instanken installiert. Zuletzt wird der Befehl npm run build aufgerufen, der sich in package.json befindet. Dieser Befehl erstellt zuerst die React -Anwendung und dann den Server aus. Wenn der Server auf diese Weise gestartet wird, wird die Umgebungsvariable NODE_ENV auf production eingestellt und die erstellte Version der React -Anwendung verwendet.
Wir verwenden zwei Docker-Compose-Dateien. Der docker-compose.dev.yml für Entwicklungsmodus und docker-compose.yml für den Produktionsmodus, beide im Root-Verzeichnis. Jede Komponierungsdateien lädt die in .env -Datei angegebenen Umgebungsvariablen.
# docker-compose.dev.yml
version : " 3.5 "
# inspired by https://github.com/khezen/compose-postgres
services :
postgres :
container_name : postgres_container
image : postgres:11
environment :
POSTGRES_USER : ${DB_USER}
POSTGRES_PASSWORD : ${DB_PASSWORD}
PGDATA : /data/postgres
volumes :
- postgres:/data/postgres
ports :
- " ${DB_PORT}:5432 "
networks :
- postgres
restart : always
pgadmin :
container_name : pgadmin_container
image : dpage/pgadmin4
environment :
PGADMIN_DEFAULT_EMAIL : ${PGADMIN_EMAIL}
PGADMIN_DEFAULT_PASSWORD : ${PGADMIN_PASSWORD}
PGADMIN_CONFIG_SERVER_MODE : " False "
volumes :
- pgadmin:/root/.pgadmin
ports :
- " ${PGADMIN_PORT}:80 "
networks :
- postgres
restart : always
server :
container_name : server_container
build :
context : .
dockerfile : Dockerfile
depends_on :
- postgres
ports :
- " ${SERVER_PORT}:${SERVER_PORT} "
networks :
- postgres
restart : always
networks :
postgres :
driver : bridge
volumes :
postgres :
pgadmin : Diese Komponierungskonfiguration erstellt 3 Container, 1 Netzwerk und 1 Volumen zum Speichern anhaltender Daten. Jeder Container verwendet dasselbe Netzwerk für die Kommunikation mit anderen Containern. Jeder Container startet nach dem Ausfall automatisch neu. Container postgres_container erstellt PostgreSQL Server, wobei die persistenten Daten in Volumen gespeichert werden. Es gibt auch Container pgadmin_container , der SQL -Client ist. Letzter Container mit dem Namen server_container ist dort, wo unsere Haupt -App ausgeführt wird. Anstelle von Bild verwendet es Build, definiert in DockerFile, erörtert im vorherigen Abschnitt.
Die Konfiguration für den Entwicklungsmodus komponieren sich für den Bereitstellungsmodus sehr ähnlich. Der einzige Unterschied besteht darin, dass es keinen server_container gibt, da Server und Client separate Instanzen sind, die von Docker ausgehen.
.env.example in .env und setzen Sie den Wert von ${DB_HOST} auf postgres .client/.env.production.example in client/.env.production um.${REACT_APP_GOOGLE_API} in client/.env.production zu erhalten. Reverse Proxy muss so eingestellt werden, dass der Zugriff an Jenkins und Application Server weitergeleitet wird. Die in ./env angegebenen Ports müssen mit denen in Nginx Reverse Proxy -Konfiguration übereinstimmen.
Navigieren Sie zunächst zu verfügbaren Websites -Konfigurationsverzeichnissen.
cd /etc/nginx/sites-available/ Konfigurationsdatei erstellen. Sie können es so nennen, wie Sie es haben. Gute Praxis ist es, es genauso zu nennen wie Ihre DNS -Adresse. In unserem Fall ist es lora.fiit.stuba.sk .
touch lora.fiit.stuba.sk Kopieren und fügen Sie den folgenden Code in die neu erstellte Datei ein und fügen Sie sie ein. Ändern Sie die Konfiguration von proxy_pass für jeden Speicherort, um die in .env angegebenen Ports zu entsprechen. Vergessen Sie nicht, server_name auch an Ihren DNS anzupassen.
upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}
# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
server_name lora.fiit.stuba.sk www.lora.fiit.stuba.sk;
# this is the jenkins web root directory
# (mentioned in the /etc/default/jenkins file)
root /var/run/jenkins/war/;
access_log /var/log/nginx/jenkins/access.log;
error_log /var/log/nginx/jenkins/error.log;
# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;
location /jenkins/ {
autoindex on ;
sendfile off ;
proxy_pass http://jenkins/jenkins/;
proxy_redirect default ;
proxy_http_version 1.1 ;
# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade ;
proxy_set_header Upgrade $http_upgrade ;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $scheme ;
proxy_max_temp_file_size 0 ;
#this is the maximum upload size
client_max_body_size 10m ;
client_body_buffer_size 128k ;
proxy_connect_timeout 90 ;
proxy_send_timeout 90 ;
proxy_read_timeout 90 ;
proxy_buffering off ;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection "" ; # Clear for keepalive
}
location / {
#Add serving gzipped files
gzip_static on ;
gzip on ;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 256 ;
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss text/javascript
application/atom+xml
application/geo+json
application/x-javascript
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
font/eot
font/otf
font/ttf
image/svg+xml;
proxy_pass http://127.0.0.1:5000/;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $scheme ;
# enable WebSockets
proxy_http_version 1.1 ;
proxy_set_header Upgrade $http_upgrade ;
proxy_set_header Connection "upgrade" ;
}
listen 443 ssl; # managed by Certbot
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/lora.fiit.stuba.sk/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/lora.fiit.stuba.sk/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# SSL redirect from HTTP to HTTPS
server {
if ( $host = lora.fiit.stuba.sk) {
return 301 https:// $host$request_uri ;
} # managed by Certbot
listen 80 ;
server_name lora.fiit.stuba.sk www.lora.fiit.stuba.sk;
return 404 ; # managed by Certbot
}Datei speichern und den Nginx -Dienst neu starten
sudo systemctl restart nginx Die Jenkins -Anwendung sollte unter lora.fiit.stuba.sk/jenkins zugänglich sein. In Ihrem Fall wäre es Ihr DNS -Name anstelle von lora.fiit.stuba.sk .
Wenn Sie das Standard -Home für Jenkins ändern möchten, können Sie JENKINS_HOME Variable ändern. Der Leitfaden ist stark von diesem Tutorial inspiriert.
Erstellen Sie ein neues Verzeichnis, wohin Sie die Jenkins nach Hause bringen möchten. In unserem Fall ist es /data/jenkins .
mkdir /data/jenkinsÄndern Sie das Eigentum an neu erstelltem Verzeichnis.
sudo chown jenkins:jenkins /data/jenkins Kopieren Sie den Inhalt des alten Jenkins Home Directory, /var/lib/jenkins/ , in das neue Jenkins Home Directory, /data/jenkins/ unter Verwendung des folgenden Befehls.
sudo cp -prv /var/lib/jenkins /data/jenkins/Ändern Sie als nächstes das Jenkins -Benutzerhaus.
sudo usermod -d /data/jenkins/ jenkins Aktualisieren Sie den neuen Jenkins Home Directory Path in /etc/default/jenkins . Sie können jeden Editor Ihrer Wahl verwenden. In unserem Fall verwenden wir VI.
sudo vi /etc/default/jenkinsScrollen Sie zum Jenkins -Heimstandort und aktualisieren Sie den neuen Heimverzeichnisweg.
# defaults for Jenkins automation server
# pulled in from the init script; makes things easier.
NAME=jenkins
# arguments to pass to java
# Allow graphs etc. to work even when an X server is present
JAVA_ARGS= " -Djava.awt.headless=true "
# JAVA_ARGS="-Xmx256m"
# make jenkins listen on IPv4 address
# JAVA_ARGS="-Djava.net.preferIPv4Stack=true"
PIDFILE=/var/run/$NAME/$NAME.pid
# user and group to be invoked as (default to jenkins)
JENKINS_USER=$NAME
JENKINS_GROUP=$NAME
# location of the jenkins war file
JENKINS_WAR=/usr/share/$NAME/$NAME.war
# jenkins home location
JENKINS_HOME=/data/$NAME
# set this to false if you don't want Jenkins to run by itself
# in this set up, you are expected to provide a servlet container
# to host jenkins.
RUN_STANDALONE=trueStarten Sie den Jenkins -Dienst mit dem folgenden Befehl.
sudo service jenkins start
Besuchen Sie Jenkins von Ihrem Browser unter lora.fiit.stuba.sk/jenkins .
Melden Sie sich in die Anwendung an.
Navigieren Sie zur Manage Jenkins -Taste auf der linken Seite des Bildschirms.
Klicken Sie auf die Registerkarte Manage Credentials in Security group .
Klicken Sie dann auf den (global) Link in der Tabelle.
Klicken Sie auf die Schaltfläche addCredentials auf der linken Seite des Bildschirms.
Wählen Sie die Option Secret file aus Kind -Dropdown -Menü.
Laden Sie erfüllt .env -Datei und ID -Feld auf env .
Wiederholen Sie den Schritt 6 und laden Sie den erfüllten client/.env.production -Datei hoch und setzen Sie das ID -Feld auf envClient .
Erstellen Sie weitere Anmeldeinformationen, wählen Sie diesmal jedoch SSH Username with private key aus dem Dropdown -Menü. Setzen Sie das ID-Feld auf lora-application-server-ssh . Um SSH -Tasten für Ihr Repository (wobei der Quellcode des Anwendungsservers ist) zu erhalten, folgen Sie diesen Anweisungen.
Klicken Sie von Dashboard auf die Schaltfläche New Item , die sich in der linken Seite des Bildschirms befindet.
Geben Sie den gewünschten Namen ein, klicken Sie auf Pipeline -Schaltfläche und bestätigen Sie, wie Sie auf die Schaltfläche OK klicken.
Zum Pipeline -Skript einfügen folgende Code einfügen
node {
/*** 1 Pull new changes from git branch deploy ***/
stage ( 'Pull master branch' ) {
git credentialsId : 'lora-application-server-ssh' , url : '[email protected]:danielhros/lora-application-server.git'
}
/*** 2 Add secret enviroment variables stored securely in Jenkins ***/
stage ( 'Add enviroment variables' ) {
/* 2.1 Remove .env file if exists */
sh 'rm -f -- .env'
/* 2.2 Add .env file to server */
withCredentials ( [ file ( credentialsId : 'env' , variable : 'env' ) ] ) {
sh "cp $env ./"
}
/* 2.2 Add .env file to client */
withCredentials ( [ file ( credentialsId : 'envClient' , variable : 'envClient' ) ] ) {
sh 'cp $envClient client/.env.production'
}
}
/*** 3 Build docker image ***/
stage ( 'Build docker image' ) {
sh '(docker-compose build)'
}
/*** 4 Run docker image in production ***/
stage ( 'Run docker images' ) {
sh '(docker-compose up -d)'
}
/*** 5 Clean after build ***/
stage ( 'Clean workspace' ) {
sh 'docker system prune -f'
cleanWs ( )
}
}Speichern Sie Änderungen und führen Sie Ihre erste Pipeline aus
Glückwunsch! Nachdem die Pipeline die Anwendung erfolgreich erstellt und bereitgestellt hat, ist Ihre App unter lora.fiit.stuba.sk zugegriffen.