Review of freshly installed Fedora 31 Workstation (Gnome GUI)

After the tutorial of Install Fedora Workstation 31 (Gnome GUI) this tutorial is mainly to see what to expect from a freshly installed Fedora 36 Workstation – the look and feel of the GUI (Gnome – version 3.30).

  • Xorg X server – 1.20.5
  • GNOME (the GUI) – 3.34.1
  • linux kernel – 5.3.7

More technical details here – Technical details of Fedora Workstation 31 (Gnome GUI).
The idea of this tutorial is just to see what to expect from Fedora 31 Workstation (Gnome)the look and feel of the GUI, the default installed programs and their look and how to do some basic steps with them. Here you’ll find more than 150 screenshots and not so many text we do not want to turn this review of many text and version information and 3 meaningless screenshot, which you cannot see anything for the user interface, which these days is the primary goal of a Desktop system. You can expect more of this kind of reviews in the future…
You can find similar article for Fedora Workstation 27 – Review of freshly installed Fedora 27 Workstation (Gnome GUI), Review of freshly installed Fedora 29 Workstation (Gnome GUI)
And for all installation and review tutorials we use real workstations not virtual environments!

SCREENSHOT 1) Fedora (5.3.7-301.fc31.x86_64) 31 (Thirty One)

main menu
grub entry boot

Keep on reading!

aplty – unable to find control.tar.gz part in package – change deb package compression from xz to gzip

We upgraded to a new version of Ubuntu and our CI (continuous integration) scripts began to throw errors when uploading packages to out aptly repository:

"Report":{"Warnings":["Unable to read file /srv/aptly/.aptly/upload/mysoft/mysoft-6.15-pk19.deb: unable to find control.tar.gz part in package /srv/aptly/.aptly/upload/mysoft/mysoft-6.15-pk19.deb"],"Added":[],"Removed":[]}}

But if the same command:

dpkg-deb --build $PKGNAME

is executed on our older Ubuntu 16 everyhting is perfect and no error when uploading the package in the repository.

It turns out the new version of dpkg 1.19.0 the dpkg-deb will compress the deb file with XZ by default. Before version 1.19 the default compression is gzip.

You may upgrade your aptly installation to 1.20 and above or just fix your script to use “-Zgzip” with dpkg-deb

dpkg-deb -Zgzip --build $PKGNAME

This command will force the dpkg-deb to use gzip to compress the debian package.

Change the compression of existing deb package

Thanks to the aptly bug report – https://github.com/aptly-dev/aptly/issues/655 (hopes this link stays forever) you may have a workarround to decompress and comrpess an existing package with antoher algorythm

dpkg-deb -R package.deb tmp
rm package.deb
fakeroot dpkg-deb -Zgzip -b tmp package.deb
rm -rf tmp

docker mysql – Fatal error: Please read “Security” section of the manual to find out how to run mysqld as root!

Pulling the official MySQL image from the docker registry https://hub.docker.com/r/mysql/mysql-server to start a MySQL instance with your configuration file (and MySQL binary files). Adding the “–volume” option for the configuration directory (or file) and MySQL binary files and you stumble on the error:

2019-12-03 01:13:38 0 [Note] mysqld (mysqld 5.6.46-log) starting as process 67 ...
2019-12-03 01:13:38 67 [ERROR] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!

2019-12-03 01:13:38 67 [ERROR] Aborting

2019-12-03 01:13:38 67 [Note] Binlog end
2019-12-03 01:13:38 67 [Note] mysqld: Shutdown complete

Apparently, the server option is not configured to run properly as a root user and you do not want to run it, but why it keeps insisting to run it as root?

Because of the entry point script will execute only “mysqld” as a command, which expects to have a “user” option in the “[mysqld]” section of your my.cnf configuration file!

Do not miss the user option in my.cnf! This is how the MySQL server will be using the “mysql” username not the root!

user=mysql

Typical error, because it is not so common to include the username in my.cnf configuration file of the mysqld process to run as. If you use the official docker MySQL image to create your configuration file you would not encounter the above error, but if you use an existing (probably old and from non virtualized environment) my.cnf make sure to include the username, which should be used to run the mysqld process as.

Here is our command to execute the container:

