Docker & Docker Compose, Bugs & Fixes.
Table of contents
- First Step
- Let's Go
- Docker vs Docker Compose
- Docker Error: HTTP 408 response body: invalid character '<' looking for beginning of value
- Docker Error: You have reached your pull rate limit.
- Starting Docker Compose
- Stopping the Docker Composer Services
- Running Commands in the Docker Container's Shell
- PHP-fpm
- SSL & Certbot
- Little Facts
- Read More
In the name of God
I was trying to bring a website on my server from a simple web host. This article is just a resource gathering of opening and reading about 150 browser tabs. I feel I'd need to read this sooner or later again. Hope it's useful.
I am trying to bring a website on my Ubuntu 22.04 server. These are the required stuff:
- Nginx + SSL for the domain
- PHP + Composer
- MariaDB (or MySQL) + PHPMyAdmin
I felt I have to learn Docker at some point so I started here. And I wanted to make my server a little more secure.
First Step
This isn't a step by step guide. Your first step would be to read about all the By DigitalOcean and A Guide Collection by Igor Fomin at Hackernoon links at the Read More section at the bottom of this article. Then, many of your questions would be answered here.
Let's Go
Docker vs Docker Compose
Docker is an open platform for developing, shipping, and running applications.
docker
manages single containers.docker compose
manages multiple container applications.
Usage of docker compose
requires 3 steps:
- Define the app environment with a Dockerfile
- Define the app services in docker-compose.yml
- Run
docker compose up
to start and run app
(Source: stackoverflow.com/a/50577830/11041841)
Docker Error: HTTP 408 response body: invalid character '<' looking for beginning of value
After installing Docker, I tried docker pull hello-world
to test it, but got the error:
Error response from daemon: error parsing HTTP 408 response body: invalid character '<' looking for beginning of value: "<html><body><h1>408 Request Time-out</h1>\nYour browser didn't send a complete request in time.\n</body></html>\n\n"
The solution (thanks to this StackOverflow answer) was to adjust the MTU.
# sudo ip link set dev [interface] mtu [size]
sudo ip link set dev eth0 mtu 1400
# In another case:
sudo ip enp1s0 mtu 1000 up
You can get your device info to choose the [interface]
using:
sudo ip a
Docker Error: You have reached your pull rate limit.
Another error I encountered was this. This could have had 2 reasons:
- I wasn't logged in to Docker in the CLI.
- US Sanctions on Iran.
I live in Iran 🇮🇷. The heavy weight of the US sanctions are inhuman and annoying.
Login to Docker CLI
First try to [signup at docker.com and] login to the Docker CLI (preferably with a token instead of password for better security) using (Source):
docker login
Using DNS Servers
- Find a DNS service.
- Set the DNS on your Ubuntu.
- Login to Docker CLI and try again.
How to Set DNS on Ubuntu
First read askubuntu.com/a/1407182/1636166. if it didn't work, use the following method.
You need to configure the /etc/network/interfaces
file if you want to change your DNS server via the command line.
It should look something like this:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
# iface eth0 inet dhcp
# address 192.168.X.X
# netmask 255.255.255.0
# gateway 192.168.X.X
dns-nameservers X.X.X.X
If you have more than one DNS server, just add a space between each:
dns-nameservers X.X.X.X Y.Y.Y.Y Z.Z.Z.Z
Just replace the Xs, Ys, and Zs with your own IPs of the DNS servers of choice, and when this is done, you can run this command to update the settings (ifconfig
, ifdown
, ifup
are deprecated):
sudo ip link set eth0 down && sudo ip link set eth0 up
# Deprecated version
sudo ifdown eth0 && sudo ifup eth0
Make sure to use these commands in a single line with &&
to avoid getting stuck out if you're using your system over a network or SSH.
(Source: askubuntu.com/a/346845/1636166 & unix.stackexchange.com/a/50614/554870 & unix.stackexchange.com/a/534879/554870)
From some Docker version on, the Docker Compose command has changed from
docker-compose
todocker compose
, removing the dash.
Starting Docker Compose
There are different commands for this (start, up, run, ...).
In the CLI, go to the folder containing your docker-compose.yml
file, then run this to build and run it:
# Start and restart all the services defined in `docker-compose.yml`
docker compose up
# Start and restart all the services defined in `docker-compose.yml` **detached** from the CLI
docker compose up -d
# Only to restart containers that were previously created, but were stopped. It never creates new containers.
docker compose start
# Running `one-off` or `adhoc` tasks.
docker compose run
# If you have new changes on your images or Dockerfiles use (probably after `down` command), to start them again, run:
# To still use image cache
docker compose up --build
# Another version of it (Don't know the difference)
docker compose up --build --force-recreate
# To never use cache
docker compose build --no-cache
The -d
option is to start the services detached from the CLI. but If you're running it for the first time, not using this options makes debugging easier, as it shows to logs. If so, you can use Ctrl+C
to stop the services.
Together with --force-recreate
, you might want to consider using the flag -V
too:
-V, --renew-anon-volumes Recreate anonymous volumes instead of retrieving data from the previous containers.
Stopping the Docker Composer Services
There are different commands for this (pause, stop, down).
down
& stop
By current official documentation, down
stops and removes containers, networks, volumes, and images created by up, if they are already stopped or partially removed and so on, then it will do the trick too.
Docker Compose down
command stops all services associated with a Docker Compose configuration. Unlike stop
, it also removes any containers and internal networks associated with the services. But NOT internally specified volumes. To do that as well, you need to additionally specify the -v
flag after the down command. (Source)
# Stop services only, but don't remove them
docker compose stop
# Stop and remove containers, networks (optionally images and volumes as well)
docker compose down
# Down and remove volumes (or `-v`)
docker compose down --volumes
# Down and remove images
docker compose down --rmi <all|local>
# Delete all containers
`docker rm -f $(docker ps -a -q)`
# Delete all volumes
`docker volume rm $(docker volume ls -q)`
(Source: stackoverflow.com/q/32612650/11041841 & stackoverflow.com/a/61930747/11041841 & linuxhint.com/how-to-clean-up-docker-compos..)
Another method of resetting is (suggested by this StackOverflow answer):
docker compose rm -f
docker compose pull
# docker compose up --build -d
# docker compose stop -t 1
And another one (not tested, suggested by this StackOverflow answer):
docker stop $(docker ps -qa)
docker system prune -af --volumes
Running Commands in the Docker Container's Shell
docker attach
will let you connect to your Docker container, but this isn't really the same thing as ssh. If your container is running a webserver, for example, docker attach
will probably connect you to the stdout of the web server process. It won't necessarily give you a shell.
To run arbitrary commands inside an existing container (Source):
docker exec -it <container_id> bash
Of course, whatever command you are running must exist in the container filesystem.
In the above command <container_id>
is the name or ID of the target container. It doesn't matter whether or not you're using docker compose
; just run docker ps
and use either the ID (a hexadecimal string displayed in the first column) or the name (displayed in the final column).
docker exec
only works on running containers (otherwise use docker run -it --entrypoint /bin/bash
or similar).
-it
means:
-i
,--interactive
: Keep STDIN open even if not attached.-t
,--tty
: Allocate a pseudo-TTY.
PHP-fpm
When setting up PHP in my nginx config, I was using the following config, as I normally would without docker:
# Pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
But it gave me an error:
nginx: [emerg] open() "/etc/nginx/snippets/fastcgi-php.conf" failed (2: No such file or directory)
This answer on StackOverflow recommended the following, and it worked:
location ~ \.php$ {
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
The important part of the answer is changing include snippets/fastcgi-php.conf
to include fastcgi_params
.
SSL & Certbot
After trying a bit, I finally concluded that for my case, the best way to use HTTPS/SSL on my website it to use the nginx on the host OS, rather than the nginx in the docker container, and then reverse proxy to it.
But here are some useful links:
- HTTPS using Nginx and Let's encrypt in Docker (mindsers.blog)
- Let’s Encrypt certificate for dockerized Nginx under Cloudflare (Gist/jesugmz)
And when using the certbot --nginx
command, I encountered this error:
The requested nginx plugin does not appear to be installed
If you could, install the python3-certbot-nginx
package.
sudo apt-get install python3-certbot-nginx
Or you can not use --nginx
and manually add the certificates to the nginx config.
(Source: stackoverflow.com/a/64571234/11041841 & github.com/certbot/certbot/issues/1736)
Also Read Nginx and Let’s Encrypt with Docker in Less Than 5 Minutes (pentacent.medium.com).
Little Facts
- To install packages in the container, we can use the ol'
Dockerfile
(Source) - The Nginx config should not be named
default.conf
. (Source)
Read More
By DigitalOcean
- How To Install and Use Docker on Ubuntu 22.04
- How To Install and Use Docker Compose on Ubuntu 22.04
- How To Set Up Laravel, Nginx, and MySQL With Docker Compose on Ubuntu 20.04
- How To Install MariaDB on Ubuntu 22.04
- How To Secure a Containerized Node.js Application with Nginx, Let's Encrypt, and Docker Compose
- Initial Server Setup with Ubuntu 22.04
A Guide Collection by Igor Fomin at Hackernoon
The GitHub Repo: github.com/ikknd/docker-study
- #1. (Nginx) Nginx + Docker: How to Get Html Page Up With Local Domain Name
- #2. (PHP) Nginx + PHP + Docker: How To Get PHP Page Up With Local Domain Name
- #3. (MySQL/MariaDB) MariaDB + Phpmyadmin + Docker: Running Local Database
- #4. (Redis) How To Configure Redis + Redis Commander + Docker
- #5. (Composer) Get PHP Composer to Run On Docker Container
- #6. (CRON) How To Setup Cron And Docker Correctly
- #7. (Env) How To Use Environment Variables In Docker Compose File
- #8. (Extend) How To Extend Docker Compose File
- #9. (PHP xdebug) How To Debug PHP Container With Xdebug And PhpStorm
GitHub Gists & Repos
- Docker - Nginx + PHP FPM + MariaDB + PhpMyAdmin (Gist/Fabricio20)
- Docker NGINX PHP MySQL PhpMyadmin (rzrokon/Docker-NGINX-PHP-MySQL-PhpMyadmin)
Other References
- Tutorial: Create multi-container apps with MySQL and Docker Compose (Microsoft)
- Docker MariaDB + MySQL + PHP FPM + Nginx Reverse Proxy + Nginx WordPress + PhpMyAdmin Setup (hungred.com)
- Dockerize Laravel, Nginx, MariaDB, PhpMyAdmin, Redis and Npm (Medium/Reza Khademi)
- Guide to install Nginx + Php + MariaDB + Phpmyadmin in Docker (blog.sylo.space)
- Containerize WordPress with NGINX, PHP, MySQL, and phpMyAdmin using Docker Containers (Tutorials24x7.com)
- Create database on docker-compose startup
- Dockerfile reference (Docker)
- Best practices for writing Dockerfiles (Docker)