Docker
Thanks Keith for the intro!
Keith: Alpine is a stripped down linux distro. Need to learn about how to handle persistent volumes, container secrets (don't put in container, but it can prompt for things). Dockerfile -v (volume). Container should output to stdin/out, then host can manage logging. Terraform can build your arch (can use a proxmox template), ansible is great for actual tasks. GCP has managed kubernetes (wait until you understand why you need it). Check out hashicorp vault FOSS version for awesome secret storage that is docker-compatible.
Maintenance
Restart on reboot
If you are using docker compose
, you should add this to your containers in compose.yml:
restart: always
To restart a single container on reboot, once it is running, update its config:
docker update --restart unless-stopped container_id
Prune regularly
ALWAYS prune your host's containers and images! Or docker will eat your drive alive. Do this in crontab:
0 3 * * * docker container prune -f && docker image prune -f
On occasion you may also need to clean up strays, with this super-prune:
docker system prune --all
It will remove all unused images not just dangling ones. Make sure the ones you want to keep are running! But DO THIS whenever you've been dicking around for a while, you're sure to have splorched some schtumm!
Also don't forget to prune your system log.
Commands
docker build -t name . # builds an image from curr dir Dockerfile docker images # lists images docker run --name cont-name image # to create and start a container from an image, which you can then stop and start # -it to run in a terminal, then Ctrl-C to stop it; use -d to run detached docker logs --follow cont-name # tail container logging docker ps # to see what containers are running docker ps -a # to see what containers are running (including recently stopped containers) docker start|stop name # to start/stop a container docker exec -it cont-name cmd # to run cmd on running container docker exec -it cont-name bash # get bash prompt on running container docker exec -u root -it cont-name /bin/bash # to run bash as root (so eg you can `apt install ...`) docker cp $(docker create --rm ${imageBaseUrl}):/image/path/files /local/path # copy image files docker rm name # to remove a stopped container docker container prune # to remove all stopped containers docker images # lists images docker rmi REPOSITORY/TAG # to remove an image docker image prune # remove all dangling images docker push|pull # push to / pull from hub.docker.com (for subsequent pull elsewhere!)
Pretty ps
Use this to show containers in a nice format (you can also add this as default, in ~/.docker/config.json):
docker ps -a --format 'table Template:.ID\tTemplate:.Status \tTemplate:.Names\tTemplate:.Command' docker ps -a --format 'table Template:.ID\tTemplate:.Status \tTemplate:.Names\tTemplate:.Command' | grep #mycontainer#
Restart container with new image
This is best practice, especially for large containers that are hosted at another location. It removes the image retrieval time from the overall container downtime:
docker pull mysql docker stop my-mysql-container docker rm my-mysql-container docker run --name=my-mysql-container --restart=always ...
Containers
Find nirvana here.
Debian slim
Debian slim containers are much smaller than standard installs. They are stripped of things like documentation, while still maintaining a full linux kernel and C++ stack.
You can use apt to bake in what you need from there. Nice!
Node
The official node container is huge (1GB), the alpine one is relatively tiny. See the list here.
alpine
Alpine is the best TINY base linux container. But it runs BusyBox and musl so many things (nvm, meteor) won't work (at least without a TON of effort).
Node on alpine
Here's a good starting point for a node app, but remember meteor won't work:
FROM alpine/git RUN apk --update add curl bash tar sudo npm SHELL ["/bin/bash", "-c"] ENV NEWUSER='m' RUN adduser -g "$NEWUSER" -D -s /bin/bash $NEWUSER \ && echo "$NEWUSER ALL=(ALL) ALL" > /etc/sudoers.d/$NEWUSER && chmod 0440 /etc/sudoers.d/$NEWUSER USER m WORKDIR /home/m COPY --chown=m my-code /home/m/my-code RUN npm install -g whatevah EXPOSE 3000 CMD [ "my_app", "param1" ]
More examples
- Example dockerfile for nextcloud
LetsEncrypt SSL certificate generator
docker pull zerossl/client # well that experiment went to shit... we tried to add a TXT domain record but it wasn't found # tom thought we needed a full resolving A record before TXT would work # either way, we can use a self-signed cert with gitlab and forego the constant need to renew
Networking
Bridge networking (the default) allows connections between containers running on the same docker host.
docker network create my-nw # defaults to --driver bridge docker run (...) --network my-nw (...) # to create and start a container on the network docker network connect my-nw container-name # to attach a container to the network after it is started docker network inspect my-nw
Install
Install docker
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update && sudo apt-get install docker-ce docker-ce-cli containerd.io sudo docker run hello-world sudo docker container ls -all # to see previous run-and-teardown sudo usermod -aG docker m # to add m to docker group for complete access, no more need for [sudo docker]
Install docker compose
A good easy way to coordinate multiple containers. Used for rocketchat docker install. Kubernetes is too big to worry about right now...
sudo apt-get install docker-compose-plugin
See the RocketChat compose.yml file for an example:
development/config/ubuntu/matryoshka/home/m/apps/RocketChat/compose.yml
Proxmox CPU config
Some images (like Meteor 5.0) require more-advanced CPU capabilities than Proxmox grants by default. Specifically, Mongo 5.0 requires AVX cpu instructions. To enable them:
Proxmox > VM > Edit > Processor > Type: "host"
Note that my Proxmox docker VM is called matryoshka.