docker run --privileged -d -v /mnt/storage/docker/mysql-slave/files:/var/lib/mysql -v /mnt/storage/docker/mysql-slave/etc/my.cnf:/etc/my.cnf mysql/mysql-server:5.6

Gentoo – UnicodeEncodeError: ‘ascii’ codec can’t encode character ‘\xc4’ in position 83: ordinal not in range(128)

Recently emerging package =dev-lang/go-1.13.4 under Gentoo failed on one of our virtual servers with:

--- /usr/lib/go/test/fixedbugs/issue27836.dir/
Traceback (most recent call last):
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/_MergeProcess.py", line 234, in _spawn
    prev_mtimes=self.prev_mtimes, counter=counter)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 1788, in wrapper
    return f(self, *args, **kwargs)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 5385, in merge
    counter=counter)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 4548, in treewalk
    rval = self._merge_contents(srcroot, destroot, cfgfiledict)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 4828, in _merge_contents
    self.settings["EPREFIX"].lstrip(os.sep), cfgfiledict, mymtime):
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 5225, in mergeme
    encoding=_encodings['merge'])
  File "/usr/lib64/python3.6/site-packages/portage/util/movefile.py", line 256, in movefile
    selinux.rename(src, dest)
  File "/usr/lib64/python3.6/site-packages/portage/__init__.py", line 246, in __call__
    rval = self._func(*wrapped_args, **wrapped_kwargs)
  File "/usr/lib64/python3.6/site-packages/portage/_selinux.py", line 71, in rename
    os.rename(src, dest)
UnicodeEncodeError: 'ascii' codec can't encode character '\xc4' in position 83: ordinal not in range(128)

>>> Failed to install dev-lang/go-1.13.4, Log file:

>>>  '/var/tmp/portage/dev-lang/go-1.13.4/temp/build.log'

The above log shows that the emerge fails in the installation phase when moving the files to the proper path in the system. The problem there is a non-ASCII character in the file name or path, but the environment is set to use ASCII as language.

The solution is to check if the environment LANG is set and what it contains. In this case, we should set the LANG environment to utf8.

export LANG=en_US.UTF-8

Most of the cases this kind of error could occur with virtual servers, docker (or the other kind of containers like lxc, podman and so on) containers and chroot jails or screens with changed user with su or sudo! In our case, the LANG just got missed because of a switch user procedure in a container and the emerge failed with the above error. When the LANG is missing probably the default value is “C”. In fact, check not only LANG but also the “LC_ALL” environment variable (it may have different value, which is wrong!), which also should be “en_US.UTF-8”:

export LC_ALL=en_US.UTF-8

Or try removing it at all with

unset LC_ALL

Keep on reading!

Build docker image with custom Dockerfile name – docker build requires exactly 1 argument

Docker uses the Dockerfile to build docker images, but what if you want to change the name and (or) the path of this file?
By default “docker build” command uses a file named Dockerfile on the same directory you execute the “docker build“. There is an option to change the path and name of this special file:

  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')

And the “-f” may include path and file name but it is mandatory to specify the path at the end “docker build” usually the current directory (context by the docker terminology) by adding “.” (the dot at the end of the command)

So if you want to build with a docker file mydockerfile in the current directory you must execute:

docker build -f mydockerfile .

If your file is in a sub-directory execute:

docker build -f subdirectory/mydockerfile .

The command will create a docker image in your local repository. Here is the output of the first command:

root@srv:~/docker# docker build -f mydockerfile .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:bionic-20191029
bionic-20191029: Pulling from library/ubuntu
7ddbc47eeb70: Pull complete 
c1bbdc448b72: Pull complete 
8c3b70e39044: Pull complete 
45d437916d57: Pull complete 
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for ubuntu:bionic-20191029
 ---> 775349758637
Step 2/3 : MAINTAINER test@example.com
 ---> Running in 5fa42bca749c
Removing intermediate container 5fa42bca749c
 ---> 0a1ffa1728f4
Step 3/3 : RUN apt-get update && apt-get upgrade -y && apt-get install -y git wget
 ---> Running in 2e35040f247c
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:4 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
.....
.....
Processing triggers for ca-certificates (20180409) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
Removing intermediate container 2e35040f247c
 ---> 2382809739a4
