- About
- Before you start: Suggestions
- Getting Started
- Commands Cheat-Sheet
- Straight to the point
- Nginx
- MariaDB
- Wordpress
- Resources
Inception is a project about Docker containers, this will help expand knowledge about system administration and some Web development skills as well.
This project can also be understood under the name of LEMP Stack Deployment
learn more
which simply stands for Linux, NGINX (pronounced Engine X), MySQL, and PHP-FPM.
This project carries a lot of diverse topics, and with them A LOT of documentation, for that reason I created this guide, to have the Resources necessary for you to get some information about each topic and hopefully save some hours and avoid falling down the rabbit hole of material that one can find online.
For the order of the project I want to suggest some points that helped me to not get lost, learn comfortably and move forward quicker.
(this are tips that help me but are not necessary to follow, so feel free to find what its best for you, _this is not a copy-paste guide so you will still have to figure some things out โ๐ผ)
1. Use a SSH connection between your VM and your work station learn how
(specially if you are working at 42 campus with limited ram on your VM), For this my choice was to use the extension for Visual Studio code called Remote - SSH
[ Download it here ]
DISCLAIMER!
When using this extension the ssh connection over VS code will not have root permission to write and save files on your VM machine, so for this we can do 2 things, either install the extension for saving files over the remote desktop as root called "Save as Root" or we follow a process to link a public key to our VM machine.
The extension is called "Save to root" and you can download it here https://marketplace.visualstudio.com/items?itemName=yy0931.save-as-root)
This is more work but less to worry afterwards, so do the following:
MAC
- virtualBox Settings -> Network -> Adapter1 : Bridged Adapter + Allow All VM
- Sudo systemctl status ssh = should be โactive(running)โ
MAC
- cd ~/.ssh
- ssh-keygen -t rsa = generates new key (call it โvm_keyโ, when prompted) and leave empty the other fields
- ssh-copy-id -i vm_key.pub username@ipaddress
VM
- Sudo nano /etc/ssh/sshd_config
- Uncomment the line โPubkeyAuthentication yesโ
- Sudo nano /etc/ssh/ssh_config
- Add following 2 lines to the end:
Host *
IdentityFile ~/.ssh/vm_key
MAC
- In VS Code, click on Remote ssh extension
- add a new remote connection using the following SSH Connection command
ssh -i ~/.ssh/vm_key username@ipaddress - On the settings of your ssh connection the file should look something like this:
e.g.:
Host 10.29.247.138 HostName 10.29.247.138
Port 22
User rofl
IdentityFile ~/.ssh/vm_key
This will make it easier to work on the project if you like, for example, opening multiple files while also navigating through the folder structure of your machine.
It will be easier to handle errors and to give order to the topics you will learn, the logic I followed was:
- [Nginx]
Learn first how to launch a docker image && to execute this image without
using docker-compose.
Learn How to display an html page on http://localhost:80"
Learn how to display an html page with SSL on http://localhost:443"
- [MariaDB]
learn to create a database via command line
learn to show databases
learn to access databases remotely
You can begin from here the docker-compose file, you don't need it before
- [WordPress+PHP]
learn to use WP CLI and use it to create users
learn how to use the Wordpress dashboard
- [Bonus](from easy to hard IMO)
FTP Server
Redis cache for Wordpress
Static Webpage
Own Service
Adminer
there are many and very different ways to approach the tasks of the project, it all comes down to how each person learned to write in bash
and on which OS they run their VM on, this will determine which commands differ from their syntax even if they do the same. (sounds basic, but many people with few experience in deep UNIX language might struggle with this).
Reading other peoples solution gives perspective on what THIS PROJECT really needs and what to skip.
In short, if you don't know how to do something, see what others do, try to understand it and then write your approach.
(AKA the super alternative learning method)
Weird suggestion I know, but it has proven me to work to a certain extent with other projects. In this case I suggest you to do this ONLY if you feel like understanding and reinforcing on what you just did.
No need to write all files from the beginning, I mean, you already did right?, so its a matter of straight checking boxes and using the material you already created
For Speed-run examples of what this project needs (but using the docker hub ) check this:
Tis is a no-brainer, but still remember to do it, just install git
on your VM and push your work after each session, if for any reason your VM dies, your whole work will be safe on git. โ๐ผ
The first step for this project is obviously to get your hands on a virtual machine
with any Linux distribution, my choise was to work on the last version of UBUBTU . In this machine you will need to install Docker && Docker-compose
and setup the according sudo permissions
necessary for your user to work.
> sudo apt-get update # update the system
> sudo apt-get upgrade # upgrade to current version
> sudo apt-get install openssh-server # install ssh service
> sudo systemctl enable ssh # enable ssh service
> sudo systemctl status ssh # check if its running
> sudo apt-get install -y ufw # install firewall
> sudo ufw allow ssh # install allow ssh connection via port 22/tcp
> sudo ufw enable # enable firewall
> sudo ufw status # check status
> ssh username@IP_address # connect to your VM ip address via ssh
> sudo apt-get install docker # install Docker
> sudo apt-get install -y docker-compose # install Docker-compose
> su # Switch to root user
> sudo usermod -aG sudo user_name # Add user to sudo group
> sudo usermod -aG docker user_name # add user to docker group
This project is mainly about learning to use Docker and Docker-compose so its good to start getting familiar with what it is and the common commands to use it. \
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package.Learn more
In order to build our containers, each will need a set of instructions that can install the corresponding dependencies for each Service to run and this instructions are written in a file called Dockerfile
DOCKERFILE'S MAIN SYNTAX:
FROM # Instruction used to specify the valid docker image name.
# So specified Docker Image will be downloaded from the
# docker hub registry if it is not exists locally.
RUN # This runs a Linux command. Used to install packages into
# container, create folders, etc.
COPY # Instruction is used to copy files, directories and remote URL files
# to the destination within the filesystem of the Docker Images.
ADD #This command works like a mix of RUN and COPY.
# A valid use case for ADD is when you want to extract a local tar file
# into a specific directory in your Docker image.
EXPOSE # Instruction is used to inform about the network ports that the container
# listens on runtime. Docker uses this information to interconnect containers
# using links and to set up port redirection on docker host system.
CMD # Allows you to set a default command which will be executed only when
# you run a container without specifying a command.
ENV # Set Environment variables permanently on the container
Docker Compose is a Docker tool used to define and run multi-container applications. With Compose, you use a YAML file to configure your applicationโs services and create all the appโs services from that configuration.
Think of Docker-compose as the "Cook" that uses "Recipes"(our Docker Files) to create "Dishes"(our Containers)
# We start with the version of our docker compose
version: '3.5'
# create a Network to conect your services
networks:
my_network:
# we declaire the services we will build
services:
my_service:
# We give the Path to our dockerfile.
# '.' represents the current directory in which
# docker-compose.yml is present.
build: .
# image to fetch from docker hub
#if built locally image will just give a name to your image
image: image_name:version
# Mapping of container port to host
ports:
- "5000:5000"
# create a dependancy on another container for the containers to
# have an order of creation
depends_on:
- other_container
# Mount volume (the path to a local machine folder)
# where changes to our containers will be saved
volumes:
- "user_custome_vol_name:/path_for_files"
# Import a file with Environment variables
# containers will use these variables
# to start the container with these define variables.
env_file: .env
#connect to your network
networks:
- my_network
# Set the arguments that will be used as variables in the container
# this will look into the .env file
args:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MY_SQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
# Restart the containers if needed
restart: unless-stopped
It will be IMPORTANT that you start getting familiar with Docker and with the syntax of Docker Files and of Docker-compose. this two files are basically the ```Core``` of your project.
Alright! lets do this! ๐ช๐ผ
-
What you need to know about NginX:
Nginx is an open-source software, functioning initially as a web server, but itโs also used as a reverse proxy, HTTP cache, or a load balancer.
Nginx is a web server which stores html, js, images files and use http request to display a website. The default configuration file of Nginx is nginx.conf and Nginx conf documents will be used to config our server and the right proxy connexion. -
Installation:
The following commands will get the Nginx server running and it can be tested by opening a browser and typinglocalhost
> sudo apt update
> sudo apt -y install nginx
> sudo systemctl enable nginx #Enables Nginx to automatically start at boot time.
Installing Nginx in a container makes use of most of this commands but needs a personalized configuration via config files. but if you simply want to test that it works outside a container then use the following commands"
> sudo apt install ufw
> sudo sudo ufw allow 'Nginx HTTP'
- Nginx Docker-file
Be sure to run nginx in debug mode (foreground) and not as a daemon, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
CMD ["nginx", "-g" "daemon_off"
in the CMD in order for nginx to stay run in debug mode (foreground) and not as a daemon, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
- **:
If these commands ask for sudo, simply add the user to the sudo and docker group
> #DOCKER / COMPOSE
> docker-compose up # runs the docker-compose file (builds all)
> docker-compose down # Stops all containers and deletes them
> docker built . -t name_of_image # builds the docker image
> docker images # Shows images built
> docker ps # Shows containers running
> docker rm -f $(docker ps -qa) # Delete All Containers
> docker rmi -f $(docker images -qa) # Delete All Images
> docker stop `docker ps -qa` # Stop all Containers
> docker volume rm `docker volume ls -q` #Delete All Volumes
> docker logs container_name # Debug Log of a container
> docker exec -it container_name bash # Open shell of a container
> #NGINX
> cat /etc/nginx/nginx.conf # this is the original config file of nginx
> systemctl status nginx # checks if nginx server is up and running
> service nginx start # starts the server
> service nginx stop # stops the server
> docker run -p 443:443 imageName # To run and test without docker compose
> systemctl status ufw # check if the firewall is up and active
- SSL CERTIFICATE
We can create a self-signed key and certificate pair with OpenSSL in a single command:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
- TLS: configure TLS 1.2 and 1.3:
TLS
stands for Transport Layer Security
is a protocol for securing communication between the client
and the Server
In order to set the TLS version we have to add ssl_protocols TLSv1.2;
into our nginx.conf
-
What you need to know about MariaDB:
MariaDB will be the database to store information about our Wordpress users and settings.
In this section we have to create the Mariadb image and create 2 users. -
Installation:
> sudo apt-get update # Run updates
> sudo apt-get install mariadb-server # install Data base Service
> sudo apt-get install mariadb-client # install Data base Service
> sudo mysql_secure_installation # Ensure secure connection to data base
What are the steps to create your MariaDB Container:
- Download mariadb-client and mariadb-server
- Expose port 3306
- Remove the original config file from mariadb and replace it with your own
- Set the ARG values to your database Environment Variables
- Copy the script you made on the container and run it
- Stop the mysql service
- Run the command mysql_safe
- Use the
mysql -u root -e
to run the database as root user and execute commands to create the data base (name, user, password, grant privileges ) Learn how
- Login into your container's shell and run the service mariadb using the user root and the password, then check for the existing databases and users
> docker exec -it mariadb
> mariadb -u root -p your_pass
> SHOW DATABASES;
> SELECT User, Db, Host from mysql.db;
- What you need to know about Wordpress :
WordPress is an open-source content management system (CMS). Itโs a popular tool for individuals without any coding experience who want to build websites and blogs.
What are the steps to create your Wordpress Container
- Download php-fpm
- Copy your own www.conf file into php/7.3/fpm/pool.d/
- Download Wordpress-CLI
- Move files from Wordpress in the
/var/www/
directory (either/html
or your own) - Create the php directory to enable php-fpm to run
- Copy the script and launch it
- Make the working directory the one of your WP files
- Give the 4 environmental variables for Wordpress
- Use WP-CLI commands to create admin user and database names
- create another user who is not an admin using WP-CLI command
- Launch php-fpm
- Create a www.conf file
You need to edit www.conf and place it in
/etc/php/7.3/fpm/pool.d
andwp-content.php
to disable (7.3 is the usual version of php on a 42 VM) access to the Wordpress installation page when you access your site at https://login.42.fr - Put listen = 0.0.0.0:9000 to listen to all ports
- Increase the number for the pm values in order to avoid a 502 page
Installation:
> sudo apt update && sudo apt install \ # Run updates and install php + extensions
php-cli \
php-fpm \
php-json \
php-pdo \
php-mysql \
php-zip \
php-gd \
php-mbstring \
php-curl \
php-xml \
php-pear \
php-bcmath \
curl
Feeling perky? not enough with 3 Containers? How about 2 more?
- What you need to know about FTP SERVERS :
An FTP Server, in the simplest of definitions, is a software application that enables the transfer of files from one computer to another. FTP (which stands for โFile Transfer Protocolโ) is a way to transfer files to any computer in the world that is connected to the Internet. For Wordpress it allows to modify easily your files like the Wordpress files or your code.
- Installation:
> sudo apt-get update # Run updates
> sudo apt-get install -y vsftpd # install Data base Service
- Config file:
After installing the vsftpd
service, you can find the default configuration file at the /etc/vsftpd/vsftpd.conf
directory.
The variables that are set are sufficient for the ftp to work, but since you have to use the Wordpress directory, you will have to change the attribute local_root
to your Wordpress directory. Any additional variable for our specific purpose of the Inception Project eludes my awareness, so experiment and check for referents of configurations โ๐ผ.
- Wordpress Config file:
There are multiple ways to check if your server works:
- Check inside your container that the service is active
#If you want to test your container log int your containers shell using this command
> docker exec -it containername bash
# Now check if the service ftp is up and running
> service vsftpd status
# You should get the following
# [ ok ] FTP server is running.
-
Use the application FILEZILLA (download it fro Manage Software Center) on your MAC or VM to test and visualize your file system
-
Use the FTP address in any browser by typing the following:
ftp://your_VM_ip_address
and follow the POP-UP message that will open a folder with the folder you created for your FTP server. -
Connect via terminal:
# use the command ftp followed by username and localhost and the ftp port
> ftp username@localhost 21
> redis-cli -h localhost -p 6379 ping
GENERAL KNOWLEDGE
VS code Extension for remote SSH connection
DOCKER
Learn about Docker
- https://yannmjl.medium.com/what-is-docker-in-simple-english-a24e8136b90b
- https://www.youtube.com/watch?v=eGz9DS-aIeY Learn how to make a Docker-compose file
- https://www.youtube.com/watch?v=DM65_JyGxCo
Learn about Dockerfile
commands and Syntax
Using variables in Docker compose
- https://betterprogramming.pub/using-variables-in-docker-compose-265a604c2006
- https://www.educative.io/blog/docker-compose-tutorial
- https://vsupalov.com/docker-env-vars/
Some more Docker knowledge
NGINX
Beginners guide:
Certificates:
Use TSL V1.3 ONLY:
How to configure php on Nginx :
- https://www.dreamhost.com/blog/guide-to-wp-cli/#:~:text=The%20WP%2DCLI%20is%20a,faster%20using%20the%20WP%2DCLI.
- https://www.digitalocean.com/community/tutorials/understanding-and-implementing-fastcgi-proxying-in-nginx
MariaDB
Create a Database via CLI
Connect to mariadb:
WORDPRESS
What is Wordpress:
How to install it :
How to install it in a docker Container:
How to use the WP-CLI (Command line):
-https://make.wordpress.org/cli/handbook/guides/installing/
BONUS STUFF
REDIS