Ok Basil, Here are a few things you can try to use docker-compose which is a heck of a lot easier.
Since you are using ubuntu you need to install docker-compose
Code:
apt install docker-compose
You then want to make a directory where you are going to keep your compose files.
I usually put mine in /etc/docker/compose/<project or site>
Code:
mkdir -p /etc/docker/compose/<project or site name>
cd /etc/docker/compose/<project or site name>
Your compose file in this directory needs to specifically be called docker-compose.yml. If you don't know about working with yml files, spacing is very important. If you need to indent its 2 spaces. I'd recommend not using tabs to not screw things up. Make sure the columns line up. I've wasted a lot of time with malformed yml files because of spacing issues, so word of caution.
So I'll post my docker-compose.yml version for collabora here. I'm using this page as a reference on how to construct this file:
https://www.collaboraoffice.com/code/docker/
Code:
---
version: '3.3'
networks:
net:
driver: bridge
services:
collabora:
restart: always
image: collabora/code:latest
container_name: collabora
networks:
- net
ports:
# - 127.0.0.1:9980:9980
- 9980:9980
cap_add:
- MKNOD
environment:
- username=<admin user name>
- password=<admin password>
- domain=nextcloud\.domain\.com
# - cert_domain=office.domain.com
- DONT_GEN_SSL_CERT="True"
- server_name=reverse_proxy.domain.com
- extra_params=--o:ssl.enable=false --o:ssl.termination=true
# - extra_params="--o:ssl.enable=true"
# - extra_params="--o:ssl.enable=false"
# volumes:
# - /etc/letsencrypt/privkey.pem:/etc/loolwsd/key.pem
# - /etc/letsencrypt/cert.pem:/etc/loolwsd/cert.pem
# - /etc/letsencrypt/chain.pem:/etc/loolwsd/ca-chain.cert.pem
Ok so lets kind of step through this file briefly. The # lines are comments, feel free to exclude. I like to play with various options during testing so its easier for me to be able to flip these options on and off as needbe
version # needs to be in relation to your installed docker version. A page of the available version numbers is here:
https://docs.docker.com/compose/compose-file/compose-versioning/. Version numbers are backwards compatible.
Docker networking. Docker creates a private internal docker network using a network bridge. Containers declared within the docker-compose file can speak to each other using docker's internal network. The internal DNS server for the docker network is at address 127.0.0.11. When containers need to perform DNS lookups they first check docker's internal DNS, then the docker host's /etc/hosts file, and then ask the network router. DNS Host over rides may be done at the /etc/hosts or router level. Docker containers are known on the network by their container_name variable.
networks:
net:
driver: bridge
This defines an internal network using a network bridge. A routed network could also be used however a bridged network is fairly easy to work with in most cases.
restart: always -- means the container will be restarted when the host is rebooted or restarted. The container will not automatically restart after the docker image is stopped manually, but would restart if stopped after a host reboot. We'll discuss starting and stopping containers below
image: collabora/code:latest - this tells docker what image to pull from dockerhub.
https://hub.docker.com/r/collabora/code/tags
container_name - defines the name for the container. This will be used for stop/restart operations and will also by the host name for the container.
networks:
- net
This line tells the container what network bridge to utilize.
ports:
Ports or expose can be used. Ports 9980:9980 -- The first 9980 is docker's host port, and the second 9980 refers to the container' port. 9980:9980 maps the docker host's port 9980 to the docker container's port 9980. The docker container will listen for all incoming connections on port 9980 when defined in this way 9980:9980. If you only want to listen for incoming connection from a specific address you could use 127.0.0.1:9980:9980 which means the docker container will only bind port 9980 to listen for incoming connections from the local host. 127.0.0.1:9980:9980 is usually used if a revere proxy is run directly on the docker host. Expose is another variant of ports but not valid in this instance. expose 9980 would the container is exposing it's 9980 port only to listen to incoming connections from the docker network. Use of expose is valuable when you only want intra-container communication.
If using a firewall on the docker host -- please be sure to open port 9980 (see ufw or iptables).
cap_add:
- MKNOD
This "adds capabilities" to the container to be able to make special files using mknod -
https://docs.docker.com/engine/reference/run/
Environmental Variables are the variables as best defined in
https://www.collaboraoffice.com/code/docker/. These options will mirror what is usually used on the command line.
volumes -
Briefly volumes are a way to map a host or directory of the docker host directly to a host or directory within the docker container. If you wanted to generate Let's Encrypt SSL certs for the container itself, you could map the relevant key, cert, and chain files here if needed. Another example of using volumes would be if you wanted to keep a working copy of the /etc/loolwsd/loolwsd.xml directly on the host and make modifications directly to the configuration file. You could make changes to the file and then map it as a volume for the container to use -- effectively it would overwrite the default loolwsd.xml file within the container. I'd recommend trying to make changes via setting environmental variables prior to editing the loolwsd.xml file directly. Syntax can be tricky with the xml file and prone to errors. I've found very little need (if at all) to directly modify this file is using docker-compose.
Once you have configured and started your compose file:
1. Make sure you are within the docker-compose.yml directory (/etc/docker/compose/<project or site name>
2. Start the docker network with containers: docker-compose up -d --build --remove-orphans
3. You can check the state of the containers with: docker ps
4. You can check the logs of an individual container with: docker logs <container_name>
5. To stop all running containers: docker-compose down -v
Optional Step
By default docker-compose will not pull updated containers from dockerhub. (If building and using docker images created from a DOCKERFILE totally ignore this section or modify the information to your needs). If you want to automatically pull the latest containers, there are a number of methods.
Probably the most comprehensive method is actually using a docker project itself known as ouroboros:
https://hub.docker.com/r/pyouroboros/ouroboros.
Watchtower
https://github.com/containrrr/watchtower is another alternative. This is the "old tried and true" method for keeping containers updated automatically. I thought the project died however looking at their github there have been many recent commits.
Another simple and cheap method is the use of systemd timers and service files. Based on some examples I've found on the internet, I've constructed the following 3 files: docker-compose-reload@.service, docker-compose-reload@.timer, docker-compose@.service. In a nutshell, these files will use a systemd timer method (analogous to cron tasks), where at a specified interval, systemd will "refresh" the containers by stopping the running containers, pulling new images if necessary from dockerhub, and then restarting the container. (You don't get all the nifty feedback, graphs, and emails however that pyourobors would offer -- if you need such things!!).
Here are the files:
docker-compose-reload@.timer
Code:
[Unit]
Description=Refresh images and update containers
Requires=docker-compose@%i.service
After=docker-compose@%i.service
[Timer]
OnCalendar=daily
[Install]
WantedBy=timers.target
docker-compose-reload@.service
[Unit]
Description=Refresh images and update containers
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl reload-or-restart docker-compose@%i.service
docker-compose@.service
[Unit]
Description=Docker Compose %i container starter
After=docker.service network-online.target
Requires=docker.service network-online.target
[Service]
WorkingDirectory=/etc/docker/compose/%i
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/bin/docker system prune
ExecStartPre=/usr/bin/docker-compose down -v
ExecStartPre=/usr/bin/docker-compose rm -fsv
ExecStartPre=/usr/bin/docker-compose pull --quiet
#ExecStartPre=/usr/bin/docker-compose build --compress
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down -v
ExecStopPost=/usr/bin/docker-compose rm -fv
ExecReload=/usr/bin/docker-compose pull --quiet
ExecReload=/usr/bin/docker-compose up -d
[Install]
WantedBy=multi-user.target
Be sure to modify the docker-compose-reload@.timer file and change the OnCalendar option to fit your needs. This option works similar to cron settings:
https://wiki.archlinux.org/index.php/Systemd/Timers
To use these files it would be similar to any systemd file (For these files to work - they assume a directory structure of /etc/docker/compose/<project or site name>. This assumption can be changed by modifying the docker-compose@.service file - See Working Directory):
systemd enable docker-compose-reload@<project or site name>.service
systemd enable docker-compose-reload@<project or site name>.timer
systemd enable docker-compose@<project or site name>.service
systemd start docker-compose-reload@<project or site name>.timer
systemd start docker-compose@<project or site name>.service
That's it. Hopefully that helps.