Successfully built 2382809739a4

Here is the image:

REPOSITORY                            TAG                 IMAGE ID            CREATED              SIZE
root@srv:~# docker images
<none>                                <none>              2382809739a4        About a minute ago   186MB

Build command with custom name and registry URL and TAG

root@srv:~# docker build -t gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base:v0.1 -f mydockerfile .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:bionic-20191029
 ---> 775349758637
Step 2/3 : MAINTAINER test@example.com
 ---> Using cache
 ---> 0a1ffa1728f4
Step 3/3 : RUN apt-get update && apt-get upgrade -y && apt-get install -y git wget
 ---> Using cache
 ---> 2382809739a4
Successfully built 2382809739a4
Successfully tagged gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base:v0.1
root@srv:~# docker push gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base:v0.1
The push refers to repository [gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base]
7cebba4bf6c3: Pushed 
e0b3afb09dc3: Pushed 
6c01b5a53aac: Pushed 
2c6ac8e5063e: Pushed 
cc967c529ced: Pushed 
v0.1: digest: sha256:acf42078bf46e320c402f09c6417a3dae8992ab4f4f685265486063daf30cb13 size: 1364

the registry URL is “gitlab.ahelpme.com:4567” and the project path is “/root/ubuntu-project/” and the name of the image is “ubuntu18-manual-base” with tag “v0.1“. The build command uses the cache from our first build example here (because the docker file is the same).

Typical errors with “-f”

Two errors you may encounter when trying the “-f” to change the name of the default Dockerfile name:

$ docker build -t gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base:v0.1 -f mydockerfile subdirectory/
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /builds/dev/docker-containers/mydockerfile: no such file or directory

$ docker build -t gitlab.ahelpme.com:4567/root/ubuntu-project/ubuntu18-manual-base:v0.1 -f subdirectory/mydockerfile
"docker build" requires exactly 1 argument.
See 'docker build --help'.

Usage:  docker build [OPTIONS] PATH | URL | -

First, you might think the -f would take the path and file name and this should be enough, but the errors above appears!

Our example Dockerfile

This is our simple example docker file:

FROM ubuntu:bionic-20191029
MAINTAINER test@example.com

RUN apt-get update && apt-get upgrade -y && apt-get install -y git wget

We are using the official docker image from Ubuntu. Always use official docker images!

autorelabel failed to relabel the root filesystem on boot when enabling the selinux on CentOS 8

This article is of a kind – “/.autorelabel” file does not work, because the enable of SELINUX ended with unreachable server.

Enabling the SELINUX should be easy as

  1. just editing a text file – /etc/selinux/config to include
    SELINUX=enforcing
    
  2. relabel all (or at least the root) file systems by creating the “/.autorelabel” file.
  3. restarting the system. The boot process will detect the “/.autorelabel” file and relabel the file systems and then it will restart the system in the normal boot order.

But this time the relabeling did not happen as usual (It happened on CentOS 8, but probably could happen in any Linux distribution?). The server never got reachable again and on the screen, there were multiple errors – all of “Permission denied”!

It is better when enabling SELINUX to set “permissive” mode at first and relabel the root file system with “/.autorelabel” and then to enable “enforcing” mode of SELINUX.

Using “permissive” first for the relabel process guarantees you would have your server back after the process because the SELINUX rules are not enforced.
Here is the better procedure of enabling the SELINUX:

  1. just editing a text file – /etc/selinux/config to include
    SELINUX=permissive
    
  2. relabel all (or at least the root) file systems by creating the “/.autorelabel” file.
  3. restarting the system. The boot process will detect the “/.autorelabel” file and relabel the file systems and then it will restart the system in normal boot order.
  4. edit the /etc/selinux/config to enable “enforcing” mode
    SELINUX=enforcing
    
  5. Restart (it’s better) or just enable SELINUX enforcing live with:
    setenforce 1
    

Our screenshots log of the relabel failure process

SCREENSHOT 1) No autorelabel initiated on boot despite the presence of “/.autorelabel” file.

Multple “Permission Denied” errors and many reports from “audit” – the SELINUX log daemon. The host is unreachable – no network started. No logging is possible!

main menu
boot freezing

