ft_server tutorial — 42 project

ft_server is a project by 42 school which introduces to docker containers and system administration.

This tutorial includes:
for a complete project have a look here.

Docker is the famous 🐳 whale container.
A container is a all-packed-in-one system than can run on your machine while being entirely independent from it.
You can have python2 installed on your machine, and python3 installed in a container; you can have a machine that runs on ubuntu, and a container that runs on arch. And it’s all perfectly fine.

Containers allow us to create tailor-made environment for our applications without interfering with the machine environment.

For this project, we are asked to use a folder srcs and a Dockerfile:

├── Dockerfile
└── srcs/

The dockerfile is like a makefile.
We could draw a simple comparison.

Dockerfile                  | Makefile
docker build . | make
image_id | a.out
docker run image_id | ./a.out

The dockerfile is then a set of instructions that builds up an environment with exactly what you need for your program to run, including specific library version, for example.

A few simple preliminary rules:
- Don’t use sudo statements in your dockerfile
- Don’t use . to indicate the current working directory, use ./ instead
- To chain lines use \
- A dockerfile has one and only one CMD statement
- Use COPY to move files from outside the container into the container
- Use RUN to run bash scripts inside the container

Now, the subject ft_server wants us to build a container with
- a debian buster OS
- nginx server
- mySQL database
- phpmyadmin service
- wordpress service

Docker works from images.
To get the image of debian buster, we’ll start off writing our dockerfile in the following way:

FROM debian:buster

The : format indicates the version (or tag) of the image you need.
Now we can proceed — our Dockerfile will be divided into:
- part1, installations
- part2, configuration
- part3, permissions (grant rights to user)


For more about installations, check out this link.

RUN apt-get -y update                       
RUN apt-get -y install nginx \
mariadb-server \
php-fpm php-mysql \
wget dialog apt-utils \
php php-cgi php-mysqli php-pear php-mbstring php-gettext php-common php-phpseclib php-mysql


Set the working directory for your server.

WORKDIR /var/www/localhost

Make sure you have you config files saved in the srcs folder.
Let’ start with nginx.

COPY srcs/nginx.config /etc/nginx/sites-available/                       RUN ln -s /etc/nginx/sites-available/nginx.config /etc/nginx/sites-enabled/

We COPY the config from srcs into the container, in a folder of our choice.
Then we RUN a command, in this case we create a symbolic link from sites-available to sites-enabled.

We need to do this for all config files in the right folder, for all the services we have.

This is for phpmyadmin and wordpress.
[important] : find all the config and setup files at this gal’s medium part 1 and part 2.

I’ll let you work out the setup for phpnymadmin and wordpress.
When you’re done don’t forget to COPY.

COPY ./srcs/config.inc.php /var/www/myserver/phpmyadmin/                       COPY ./srcs/wp-config.php /var/www/myserver/wordpress/


We need now to grant permission to the user or we won’t have access to the folders’ content.

RUN chown -R www-data:www-data ../**/**                       
RUN chown -R 755 /var/www/myserver
RUN chmod -R 755 /var/www/*

and add the ssl certificate, fo C and ST you can of course switch to your country code and state.

RUN openssl req -x509 -nodes -days 365 -subj "/C=BE/ST=Belgium/L=your_city/O=your_building/OU=your_office/CN=your_name" -newkey rsa:2048 -keyout /etc/ssl/nginx-selfsigned.key -out /etc/ssl/nginx-selfsigned.crt;


A dockerfile should have only one CMD line, which is also the entry point of the container.

COPY ./srcs/init.sh ./                       
CMD /bin/bash ./init.sh
EXPOSE 80 443

The expose line doesn’t really do anything.
It only let people know on which ports you have configured your server — in our case, 80 for http and 443 for https.

So, what’s inside the init.sh?

service nginx start                       
service mysql start
service php7.3-fpm start

echo "CREATE DATABASE wordpress;"| mysql -u root --skip-password echo "GRANT ALL PRIVILEGES ON wordpress.* TO 'root'@'localhost' WITH GRANT OPTION;"| mysql -u root --skip-password echo "FLUSH PRIVILEGES;"| mysql -u root --skip-password echo "update mysql.user set plugin='' where user='root';"| mysql -u root --skip-password
#sleep infinity & wait # option 1
bash # option 2

We start nginx, mysql, php.
We setup our mysql database (we create a user and a password — in our case, we opted for no password at all).
Now at the very bottom we have two ways of running our container.
Let’s see how they differ.

When our dockerfile is ready, we have to build our container with docker build . and it will produce an image; you can also specify the name of your image if you want to, with docker build -t a_name .

Once it’s built, you’ll see on your terminal:

Removing intermediate container c46df72a253f
---> aa89aa05b6d1
Successfully built aa89aa05b6d1 # of course the id will be different

The last code we got is our image id that we need to run.
We can now run the container with docker run -p 80:80 -p 443:443 image_id(don’t forget to always specify the -p port number).
But there is more, remember the two options?

With option 1 sleep infinity & wait :

We can run our container with a simple docker run.
Our docker container will continue run even after all processes have been run, literally forever. To exit it, open a new terminal tab and:

docker ps -a # to find the name of the running container
docker container stop container_name

With option 2 bash :
we will have to run the container with the -it flag, docker run -it -p 80:80 -p 443:443 image_id . -it stands for interactive.
After running, you will land into the container bash terminal.
There you will be able to use all the shell commands, like ls, and navigate into your container.
To exit, type exit or press ctrl+d.


autoindex is what allows nginx to automatically find our website index.html page when we get on localhost. In nginx config you see a line that goes autoindex: on . That’s the default — if you turn it off, localhost will throw an error, usually 403 Forbidden, and the page will be inaccessible.

You’ll need this script (don’t forget to COPY it):

sed -i “s/autoindex on;/autoindex off;/g” /etc/nginx/sites-available/nginx.config 
service nginx restart

Now, how to run it?
If you are running your container with the -it flag, you’ll just need to do bash myscript.sh in your container bash.
If you don’t use -it, while your container is running, you’ll have to open a new terminal tab and run:

docker run exec <container_name> bash /myscript.sh

Gals and guys, happy coding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store