Skip to content
A series of self-hosted services running under Docker
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Self-hosted services with Docker

After working through all of the steps in this guide, you will have a public server running these services:

The above services run with:

  • Dynamic DNS support
  • SSL enabled, using Let's Encrypt certificates

Please note:

  • Every occurence of must 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.

Enable WLAN

  • Install wpasupplicant (apt install wpasupplicant)
  • Edit /etc/netplan/01-netcfg.yaml (use iw dev to get the device name of the WLAN adapter):
  version: 2
  renderer: networkd
      dhcp4: yes
      optional: true
      dhcp4: yes
      optional: true
          password: "PASSWORD"

The 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 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


Add Gitlab


Other Considerations


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:
User number 13 would usually be shown as proxy, for example in the output of ls -la.

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 27 or 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. ls -la.

To Do

  • 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)
You can’t perform that action at this time.