Self-hosted services with Docker
After working through all of the steps in this guide, you will have a public server running these services:
- Wordpress Content Management System (https://wordpress.com)
- More to follow
The above services run with:
- Dynamic DNS support
- SSL enabled, using Let's Encrypt certificates
- Every occurence of
example.commust be replaced with your own domain.
- The server name in the example is
ubuntu. Use a different name if desired.
- There are a few sample passwords present: Do change them!
Hardware and host operating system
This is the hardware/software used to operate the server:
- Hardware: Intel NUC NUC8i5BEH with 32GB RAM and a 256GB SSD. There is room for an additional 2.5" drive in the case.
- Operating System: Ubuntu Server 18.04.2 LTS
Setup host operating system
It took me several attempts to get the installation right. This is what I did learn:
- Use the "Alternative Ubuntu Server installer", not the default one.
- Add the "SSH Server" package, and nothing else.
- Install wpasupplicant (
apt install wpasupplicant)
iw devto get the device name of the WLAN adapter):
network: version: 2 renderer: networkd ethernets: eno1: dhcp4: yes optional: true wifis: wlp0s20f3: dhcp4: yes optional: true access-points: "APNAME": password: "PASSWORD"
optionalpart is advisable: If e.g. ethernet does not get an IP address, then the boot process hangs for a very long time. After editing, use
sudo netplan apply to load the changed configuration. Use
networkctl to check if the WLAN is up.
Apart from SSH, a default Ubuntu Server does not expose any significant ports. To validate this, use
ss -tua and check for yourself. The
bootp ports are required for DHCP, and the
127.0.0.1 ports are purely local.
I would recommend to change the SSH port: Edit
/etc/ssh/sshd_config to accomplish this.
Setup external services
You will need a dynamic DNS service, unless you have a fixed IP address. I recommend that you set-up one single A-record for your machine, using the server name that you defined when you installed Ubuntu (
ubuntu by default). All other services (e.g.
www) are then added using CNAME Alias Records, pointing to the one A-record. This way, only one single record needs to be updated if the IP address changes.
Enable dynamic DNS updates
Go to the "ddclient" directory and follow the readme there.
Setup reverse proxy with https
Go to the "traefik" directory and follow the readme there.
Add Wordpress service
Go to the "wordpress" directory and follow the readme there.
Add docker GUI
Add database GUI
Add docker registry
In Unix, users (and groups) are identified by an integer value. This value can be translated to a "nice" user name by /etc/passwd. Here is a sample entry:
13 would usually be shown as
proxy, for example in the output of
A Docker image must use a Linux user when running its service. A typical
mariadb image for example uses user 27. Inside of the docker image will be an entry for this user in the image's
/etc/passwd. Outside, in the host operating system, this entry will be missing.
If you map a volume to a directory on the host operating system, you will see many files with a numeric UID, instead of a "nice" user name. This is purely cosmetic, and does not have any consequences.
Typically, you can't read and/or write such files with your admin user. This is not because of the numeric UID, but simply because your user has no access to the file. Whether the file is owned by
mysql doesn't matter: As long as there is no read or write right for "other" users there is no corresponding access: You will have to use
sudo for access.
Some images allow to specify the user. This feature can be used to map them to the operator's user: The operator can then directly access the files from the host operating system, without
sudo. I would not do this: There is a reason why even an operator has to use
sudo when administering a system.
If you are bothered by the numeric values, simply add the user manually. Make sure to not give the user a shell, and also disable its password. The sole purpose of the entry in
/etc/passwd is to have a nicer look of e.g.
- Add more services (Gitlab, Docker-Registry, Docker GUI, Database GUI, ...)
- Switch from docker-compose to docker stack
- Enable database backup
- Fine tune docker-managed volumes and explicit volumes (e.g. wordpress could be explicit for better maintenance and backup)
- Centralize explicit volumes (they are now along the docker-compose files)