SCREENSHOT 2) A page up above the first screen – more “Permission Denied” errors.

main menu
boot freezing 2

SCREENSHOT 3) Second page up above the first screen – the SELINUX rules loaded successfully but no autorelabel process initiated.

main menu
boot freezing 3

A successful relabel process on boot

SCREENSHOT 1) Successful start of the relabel process.

We’ve changed the SELINUX mode to be “permissive” and everything is back to normal, the “/.autorelabel” file initiated the relabel on the next boot.

main menu
relabel process on boot initiated

SCREENSHOT 2) The relabeling of the file system is in progress.

There is a progress counter.

main menu
relabel process in progress

SCREENSHOT 3) The relabel process finished successfully and the reboot is initiated.

The next reboot the “/.autorelabel” file won’t exists and the system will boot normally.

main menu
relabel process success and last screen before reboot

SSD cache device to a software RAID5 using LVM2

Continuing our series LVM2 plus cache device:

  1. single hard disk with a SSD device SSD cache device to a hard disk drive using LVM, which uses SSD drive as a cache device to a single hard drive.
  2. Mirror LVM2 device with a SSD device for cache – SSD cache device to a software raid using LVM2 – software mirror across two devices with an additional SSD cache device over the mirror.

And now we show you how to do software RAID5 with SSD cache nvme using LVM2.

The goal:
Caching RAID5 consisting of three 8T hard drives with a single 1T NVME SSD drive. Caching reads, i.e. the write-through is enabled ().
Our setup:

  • 1 NVME SSD disk Samsung 1T. It will be used for writethrough cache device (you may use writeback, too, you do not care for the data if the cache device fails)!
  • 3 Hard disk drive 8T grouped in RAID5 for redundancy.

Keep on reading!

Technical details of Fedora Workstation 31 (Gnome GUI)

This article is for those of you who do not want to install a whole new operating system only to discover some technical details about the default installation like disk layout, packages included, software versions, and so on. Here we are going to review in several sections what is like to have a default installation of Fedora Workstation 31 (Gnome) using a real not virtual machine!
The kernel is 5.3.7 it detects successfully the Threadripper 1950X AMD and the system is stable (we booted in UEFI mode).

Software

With Fedora 31 (Workstation Edition) you can have

  • linux kernel – 5.3.7 (5.3.7-301.fc31.x86_64)
  • Graphical User Interface
    • Xorg X server (Xwayland) – 1.20.5
    • GNOME (the GUI) – 3.34.1
    • K Desktop Environment – ships with https://spins.fedoraproject.org/en/kde/ Use this spin to install KDE.
  • System
    • linux-firmware – version: 20190923, release: 20191022-103.fc31.
    • QT – 5.12.5
    • libc – 2.30
    • GNU GCC – 9.2.1
    • OpenSSL – 1.1.1d
    • coreutils – 8.31
    • yum – Depricated and replaced with dnf
    • dnf – 4.2.9
    • cups – 2.2.12
    • rsyslog – 8.1907.0
    • NetworkManager – 1.20.4
  • Servers
    • Apache – 2.4.41
    • Nginx – 1.16.1
    • MySQL server – 8.0.17
    • MariaDB server – 10.3.17
    • PostgreSQL – 11.5
  • Programming
    • PHP – 7.3.10
    • python – 2.7.17 and also includes 3.7.4
    • perl – 5.30.0
    • ruby – 2.6.5
    • OpenJDK – 11.0.4.11 and also includes 1.8.0.222.b10
    • Go – 1.13.1
    • Rust – 1.38.0
    • Subversion – 1.12.2
    • Git – 2.23.0

Note: Not all of the above software comes installed by default. The versions above are valid for the intial release so in fact, these are the minimal versions you get with Fedora 31and installing and updating it after the initial date may update some of the above packages with new versions.
The installation procedure you can find here – Install Fedora Workstation 31 (Gnome GUI).
Installed packages are 1653 occupying 6.9G space:.

[root@srv ~]# dnf list installed|wc -l
1653
[root@srv ~]# df -h /
Filesystem                               Size  Used Avail Use% Mounted on
/dev/mapper/fedora_localhost--live-root   69G  6.9G   59G  11% /

Keep on reading!

