Skip to content

suadin/infrastructure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 

Repository files navigation

Table of Contents

  1. Introduction
  2. Domain -> Server | Google
  3. Hosting -> Docker | Teamspeak | Minecraft | PostgreSQL | pgAdmin4
  4. Security -> SSL-Certificate
  5. Website -> GitHub-Repository | DockerHub-Repository | GitHub-Actions | Deployment-Script

Introduction

As full-stack-developer you need as well to know how to host software. For example infrastructure of website but as well other software like Teamspeak3 or Minecraft. Aim of documentation is to host these software with low budget and high functionality.

Domain

Server

Domain suadin.de and Server 81.169.247.92 are currently managed in strato. Need setup to connect both:

  1. add on Domain for DNS properties the Server IP as A-Record [source]
  2. add on Server the Domain as DNS-Reverse [source]

Google

  1. Login to your google account, goto domain verification, add domain suadin.de
  2. proof domain ownership: select strato, create subdomain CNAME-Target, configure CNAME-Record with CNAME-Target

Hosting

Server has Operating System (OS) Ubuntu 18.04 LTS 64bit. Pre-Installs: sudo apt-get install screen, sudo apt-get install nano

Template

  1. login as root, apt update, apt upgrade, adduser $user_name, usermod -aG sudo $user_name, su $user_name, cd ~
  2. main steps on next capters
  3. exit, sudo deluser $user_name sudo, chown -hR $user_name:$user_name /home/$user_name, exit

Docker

  1. follow step 1 of guide [source]
  2. follow step 2 but with slidely different commands: sudo gpasswd -a docker docker, sudo service docker restart
  3. start docker in screen: screen -d -m bash -c "docker run -p 8080:80 docker/getting-started", check: http://suadin.de:8080

Teamspeak

  1. download/unpack/accept-license with guide [source]
  2. add into autostart: nano /etc/crontab -> add @reboot teamspeak3 /home/teamspeak3/teamspeak3-server_linux_amd64/ts3server_startscript.sh
  3. grant/start script: chmod +x ts3server_startscript.sh, sudo chown -hR teamspeak3:teamspeak3 /home/teamspeak3, ./ts3server_startscript.sh start

Minecraft

  1. follow guide to setup new world [source]
  2. overwrite files with existing world via WinSCP
  3. add into autostart: nano /etc/crontab -> add @reboot minecraft /usr/bin/screen -dmS minecraft-screen /home/minecraft/start.sh

PostgreSQL

  1. folow install guide [source]
  2. create/grant database/user: sudo -i -u postgres, psql, CREATE DATABASE suadin;, CREATE USER suadin WITH PASSWORD 'jw8s0F4';, GRANT CREATE ON DATABASE suadin TO suadin;, \q, exit, exit

pgAdmin4

  1. use root user and follow guide for install pgAdmin4, scroll a bit down [source]
  2. change apache port to have no conflict with suadin.de [source]
  3. start pgAdmin4: sudo /usr/pgadmin4/bin/setup-web.sh
  4. create subdomain https://db.suadin.de with external detour http://81.169.247.92:8080/pgadmin4

Security

SSL-Certificate

Create-Certificate

  1. follow certbot guide until step 6, use on step 7 webroot with domain suadin.de [source]
  2. stop deployment script, sudo certbot certonly --standalone with domain suadin.de
    • result: /etc/letsencrypt/live/suadin.de/fullchain.pem & /etc/letsencrypt/live/suadin.de/privkey.pem
  3. convert privkey.pem with fullchain.pem to suadin.de.pfx, choose password [source]
  4. prepare *.pfx for docker: sudo cp suadin.de.pfx /home/docker/.aspnet/https/ (create missing folder) [source]

Renew-Manual-Certificate

  1. stop website with deployment script
    su docker  
    pkill screen
    container_id=$(docker ps -aqf "name=$repo" -aqf "status=running")
    if [ ! -z "$container_id" ]; then
       docker container stop "$container_id"
    fi
  2. sudo certbot renew
  3. execute last two steps from Create-Certificate
  4. start deployment scrip
    su docker
    cd ~
    screen ./continuous-deployment.sh

