The aim of this project is to introduce you to the world of system and network administration, offering you a global vision of a network architecture. You will learn how to install a complete web server, using a deployment technology like Docker. You will discover the basics of system and network administration, as well as the essential concepts of security.
🔗 Github Inception - Waltergcc 🔗 Github Inception - Forstman1
---
config:
look: handDrawn
theme: default
---
graph TD
direction TB
classDef black fill:#000,stroke:#333,stroke-width:1px;
classDef white fill:#fff,stroke:#333,stroke-width:1px;
classDef lightblue fill:#99f,stroke:#333,stroke-width:1px;
classDef lightgreen fill:#9f9,stroke:#333,stroke-width:1px;
classDef lightred fill:#f99,stroke:#333,stroke-width:1px;
classDef lightyellow fill:#ff9,stroke:#333,stroke-width:1px;
classDef lightorange fill:#f90,stroke:#333,stroke-width:1px;
classDef lightpurple fill:#f0f,stroke:#333,stroke-width:1px;
classDef lightcyan fill:#9ff,stroke:#333,stroke-width:1px;
classDef lightpink fill:#f9f,stroke:#333,stroke-width:1px;
classDef lightbrown fill:#963,stroke:#333,stroke-width:1px;
classDef lightgrey fill:#999,stroke:#333,stroke-width:1px;
classDef lightblack fill:#000,stroke:#333,stroke-width:1px;
classDef lightwhite fill:#fff,stroke:#333,stroke-width:1px;
classDef lightviolet fill:#9f9,stroke:#333,stroke-width:1px;
Makefile -->|Launch/Setup| Docker-compose[fab:fa-docker Docker Compose]
Docker-compose -->|Image| Dockerfile-Mariadb[fab:fa-docker Dockerfile Mariadb]
Docker-compose -->|Image| Dockerfile-Wordpress[fab:fa-docker Dockerfile Wordpress]
Docker-compose -->|Image| Dockerfile-Nginx[fab:fa-docker Dockerfile Nginx]
Dockerfile-Mariadb -->|Config| MariaDB[fa:fa-database MariaDB]
Dockerfile-Wordpress -->|Config| Wordpress[fab:fa-wordpress Wordpress]
Dockerfile-Nginx -->|Config| Nginx[fa:fa-globe Nginx]
%%{ init: { 'flowchart': { 'curve': 'step' } } }%%
graph TD
direction TB
classDef black fill:#000,stroke:#333,stroke-width:1px;
classDef white fill:#fff,color:#555,stroke:#333,stroke-width:1px;
classDef white_border fill:#fff,color:#000,stroke:#333,stroke-width:1px, stroke-dasharray: 5, 5;
classDef green fill:#0f0,color:#555,stroke:#333,stroke-width:1px;
classDef lightblue fill:#99f,color:#fff,stroke:#333,stroke-width:1px;
classDef lightgreen fill:#9f9,color:#555,stroke:#333,stroke-width:1px;
classDef lightred fill:#f99,color:#555,stroke:#333,stroke-width:1px;
classDef lightyellow fill:#ff9,color:#555,stroke:#333,stroke-width:1px;
classDef lightorange fill:#f90,color:#555,stroke:#333,stroke-width:1px;
classDef lightpurple fill:#f0f,color:#555,stroke:#333,stroke-width:1px;
classDef lightcyan fill:#9ff,color:#555,stroke:#333,stroke-width:1px;
classDef lightpink fill:#f9f,color:#555,stroke:#333,stroke-width:1px;
classDef lightbrown fill:#963,color:#555,stroke:#333,stroke-width:1px;
classDef lightgrey fill:#999,color:#555,stroke:#333,stroke-width:1px;
classDef lightblack fill:#000,stroke:#333,stroke-width:1px;
classDef lightwhite fill:#fff,color:#555,stroke:#333,stroke-width:1px;
Project:::white_border
subgraph Project
direction LR
WorldWideWeb <-->|"`*443*`"| Nginx
WorldWideWeb((fa:fa-globe World Wide<br>Web)):::lightgreen
subgraph Computer_Host["fas:fa-computer Computer Host"]
direction TB
Docker_Network:::lightblue
subgraph Docker_Network["fas:fa-network-wired Docker Network"]
direction LR
MariaDB("fa:fa-database MariaDB<br>Container")
Wordpress("fab:fa-wordpress Wordpress + PHP<br>Container")
Nginx("fa:fa-server Nginx + TLS<br>Container")
MariaDB <-->|"`*3306*`"| Wordpress <-->|"`*9000*`"| Nginx
end
Volume_MariaDB[("fas:fa-hdd MariaDB<br>Volume<br><br>/home/login/data/...")]:::lightorange
Volume_Wordpress[("fas:fa-hdd Wordpress<br>Volume<br><br>/home/login/data/...")]:::lightorange
MariaDB <-.-> Volume_MariaDB
Wordpress <-.-> Volume_Wordpress
Nginx <-.-> Volume_Wordpress
end
end
linkStyle 0 stroke:lightgreen,stroke-width:2px;
linkStyle 1,2 stroke:lightcyan,stroke-width:2px;
It is important to never commit your credentials to a repository. To avoid this, you can use a .gitignore
file to ignore the files containing your credentials.
echo "!secrets/*.template" >> .gitignore
echo "secrets" >> .gitignore
git add .gitignore
git commit -m "Ignore secrets files but keep them in the repository as template"
git push
Using the update-index command:
This command will ignore the changes made to the files in the secrets
folder but keep them in the repository, this works only locally.
git update-index --skip-worktree secrets/*
🔗 Env details and good practices
Same goes for the .env
file, which is used to store environment variables.
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Ignore .env file"
git push
The hosts file is a computer file used by an operating system to map hostnames to IP addresses. The hosts file is a plain text file and is conventionally named hosts
. It acts as a local DNS service, resolving hostnames to IP addresses.
In Unix-like operating systems, the hosts file is located at /etc/hosts
.
sudo nano /etc/hosts
Notes: This file can be used to block or redirect websites. It is an attack vector for malware.
---
config:
flowchart: { curve: 'basis' }
theme: default
htmlLabels: true
---
graph TD
direction TB
classDef black fill:#000,stroke:#333,stroke-width:1px;
classDef white fill:#fff,color:#555,stroke:#333,stroke-width:1px;
classDef white_border fill:#fff,color:#000,stroke:#333,stroke-width:1px, stroke-dasharray: 5, 5;
classDef green fill:#0f0,color:#555,stroke:#333,stroke-width:1px;
classDef lightblue fill:#99f,color:#fff,stroke:#333,stroke-width:1px;
classDef lightgreen fill:#9f9,color:#555,stroke:#333,stroke-width:1px;
classDef lightred fill:#f99,color:#555,stroke:#333,stroke-width:1px;
classDef lightyellow fill:#ff9,color:#555,stroke:#333,stroke-width:1px;
classDef lightorange fill:#f90,color:#555,stroke:#333,stroke-width:1px;
classDef lightpurple fill:#f0f,color:#555,stroke:#333,stroke-width:1px;
classDef lightcyan fill:#9ff,color:#555,stroke:#333,stroke-width:1px;
classDef lightpink fill:#f9f,color:#555,stroke:#333,stroke-width:1px;
classDef lightbrown fill:#963,color:#555,stroke:#333,stroke-width:1px;
classDef lightgrey fill:#999,color:#555,stroke:#333,stroke-width:1px;
classDef lightblack fill:#000,stroke:#333,stroke-width:1px;
classDef lightwhite fill:#fff,color:#555,stroke:#333,stroke-width:1px;
Project:::white_border
subgraph Project
direction TB
WorldWideWeb <-->|"`*443*`"| Nginx
WorldWideWeb((fa:fa-globe World Wide<br>Web)):::lightgreen
WorldWideWeb <-->|"`*7500*`"| Static_Website
WorldWideWeb <-->|"`*20-21*
60000-60010`"| FTP_Server
WorldWideWeb <-->|"`*7000*`"| Adminer
WorldWideWeb <-->|"`*3000*`"| Grafana
subgraph Computer_Host["fas:fa-computer Computer Host"]
Docker_Network:::lightblue
subgraph Docker_Network["fas:fa-network-wired Docker Network"]
subgraph Wordpress_Stack
MariaDB("fa:fa-database MariaDB<br>Container")
Wordpress("fab:fa-wordpress Wordpress + PHP<br>Container")
Nginx("fa:fa-server Nginx + TLS<br>Container")
MariaDB <-->|"`*3306*`"| Wordpress <-->|"`*9000*`"| Nginx
end
Static_Website("fab:fa-js Static Website<br>NodeJS + Express<br>Container")
FTP_Server("fa:fa-server FTP Server<br>ProFTPd<br>Container")
Adminer("fa:fa-database Adminer<br>Container")
Adminer <-->|"`*3306*`"| MariaDB
Redis("fa:fa-database Redis<br>Container")
Wordpress <-->|"`*6379*`"| Redis
Grafana("fa:fa-chart-line Grafana<br>Container")
Grafana <-->|"`*3306*`"| MariaDB
end
Volume_MariaDB[("fas:fa-hdd MariaDB<br>Volume<br><br>/home/login/data/...")]:::lightorange
Volume_Wordpress[("fas:fa-hdd Wordpress<br>Volume<br><br>/home/login/data/...")]:::lightorange
Volume_Grafana[("fas:fa-hdd Grafana<br>Volume<br><br>/home/login/data/...")]:::lightorange
MariaDB <-.-> Volume_MariaDB
FTP_Server <-.-> Volume_Wordpress
Wordpress <-.-> Volume_Wordpress
Nginx <-.-> Volume_Wordpress
Grafana <-.-> Volume_Grafana
end
end
linkStyle 0,1,2,3,4 stroke:lightgreen,stroke-width:4px;
linkStyle 5,6,7,8,9 stroke:lightblue,stroke-width:2px;
🔗 Docker - NodeJS container 🔗 Tips for NodeJS with Docker
You can also host a static website with Node.js and Express.
npm init
# run the command and answer the questions
npm install express
Create a server.js
file:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.static('public'));
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
Create a public
folder with an index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Run the server:
node server.js
# or
# npm start
Design your website in the public
folder.
- Dashboard when container run : https://localhost:7500
FTP (File Transfer Protocol) is a standard network protocol used to transfer files from one host to another host over a TCP-based network, such as the Internet.
A very popular and maintainded FTP server is ProFTPd.
🗃️ Github ProFTPd - Official Repo
🔗 Adminer Setup Docker (with docker image) 🔗 Adminer in Debian
Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB.
Adminer is a single php file that can be run in a container with php and php-mysql.
Cool theme : Hydra
-
To add custom css just put the css file in the same directory as the
adminer.php
file. -
Dashboard when container run : https://localhost:7000
- Configuration file :
/etc/redis/redis.conf
- Config Redis as Cash
- Wordpress Redis Cache - Installation - step made simpler using wp-cli (installing the plugin and configuring it)
Redis is a pseudo open-source, in-memory data structure store, used as a database, cache, and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries, and streams.
🔗 Grafana in Debian 🔗 Grafana Setup Docker
- Configuration file :
/etc/grafana/grafana.ini
- Provisioning
- Datasources MySQL
Grafana is a multi-platform open-source analytics and interactive visualization web application. It provides charts, graphs, and alerts for the web when connected to supported data sources.
Grafana is a single binary that can be run in a container.
- Dashboard when container run : https://localhost:3000
Log for all containers:
@docker compose -f <compose_file_path> logs -f
Go inside a container:
docker exec -it <container> bash
# or
# docker exec -it <container> <command>
/var/log/nginx/error.log
/var/log/nginx/access.log
/var/lib/mysql/error.log
/var/log/php7.4-fpm.log
Socket error:
- Can't connect to local MySQL server through socket
/var/run/mysqld/mysqld.sock
service mysql status cat /etc/mysql/my.cnf | grep socket cat /etc/mysql/mariadb.conf.d/50-server.cnf | grep socket cat /var/run/mysqld/mysqld.sock
- Can't connect to php-fpm through socket
/var/run/php/php7.4-fpm.sock
from Nginx# in Nginx ## Check connection to the socket curl -I -v wordpress:9000 ## Check connection to another socket curl -I -v mariadb:3306 # in Wordpress # Check the socket in the php-fpm pool configuration is listening on the right socket or port (9000) cat /etc/php/7.4/fpm/pool.d/www.conf | grep listen
Portainer is a lightweight management UI which allows you to easily manage your Docker host or Swarm cluster.
Portainer hides the complexity of managing containers behind an easy-to-use UI. By removing the need to use the CLI, write YAML or understand manifests, Portainer makes deploying apps and troubleshooting problems so easy that anyone can do it.
Portainer consists of two elements: the Portainer Server and the Portainer Agent. Both run as lightweight containers on your existing containerized infrastructure. The Portainer Agent should be deployed to each node in your cluster and configured to report back to the Portainer Server container.
A single Portainer Server will accept connections from any number of Portainer Agents, providing the ability to manage multiple clusters from one centralized interface. To do this, the Portainer Server container requires data persistence. The Portainer Agents are stateless, with data being shipped back to the Portainer Server container.