Install Fedora Workstation 31 (Gnome GUI)

This tutorial will show you the simple steps of installing a modern Linux Distribution like Fedora 31 Workstation with Gnome for the user graphical interface. First, we present the basic steps for installing the Operating system in addition to your present operating systems (here we also have Windows 10) and then you can see some screenshots of the installed system and the look and feel of it. We have other tutorials showing more screenshots of the installed and working Fedora 31 (Gnome and KDE plasma) – so you can decide which of them to try first – coming soon.

The Fedora 31 Workstation comes with

  • Xorg X server – 1.20.5 XWayland is used by default
  • GNOME (the GUI) – 3.34.1
  • linux kernel – 5.3.7

Check out our article about what software is included in comming soon.

The installation process is very similar to the old Fedora Workstation 27, Fedora Workstation 28, Fedora Workstation 29, Install Fedora Workstation 30 (Gnome GUI) , in fact the main difference is the creation of an user, which the setup is not responsible anymore, the creation of an user is done by the first boot after installation. Our system was pretty good – Asus X399 with AMD Ryzen Threadripper 1950X and NVIDIA 1080 Ti and the setup loaded successfully and there were no problems till the end.

We used the following ISO for the installation process:

https://download.fedoraproject.org/pub/fedora/linux/releases/31/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-31-1.9.iso

It is a LIVE image so you can try it before installing. The easiest way is just to download the image and burn it to a DVD disk and then follow the installation below:

SCREENSHOT 1) Here is our “UEFI BIOS->Boot->Boot Override” and in most modern motherboard you can choose to override the default boot devices.

Choose the “UEFI: HL-DT-STDVDRAM…” to boot and install Fedora Workstation 31 with UEFI support. You should do this, because most of the new hardware like video cards would not work properly without beeing in UEFI mode.

main menu
Boot from DVD/USB Installation

Keep on reading!

Docker change the port mapping of an existing container

Unfortunately, it is not possible to change the port mapping (forwarded ports from the hosts to the container) of an existing RUNNING container!

Not only that, but you cannot change the mapped ports (forwarded ports) even when the container is stopped, so think twice when you run or start a container from the image you’ve chosen. Of course, you can always use docker’s commit command, which just creates a new image from you (running, in a sense of changes fro the original image) container and then you can run the new image with new mapped ports!

Still, there is a solution not involving the creation of new docker images and containers, but just to edit manually a configuration file while the Docker service is stopped.

So if you have several docker containers running you should stop all of them! When the Docker service stops, edit the “hostconfig.json” file! Here is the whole procedure:

  1. Stop the container.
  2. Stop the Docker container service.
  3. Edit the container’s file – hostconfig.json (usually in /var/lib/docker/containers/[ID]/hostconfig.json) and add or replace ports.
  4. Start the Docker container service.
  5. Start the docker container.

Real World Example

myuser@srv:~# sudo docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS                  PORTS                                                                                    NAMES
a9e21e92e2dd        gitlab/gitlab-runner:latest   "/usr/bin/dumb-init …"   2 days ago          Up 33 hours                                                                                                      gitlab-runner
5d025e7f93a4        gitlab/gitlab-ce:latest       "/assets/wrapper"        3 days ago          Up 34 hours (healthy)   0.0.0.0:80->80/tcp, 0.0.0.0:4567->4567/tcp, 0.0.0.0:1022->22/tcp   gitlab
myuser@srv:~# sudo docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS                  PORTS                                                                                    NAMES
a9e21e92e2dd        gitlab/gitlab-runner:latest   "/usr/bin/dumb-init …"   2 days ago          Up 33 hours                                                                                                      gitlab-runner
5d025e7f93a4        gitlab/gitlab-ce:latest       "/assets/wrapper"        3 days ago          Up 34 hours (healthy)   0.0.0.0:80->80/tcp, 0.0.0.0:4567->4567/tcp, 0.0.0.0:1022->22/tcp   gitlab
myuser@srv:~# sudo docker stop gitlab-runner
gitlab-runner
myuser@srv:~# sudo docker stop gitlab
gitlab
myuser@srv:~# sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
myuser@srv:~# systemctl stop docker
myuser@srv:~# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Thu 2019-11-14 21:54:57 UTC; 5s ago
     Docs: https://docs.docker.com
  Process: 2340 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=0/SUCCESS)
 Main PID: 2340 (code=exited, status=0/SUCCESS)