Renew-Auto-Certificate

  1. follow step 9 of certobot guide [source]
  2. pre/haproxy.sh contains first scriptblock from Renew-Manual-Certificate
  3. sudo certbot renew is executed automatically between pre and post
  4. post/haproxy.sh contains
    1. execute last two steps from Create-Certificate
    2. last scriptblock from Renew-Manual-Certificate

⚠️ But never did it, therefore open task to do setup.

Website-Deployment

Continuous Integration (CI) and Continuous Delivery (CD) of website happens through GitHub and DockerHub. Pull of docker image happens with deployment script on Server.

alternative text

GitHub-Repository

GitHub account suadin contains GIT repository of website.

DockerHub-Repository

  1. connect to GitHub repository source, choose main branch and link to existing Dockerfile
  2. expect push into GitHub triggers DockerHub build run

⚠️ If you get error 'COPY failed: stat /var/lib/docker/tmp/docker-builder...': I solved it by remove repo from docker-hub and create new with same name.

⚠️ DockerHub force you to Upgrade your account if you need a connection to github: Solved that by using GitHub Actions to push images to DockerHub.

GitHub-Actions

  1. put DockerHub secrets into GitHub [source]
  2. follow guide to push docker image into DockerHub & GitHub Packages [source]
  3. do slidely changes on last step [source]
    1. add on both build & publish steps below context file: src/Server/Dockerfile
    2. replace hashed versions docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with major versions docker/build-push-action@v2

ℹ️ Change to GitHub Packages to remove DockerHub dependency

Deployment-Script

#!/bin/bash
repo="<repo-name>"
feed="<dockerhub-id>/$repo:main"
docker_params="-p 80:80 -p 443:443 -e ASPNETCORE_URLS=\"https://+443;http://+80\" -e ASPNETCORE_HTTPS_PORT=443 -e ASPNETCORE_Kestrel__Certificates__Default__Password=\"$cert_password\" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/suadin.de.pfx -v ~/.aspnet/https:/https/"
while [ true ]
do
  sleep 1
  docker container prune -f
  docker image prune -a -f
  sleep 1
  container_id=$(docker ps -aqf "name=$repo" -aqf "status=running")
  pull=$(docker pull $feed)
  if [[ $pull == *"Status: Image is up to date for $feed"* ]]; then
    if [ ! -z "$container_id" ]; then
      echo "Nothing to do..."
    else
      # duplicated code, see below. For now ok but potential improvement exists.
      echo "start container with image $feed"
      screen -d -m bash -c "docker run $docker_params --name $repo $feed"
    fi
    sleep 60
  elif [[ $pull == *"Downloaded newer image for $feed"* ]]; then
    echo "New version detected!"
    if [ ! -z "$container_id" ]; then
      echo "stop container $container_id"
      docker container stop "$container_id"
      sleep 1
      docker container prune -f
      docker image prune -a -f
      sleep 1
    fi
    echo "start container with image $feed"
    secrets="--env-file secrets.txt"
    screen -d -m bash -c "docker run $docker_params $secrets --name $repo $feed"
    sleep 60
  else
    echo "Script doesn't work like expected, please verify!"
    sleep 5
  fi
done

Comments:

  • while [ true ] & sleep 60: minutely endless loop
  • sleep 1 before/after prune necessary to avoid error messages
  • container_id=$(docker ps -aqf "name=$repo" -aqf "status=running"): take container id for potential stop and prune
  • pull=$(docker pull $feed): pull spam to detect potential changes
  • docker_params="-p 80:80 -p 443:443 ...: configure ports, specially https with certificate binding [details]
  • secrets="--env-file secrets.txt": for pass secrets into website [source]

Run:

  • Start script manually: screen ./continuous-deployment.sh
  • Start after server reboot with CRON job: nano /etc/crontab -> add @reboot docker /usr/bin/screen -dmS continuous-deployment-screen /home/docker/continuous-deployment.sh

Releases

No releases published

Packages

No packages published