System administration - Seljaki/wiki GitHub Wiki
Uvod
V sklopu predmeta Sistemska administracija smo pridobili praktične izkušnje na področju upravljanja in vzdrževanja računalniških sistemov. Osredotočili smo se na ključne naloge, ki jih sistemski administratorji redno opravljajo, s posebnim poudarkom na Linux okolju. Naš cilj je bil vzpostaviti robustno in varno strežniško infrastrukturo, ki omogoča učinkovito in zanesljivo delovanje aplikacij.
Načrtovane naloge
Za vzpostavitev projekta smo uporabili:
- Linux server
- Docker
- Docker hub
- Github & github actions
- Watchtower
- Portainer
- OpenVPN
Za naš projekt smo potrebovali strežnik, za dve spletni aplikaciji in podatkovno bazo. Odločili smo se za lasten strežnik, ker smo ga že imeli pripravljenega in konfiguriranega, ter tudi ker ima na voljo več pomnilnika od brezplačnega študentskega načrta, ki ga ponuja Microsoft Azure [1]. Strežnik ima 16gb pomnilnika, 6 jeder in nameščen distribucijo tipa Debian:
Slika 1 : izpis programa neofetch na strežniku
Najprej sem ustvaril lokalni račun Mojci in Lovrotu in jima nato še omogočil dostop do strežnika preko VPN-a.
Slika 2 : primer povezave vpn-a na strežnik
Za hitrejšo vzpostavitev dockerja, sem uporabil portainer [2], ki je spletna aplikacija za grafično upravljanje dockerja, ki nam je zelo ulajšala delo z dockerjem.
Slika 3 : prikaz docker compose stacka v portainerju
Za upravljanje izvorne kode smo uporabili git in github, kjer smo meli avtomatske akcije (CI/CD), ki so se sprožle ob »merg-u« na main. Te akcije so posodobile sliko na docker hub-u, in sprožile posodobitev na strežniku.
Slika 4 : prikaz server repozitorija na GitHub-u
Slika 5 : prikaz uspešne akcije na GitHub-u
Slike smo nalagali na docker hub. Ker smo uporabljali brezplačen račun smo lahko imeli samo
eno sliko privatno [3].
Slika 6 : slika docker hub domače strani
Uporabili smo še WatchTower, za avtomatsko posodobitev slik. WatchTower je bil nameščen v
dockerju.
Slika 7 : Prikaz poteka posodobitve slike na serverju
Implementacija
Github action
Ta GitHub Action konfiguracijska datoteka je zasnovana za avtomatizacijo procesa objavljanja Docker slike na Docker Hub vsakič, ko je koda potisnjena na glavno vejo (main) repozitorija.
Opis kode:
Za zagon akcij uporabimo ubuntu vm. Token je podan kot secret, za varno uporabo. Nato pridobimo podatke z repozatorija, nato zgradimo sliko z dockerfile-a, ki jo nato naložimo v docker hub. Potem počakamo okoli 30s, da poskrbimo da je docker slika naložena. Nato pošljemo http request z geslom na webhook servica watchtower, ki posodobi docker sliko na serveju.
name: Publish docker image
on:
push:
branches: ["main"]
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
attestations: write
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v
- name: Log in to Docker Hub
uses: docker/login-action@v
with:
username: mrdog
password: ${{ secrets.DOCKER_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b
with:
images: mrdog210/seljaki-server
- name: Build and push Docker image
id: push
uses: docker/build-push-
action@3b5e8027fcad23fda98b2e3ac259d8d67585f
with:
context:.
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Waiting for docker upload
uses: jakejarvis/wait-action@master
with:
time: "30s"
- name: Webhook
uses: indiesdev/curl@v1.
with:
url: https://seljaki-watch.schnapsen66.eu/v1/update
method: "POST"
accept: 200,201,
timeout: 120000
bearer-token: ${{ secrets.WATCHTOWER_TOKEN }}
log-response: true
retries: 1
Dockerfile
Server
Koda je zelo preprosta, uporabimo najnovejši image node. Nastavimo delovni direktorij v sliki, prekopiramo datoteke, naložimo npm pakete in nastavimo začetni ukaz.
FROM node:latest
WORKDIR /server
COPY..
RUN npm install
CMD [ "npm", "run", "start" ]
Frontend
Ker se react buildati v html in js, potrebujemo dva imega. Najprej z builderom zgradimo sliko, kjer uporabimo podoben postopek kot pri serverju. Nato pa iz direktorija /build prekopiramo datoteke v http server image. Mi uporabljamo nginx so pa alternativi (apache).
Fetching the latest node image on apline linux
FROM node:alpine AS builder
# Declaring env
ENV NODE_ENV production
ENV REACT_APP_SERVER=https://seljaki-server.schnapsen66.eu
# Setting up the work directory
WORKDIR /app
# Installing dependencies
COPY ./package.json ./
RUN npm install
# Copying all the files in our project
COPY..
# Building our application
RUN npm run build
# Fetching the latest nginx image
FROM nginx
# Copying built assets from builder
COPY --from=builder /app/build /usr/share/nginx/html
# Copying our nginx.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
Povezovanje na server
Ker odpiranje ssh porta javnosti ni zelo varno, saj je lahko ranljiv na ssh brute force napade, uporabljamo OpenVPN, kjer lahko dostopamo do vseh storitev strežnika, ki niso direktno odprte na splet, kot npr postgres strežnik ali grafični vmesnik za docker (portainer).
Avtomatsko posodabljanje docker slik na strežniku
Za avtomatsko posodabljanje slik uporabljamo program Watchtower [4]. Deluje tako, da ga dodamo v docker compose našega stacka in mu dodelimo direktorij od docker socketa in datoteke s podatki za prijavo na docker hub. Vsem slikam še dodamo ustrezen label, ki watchtower-ju pove katere slike naj nadzira za spremebo. Ko se zgodi sprememba slike, pošljemo request na webhook na protu 8081, kateremu priložimo geslo.
version: '3.8'
services:
seljaki-frontend:
image: mrdog210/seljaki-frontend:master
restart: unless-stopped
labels:
- "com.centurylinklabs.watchtower.enable=true"
environment:
- REACT_APP_SERVER=https://seljaki-server.schnapsen66.eu
ports:
- 3332:80
postgres_server:
image: postgis/postgis:16-master
restart: unless-stopped
environment:
POSTGRES_USER: seljaki
POSTGRES_PASSWORD: alex18cm
POSTGRES_DB: seljaki
POSTGRES_MULTIPLE_EXTENSIONS: postgis
ports:
- "5432:5432"
volumes:
# - ./sql-scripts:/docker-entrypoint-initdb.d
- seljakidbpostgis:/var/lib/postgres
seljaki-server:
image: mrdog210/seljaki-server:main
restart: unless-stopped
labels:
- "com.centurylinklabs.watchtower.enable=true"
environment:
- PORT=3000
- PG_HOST=postgres_server
- PG_PORT=5432
- PG_DB=seljaki
- PG_USERNAME=seljaki
- PG_PASSWORD=alex18cm
- JWT_SECRET=Shrek
ports:
- 3333:3000
depends_on:
- postgres_server
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/.docker/config.json:/config.json
command: --debug --http-api-update
environment:
- WATCHTOWER_HTTP_API_TOKEN=aaaa
labels:
- "com.centurylinklabs.watchtower.enable=false"
ports:
- 8081:8080
volumes:
seljakidbpostgis:
Avtomatski zagon testov
Ob novem merg requestu na main se zažene GH akcija, ki zažene teste in javi če so vsi uspešni. Test lahko zaženeš ročno, sprožijo pa se tudi avtomatsko.
name: Run tests
on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Setup kotlin
uses: gradle/actions/setup-gradle@v3
- name: Make gradlew executable
run: chmod +x ./gradlew && gradle wrapper
- name: Build
run: ./gradlew build
- name: Run tests
run: ./gradlew test
Nadgradnje projekta
Prihodnje nadgradnje, ki bi jih lahko uvedli, so samodejna gradna in objavljanje namizne aplikacije na github-u.
Zaključek
Skozi ta predmet smo si pridobili praktična znanja in veščine, ki so nujna za uspešno delovanje kot sistemski administratorji. Naš končni cilj je bil vzpostaviti stabilno, varno in učinkovito strežniško okolje, ki podpira avtomatizirane procese in omogoča zanesljivo delovanje aplikacij, na katero smo kar ponosni.
[1] „Azure for College Students—Offer Details | Microsoft Azure“. Pridobljeno: 31. maj 2024.
[Na spletu]. Dostopno na: https://azure.microsoft.com/en-us/pricing/offers/ms-azr-0170p
[2] „Kubernetes and Docker Container Management Software“. Pridobljeno: 31. maj 2024. [Na
spletu]. Dostopno na: https://www.portainer.io
[3] „Pricing | Docker“. Pridobljeno: 31. maj 2024. [Na spletu]. Dostopno na:
https://www.docker.com/pricing/
[4] „containrrr/watchtower“. containrrr, 31. maj 2024. Pridobljeno: 31. maj 2024. [Na spletu].
Dostopno na: https://github.com/containrrr/watchtower