Nov 14 21:54:33 srv dockerd[2340]: time="2019-11-14T21:54:33.308531424Z" level=warning msg="a9e21e92e2dd297a68f68441353fc3bda39d0bb5564b60d402ae651fa80f5c72 cleanu
Nov 14 21:54:46 srv dockerd[2340]: time="2019-11-14T21:54:46.394643530Z" level=info msg="Container 5d025e7f93a45a50dbbaa87c55d7cdbbf6515bbe1d45ff599074f1cdcf320a0c
Nov 14 21:54:46 srv dockerd[2340]: time="2019-11-14T21:54:46.757171067Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete ty
Nov 14 21:54:47 srv dockerd[2340]: time="2019-11-14T21:54:47.031709355Z" level=warning msg="5d025e7f93a45a50dbbaa87c55d7cdbbf6515bbe1d45ff599074f1cdcf320a0c cleanu
Nov 14 21:54:57 srv systemd[1]: Stopping Docker Application Container Engine...
Nov 14 21:54:57 srv dockerd[2340]: time="2019-11-14T21:54:57.439296168Z" level=info msg="Processing signal 'terminated'"
Nov 14 21:54:57 srv dockerd[2340]: time="2019-11-14T21:54:57.447803201Z" level=info msg="Daemon shutdown complete"
Nov 14 21:54:57 srv dockerd[2340]: time="2019-11-14T21:54:57.449422219Z" level=info msg="stopping event stream following graceful shutdown" error="context canceled
Nov 14 21:54:57 srv dockerd[2340]: time="2019-11-14T21:54:57.449576789Z" level=info msg="stopping event stream following graceful shutdown" error="context canceled
Nov 14 21:54:57 srv systemd[1]: Stopped Docker Application Container Engine.
myuser@srv:~# cat /var/lib/docker/containers/5d025e7f93a45a50dbbaa87c55d7cdbbf6515bbe1d45ff599074f1cdcf320a0c/hostconfig.json 
{"Binds":["/srv/gitlab/config:/etc/gitlab","/srv/gitlab/logs:/var/log/gitlab","/srv/gitlab/data:/var/opt/gitlab"],"ContainerIDFile":"","LogConfig":{"Type":"json-file","Config":{}},"NetworkMode":"default","PortBindings":{"22/tcp":[{"HostIp":"","HostPort":"1022"}],"4567/tcp":[{"HostIp":"","HostPort":"4567"}],"80/tcp":[{"HostIp":"","HostPort":"80"}]},"RestartPolicy":{"Name":"always","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"Capabilities":null,"Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"private","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":false,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":67108864,"Runtime":"runc","ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DeviceRequests":null,"KernelMemory":0,"KernelMemoryTCP":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":null,"OomKillDisable":false,"PidsLimit":null,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths":["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
myuser@srv:~# nano /var/lib/docker/containers/5d025e7f93a45a50dbbaa87c55d7cdbbf6515bbe1d45ff599074f1cdcf320a0c/hostconfig.json 
myuser@srv:~# systemctl start docker
myuser@srv:~# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-11-14 22:12:06 UTC; 2s ago
     Docs: https://docs.docker.com
 Main PID: 4693 (dockerd)
    Tasks: 54
   CGroup: /system.slice/docker.service
           ├─4693 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
           ├─4867 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 4567 -container-ip 172.17.0.3 -container-port 4567
           ├─4881 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 443 -container-ip 172.17.0.3 -container-port 443
           ├─4895 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 1022 -container-ip 172.17.0.3 -container-port 22
           └─4907 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.3 -container-port 80

Nov 14 22:12:04 srv dockerd[4693]: time="2019-11-14T22:12:04.034007956Z" level=warning msg="Your kernel does not support swap memory limit"
Nov 14 22:12:04 srv dockerd[4693]: time="2019-11-14T22:12:04.034062799Z" level=warning msg="Your kernel does not support cgroup rt period"
Nov 14 22:12:04 srv dockerd[4693]: time="2019-11-14T22:12:04.034074070Z" level=warning msg="Your kernel does not support cgroup rt runtime"
Nov 14 22:12:04 srv dockerd[4693]: time="2019-11-14T22:12:04.034361581Z" level=info msg="Loading containers: start."
Nov 14 22:12:04 srv dockerd[4693]: time="2019-11-14T22:12:04.344354207Z" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Dae
Nov 14 22:12:05 srv dockerd[4693]: time="2019-11-14T22:12:05.916782317Z" level=info msg="Loading containers: done."
Nov 14 22:12:05 srv dockerd[4693]: time="2019-11-14T22:12:05.988204406Z" level=info msg="Docker daemon" commit=9013bf583a graphdriver(s)=overlay2 version=19.03.4
Nov 14 22:12:05 srv dockerd[4693]: time="2019-11-14T22:12:05.988317448Z" level=info msg="Daemon has completed initialization"
Nov 14 22:12:06 srv dockerd[4693]: time="2019-11-14T22:12:06.010801856Z" level=info msg="API listen on /var/run/docker.sock"
Nov 14 22:12:06 srv systemd[1]: Started Docker Application Container Engine.
myuser@srv:~# sudo docker start gitlab-runner
gitlab-runner
myuser@srv:~# sudo docker start gitlab
gitlab
myuser@srv:~# sudo docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS                             PORTS                                                                                    NAMES
a9e21e92e2dd        gitlab/gitlab-runner:latest   "/usr/bin/dumb-init …"   2 days ago          Up 19 seconds                                                                                                               gitlab-runner
5d025e7f93a4        gitlab/gitlab-ce:latest       "/assets/wrapper"        3 days ago          Up 19 seconds (health: starting)   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:4567->4567/tcp, 0.0.0.0:1022->22/tcp   gitlab
myuser@srv:~# wget --no-check-certificate https://192.168.0.238/
--2019-11-14 22:13:30--  https://192.168.0.238/
Connecting to 192.168.0.238:443... connected.
    WARNING: certificate common name ‘gitlab.ahelpme.com’ doesn't match requested host name ‘192.168.0.238’.
HTTP request sent, awaiting response... 302 Found
Location: https://192.168.0.238/users/sign_in [following]
--2019-11-14 22:13:30--  https://192.168.0.238/users/sign_in
Reusing existing connection to 192.168.0.238:443.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html’

index.html                                     [ <=>                                                                                     ]  12.41K  --.-KB/s    in 0s      

2019-11-14 22:13:31 (134 MB/s) - ‘index.html’ saved [12708]


Change the ports or add more ports in “PortBindings”. The syntax is pretty straightforward just mind the comas, [] and {}.

"PortBindings":{"22/tcp":[{"HostIp":"","HostPort":"1022"}],"4567/tcp":[{"HostIp":"","HostPort":"4567"}],"80/tcp":[{"HostIp":"","HostPort":"80"}]}

Here we change the mapping from “host port 1022 to 22” to “host port 2222 to 22” just replacing the “1022” to “2222”:

"PortBindings":{"22/tcp":[{"HostIp":"","HostPort":"2222"}],"4567/tcp":[{"HostIp":"","HostPort":"4567"}],"80/tcp":[{"HostIp":"","HostPort":"80"}]}

And the second example is in addition to the 2222 change we want to add another mapping “host from 443 to 443” (open the HTTPS), just add new group with the above syntax:

"PortBindings":{"22/tcp":[{"HostIp":"","HostPort":"2222"}],"4567/tcp":[{"HostIp":"","HostPort":"4567"}],"80/tcp":[{"HostIp":"","HostPort":"80"}],"443/tcp":[{"HostIp":"","HostPort":"443"}]}

A note!

Probably there may be an idea not to be easy to add mapped ports when you think one of the main Docker goals is to isolate services per a Docker instance. It sounds strange to have a docker container for one service exporting a number of ports (or a single port) and later why you would need to expose another port? For another service in the same container, but you should use a separate container, not the same one!
But more and more Docker containers are used also to deliver a fine-tuned environment of a whole platform, which provides multiple services in a single docker container. Let’s take an example – GitLab, which offers installation in a Docker container hosting more than 10 services in a single container!